Files
Aislo/B05_Profile/B05_Profile_UI_Drainage_Facility_Hidden.ts
T
eomsangdonandClaude Opus 5.5 7f04bf961c feat(B06): 관 · 옹벽 칸 한 곳 — 조정 창은 손잡이 · 읽기만(PLAN 24-4a)
- 옹벽 · 세월교 · BOX 조정 창의 값 칸(셀렉트 · −/+) 걷음 — 읽기 · 십자 · 그림 끌기 손잡이만(input 0)
- 그림 끌기 손잡이: 고른 구조물을 끌면 십자와 같은 걸음 · 같은 동작 · 끄는 동안 미리 보기
- 좌측 [횡단 조정] 사본 상자 없앰 — 폼에 없던 줄(읽기 · 단 수 · 옵션 · 집수정 내공 · 세월교 측벽 높이 · 다단 벽)만 폼 칸에 옮겨 붙음
- 집수정 기준측점 전 · 후를 폼 칸으로(옵션 보이기 따름) · 옮겨 붙은 줄도 옵션 보이기 규칙
- 폼 값 = 칸 전부: 비운 칸은 그림 자동 · 가게(pipes)에서도 지움 · 조정 예약(culvertopt)에 따로 담지 않음
- 시험 test_b06_adjust_single_form 6건 · 거울 시험(집수정 전 · 후 폼 칸) 고침

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ACSGaHdLgnkEkoA4LDtMU
2026-09-29 23:54:12 +09:00

64 lines
3.0 KiB
TypeScript

/* =============================================================================
* B05_Profile_UI_Drainage_Facility_Hidden.ts
* 계곡 통과 시설 폼의 **끈 옵션 가리기** — M02 「구조물 옵션 보이기」에서 끈 옵션
* (`GET /api/projects/structure-types` 의 `visible: false`)의 칸을 시설 폼에서도 안 그린다
* (PLAN 21-10 흠 8).
*
* · 칸은 `labeled(..., 옵션키)` 가 붙인 `data-option-keys` 표식으로 찾는다 — 키가 여럿인 칸(본체 규격 ·
* 유입구 구조)은 **키가 다 꺼졌을 때** 가린다(하나만 꺼지면 남은 키를 적는 칸이라 둠).
* · 숨긴 칸의 값은 칸이 아니라 **폼이 받은 옛 값**(`remember`)을 저장에 그대로 싣는다 —
* 칸에 제안값을 채워도 숨긴 값이 몰래 바뀌지 않는다.
* · 필수 검사는 이 폼에 없다(레지스트리 옵션 칸은 `renderOptionFields` 가 숨긴 칸을 뺌).
* ========================================================================== */
import { hiddenFormKeys } from "./B05_Profile_UI_Drainage_Facility_Merge";
export interface HiddenOptions {
/** 폼이 받은 옵션 — 숨긴 칸의 옛 값 보존용. `setFacility` 가 부른다. */
remember: (options: Record<string, string | number>) => void;
/** 끈 레지스트리 키를 받아 칸을 가린다. */
set: (facility: string | null, registryKeys: Iterable<string>) => void;
/** 읽은 옵션에서 숨긴 칸을 칸 값이 아닌 옛 값으로 바꾼다. */
restore: (options: Record<string, string | number>) => void;
}
export function createHiddenOptions(root: HTMLElement): HiddenOptions {
let hidden: ReadonlySet<string> = new Set();
let stored: Record<string, string | number> = {};
const apply = (): void => {
root.querySelectorAll<HTMLElement>("[data-option-keys]").forEach((node) => {
const keys = (node.dataset.optionKeys ?? "").split(" ");
node.classList.toggle(
"is-option-hidden",
keys.every((key) => hidden.has(key)),
);
});
// 칸이 다 가려진 줄은 줄째(빈 줄 간격이 안 남게)
root.querySelectorAll<HTMLElement>(".b05-structure__grid").forEach((row) => {
const kids = [...row.children];
const all =
kids.length > 0 && kids.every((kid) => kid.classList.contains("is-option-hidden"));
row.classList.toggle("is-option-hidden", all);
});
};
// 횡단 보기가 칸에 옮겨 붙이는 줄(단 수 등 · 계획서 24-4a)도 같은 규칙 — 줄이 붙을 때마다 다시 건다.
// (브라우저 밖 거울 시험 DOM 에는 관찰자가 없다.)
if (typeof MutationObserver !== "undefined")
new MutationObserver(apply).observe(root, { childList: true, subtree: true });
return {
remember(options) {
stored = { ...options };
},
set(facility, registryKeys) {
hidden = hiddenFormKeys(facility, registryKeys);
apply();
},
restore(options) {
for (const key of hidden) {
delete options[key];
if (stored[key] !== undefined) options[key] = stored[key];
}
},
};
}