/* ============================================================================= * B07_DesignDetail_UI_Settings.ts * 좌측 도면 묶음 ⚙ 설정 모달(요구 280-5) — 공용 `openModal` · 머리 [원본에서 다시 그리기](281). * * 평면도 = 평면도 관리 모달 그대로(`openPlanManager`) * 횡단도 = 장 배치(열 · 행 · [이 장] · [모든 장]) · 표 배율 · [안내선 숨기기] — 좌측 카드 밑에서 옮김 * 구조물 도면 = 「M02 그림 — 축척 없음」 한 줄 · 종단 · 횡단 · 토적 · 전개도 = X · Y 축척 칸(`_UI_Settings_Scale`) * [원본에서 다시 그리기] = 지금 연 도면이 그 묶음일 때만 켬 * ========================================================================== */ import { createButton } from "@ui/ui_template_elements"; import { openModal } from "@ui/ui_template_modal"; import type { CrossLayout, DesignDrawingItem } from "./B07_DesignDetail_Api_Fetch"; import { buildCrossLayoutControls, DRAWING_GROUPS, isCrossSheet, } from "./B07_DesignDetail_UI_Panels"; import { openPlanManager, type PlanManageControls } from "./B07_DesignDetail_UI_PlanManage"; import { mountDrawingScale } from "./B07_DesignDetail_UI_Settings_Scale"; type Kind = DesignDrawingItem["kind"]; export interface DrawingSettingsDeps { drawings: DesignDrawingItem[]; current: () => DesignDrawingItem | undefined; /** 지금 도면에 버릴 것(저장본 · 고친 것)이 있나 */ canRedraw: () => boolean; /** 원본에서 다시 그리기 — 해냈으면 참(모달 닫음) */ redraw: () => Promise; plan?: PlanManageControls; cross: { layout: () => Promise; /** 배치 저장 — 모달은 닫힌 뒤 · `sheet` = 지금 장 번호(장 아니면 0) */ save: (next: CrossLayout, sheet: number) => void; guideToggle: HTMLButtonElement; }; } /** ⚙ 묶음에 드는 도면 종류 — 횡단도 카드엔 표준 횡단면도 줄이 같이 있음. */ const memberOf = (kind: Kind): Kind[] => (kind === "cross" ? ["cross", "cross_standard"] : [kind]); const note = (text: string): HTMLElement => { const line = document.createElement("p"); line.className = "b07-settings__note"; line.textContent = text; return line; }; /** 묶음 `kind` 의 ⚙ 모달을 엶. */ export function openDrawingSettings(kind: Kind, deps: DrawingSettingsDeps): void { const current = deps.current(); const mine = !!current && memberOf(kind).includes(current.kind); let closeModal = (): void => undefined; const redraw = createButton({ label: "원본에서 다시 그리기", variant: "ghost", disabled: !(mine && deps.canRedraw()), onClick: () => { void deps.redraw().then((done) => done && closeModal()); }, }); redraw.title = !mine ? "이 묶음 도면을 연 뒤 쓸 수 있음" : redraw.disabled ? "이미 원본 그대로" : "저장본 · 고친 것을 버리고 B06 원본에서 새로 그림"; redraw.classList.add("b07-settings__redraw"); if (kind === "plan" && deps.plan) { const manager = openPlanManager({ ...deps.plan, actions: [redraw] }); closeModal = manager.close; return; } const label = DRAWING_GROUPS.find((group) => group.kind === kind)?.label ?? "도면"; openModal({ title: `${label} 설정`, closeLabel: "닫기", dialogClass: "b07-settings", actions: [redraw], mount: (body, close) => { closeModal = close; if (mine) body.append(note(`지금 도면: ${current?.label}`)); if (kind === "structure") body.append(note("M02 그림 — 축척 없음")); mountDrawingScale(body, kind, deps, close); if (kind === "cross") mountCross(body, deps, close); }, }); } /** 횡단 모달 몸 — 배치 칸은 받은 뒤 · 안내선 단추는 먼저(배치를 못 받아도 남음). */ function mountCross(body: HTMLElement, deps: DrawingSettingsDeps, close: () => void): void { const current = deps.current(); const sheet = current && isCrossSheet(current) ? deps.drawings.filter(isCrossSheet).findIndex((item) => item.id === current.id) + 1 : 0; body.classList.add("ui-panel-form"); // 칸 · 단추 꼴 = 좌측 패널 때와 같음(269) const holder = document.createElement("div"); holder.className = "b07-cross-layout"; holder.append(deps.cross.guideToggle); body.append(holder); void deps.cross .layout() .then((layout) => { const apply = (next: CrossLayout): void => { close(); deps.cross.save(next, sheet); }; const controls = buildCrossLayoutControls( (sheet && layout.sheets[String(sheet)]) || layout.default, sheet ? (grid) => apply({ ...layout, sheets: { ...layout.sheets, [String(sheet)]: grid } }) : null, (grid) => apply({ ...layout, default: grid, sheets: {} }), { scale: { value: layout.table_scale ?? 1, onApply: (scale) => apply({ ...layout, table_scale: scale }), }, }, ); controls.append(deps.cross.guideToggle); holder.replaceWith(controls); }) .catch(() => holder.prepend(note("배치를 받지 못했습니다."))); }