/* ============================================================================= * E02_StabGround_UI_Water.ts * E02 지하수 카드(요구 347 · 351 · PLAN 532-3) — 건기 규칙 · 우기 갈래 넷(KDS 기본 · 지표 아래 깊이 비율 · * r_u · 사용자 수위선 구간) · 「KDS 기본 · 우기 기준안전율 1.2 와 짝」 안내 · [기본값]. * 엔진 꼴로 바꾸기는 서버(`E02_StabGround_Model.station_groundwater`) — 여기는 값만 고침. * ========================================================================== */ import { createButton, el } from "@ui/ui_template_elements"; import { t, type LocaleKey } from "@ui/ui_template_locale"; import { WATER_KEYS, WATER_RULES, WET_MODES, type WetMode } from "./logic/E02_StabGround_Check"; import { card, clone, headButtons, numInput, selectInput, table, type E02View, } from "./E02_StabGround_UI_Tables"; const L = (key: string): string => t(key as LocaleKey); function field(label: string, input: HTMLElement): HTMLElement { const node = el("label", { className: "e02-field" }); node.append(el("span", { text: label }), input); return node; } function removeButton(view: E02View, onClick: () => void): HTMLButtonElement { const button = createButton({ label: t("E02_Btn_Remove"), variant: "danger-ghost", size: "sm", onClick, }); button.hidden = !view.editable; return button; } /** 사용자 수위선 구간 표 — 줄마다 시작 · 끝 · 점(offset · 깊이) · [점 추가] · [지움] */ function linesBody(view: E02View): HTMLElement { const water = view.ground.groundwater; if (!water.lines.length) return el("p", { className: "e02-empty", text: t("E02_Line_Empty") }); const rows = water.lines.map((line, i) => { const base = `groundwater.lines.${i}`; const points = el("div", { className: "e02-points" }); points.dataset.path = `${base}.points`; line.points.forEach((point, k) => { const pair = el("span", { className: "e02-point" }); pair.append( numInput(view, `${base}.points.${k}.0`, point[0], (v) => (point[0] = v as number)), numInput(view, `${base}.points.${k}.1`, point[1], (v) => (point[1] = v as number)), removeButton(view, () => { line.points.splice(k, 1); view.rebuild(); }), ); points.append(pair); }); const addPoint = createButton({ label: t("E02_Btn_AddPoint"), variant: "ghost", size: "sm", onClick: () => { const last = line.points[line.points.length - 1]; line.points.push(last ? [last[0] + 5, last[1]] : [0, 1]); view.rebuild(); }, }); addPoint.hidden = !view.editable; points.append(addPoint); return [ numInput(view, `${base}.from_m`, line.from_m, (v) => (line.from_m = v as number)), numInput(view, `${base}.to_m`, line.to_m, (v) => (line.to_m = v as number)), points, removeButton(view, () => { water.lines.splice(i, 1); view.rebuild(); }), ]; }); return table([t("E02_Col_From"), t("E02_Col_To"), t("E02_Col_Points"), ""], rows); } export function waterCard(view: E02View): HTMLElement { const water = view.ground.groundwater; const d = view.defaults.groundwater; const rule = (key: (typeof WATER_KEYS)[number]): HTMLElement => field( L(`E02_Water_${key}`), selectInput( view, `groundwater.${key}`, WATER_RULES.map((r) => ({ value: r, text: L(`E02_Rule_${r}`) })), water[key], (v) => (water[key] = v as (typeof WATER_RULES)[number]), { src: `groundwater.${key}`, def: L(`E02_Rule_${d[key]}`) }, ), ); const mode = selectInput( view, "groundwater.wet_mode", WET_MODES.map((m) => ({ value: m, text: L(`E02_WetMode_${m}`) })), water.wet_mode, (v) => { water.wet_mode = v as WetMode; view.rebuild(); }, { src: "groundwater.wet_mode", def: L(`E02_WetMode_${d.wet_mode}`) }, ); const grid = el("div", { className: "e02-grid" }); grid.append(rule("dry"), field(t("E02_WetMode"), mode)); const body: HTMLElement[] = []; if (water.wet_mode === "kds") grid.append(rule("wet_soil"), rule("wet_rock")); if (water.wet_mode === "depth_ratio") grid.append( field( t("E02_DepthRatio"), numInput( view, "groundwater.depth_ratio", water.depth_ratio, (v) => (water.depth_ratio = v as number), { src: "groundwater.depth_ratio", def: d.depth_ratio }, ), ), ); if (water.wet_mode === "ru") grid.append( field( t("E02_Ru"), numInput(view, "groundwater.ru", water.ru, (v) => (water.ru = v as number), { src: "groundwater.ru", def: d.ru, }), ), ); if (water.wet_mode === "line") body.push(el("p", { className: "e02-hint", text: t("E02_Line_Hint") }), linesBody(view)); const { section, head } = card( "E02_Card_Water", el("p", { className: "e02-hint", text: t("E02_Water_Hint") }), grid, ...body, ); const stations = view.ground.stations; const first = stations[0]?.chainage_m ?? 0; const last = stations[stations.length - 1]?.chainage_m ?? 100; const buttons = [ createButton({ label: t("E02_Btn_Defaults"), variant: "ghost", size: "sm", onClick: () => { view.ground.groundwater = clone(d); view.rebuild(); }, }), ]; if (water.wet_mode === "line") buttons.unshift( createButton({ label: t("E02_Btn_AddLine"), variant: "ghost", size: "sm", onClick: () => { water.lines.push({ from_m: first, to_m: last > first ? last : first + 20, points: [ [-10, 1], [10, 1], ], }); view.rebuild(); }, }), ); headButtons(view, head, ...buttons); return section; }