diff --git a/B06_Section/B06_Section_UI_Page.ts b/B06_Section/B06_Section_UI_Page.ts index 7e9bcad6..40b312cc 100644 --- a/B06_Section/B06_Section_UI_Page.ts +++ b/B06_Section/B06_Section_UI_Page.ts @@ -140,7 +140,64 @@ export async function renderB06ProfileCross(root: HTMLElement): Promise { stationInterval: () => stationInterval ?? 20, focusChainage: focusStationAt, queuePipeOptions: (chainageM, patch) => stationControls.queueCulvertOptions(chainageM, patch), + applyPipeOptions: (chainageM, patch) => applyPipeOptionsToCache(chainageM, patch), }); + + /** + * 폼에서 바꾼 관 옵션을 **횡단 캐시**(`section.culvert` 스펙)에 얹고, 그 구조물이 + * 덮는 측점 카드를 다시 그린다 — 조정창 조작과 같은 흐름이라 도면이 바로 따라온다 + * (2026-08-29 사용자 보고: 값만 바뀌고 횡단도가 그대로였다). + * 여기서는 화면 캐시만 고친다 — 영구저장은 [저장]·[확정] 몫이다. + */ + function applyPipeOptionsToCache( + chainageM: number, + patch: Record, + ): void { + const owner = sectionDetail?.cross_sections.find( + (section) => Math.abs(section.chainage_m - chainageM) < 0.51, + ); + const culvert = owner?.culvert; + if (!owner || !culvert) return; + const num = (key: string): number | undefined => { + const value = Number(patch[key]); + return Number.isFinite(value) ? value : undefined; + }; + const put = (target: T, field: keyof T, value: unknown): void => { + if (value !== undefined) (target as Record)[field as string] = value; + }; + put(culvert, "pipe_kind", patch.pipe_kind); + const diameterMm = num("pipe_diameter_mm"); + if (diameterMm !== undefined) culvert.diameter_m = diameterMm / 1000; + // 유입·유출 기슭막이 제원과 집수정 구간값 — 폼 옵션 키를 스펙 자리로 옮긴다. + for (const [side, prefix] of [ + [culvert.inlet, "inlet"], + [culvert.outlet, "outlet"], + ] as const) { + put(side, "revet_form", patch[`${prefix}_revet_form`]); + put(side, "revet_height_m", num(`${prefix}_revet_height_m`)); + put(side, "revet_length_m", num(`${prefix}_revet_length_m`)); + put(side, "revet_before_m", num(`${prefix}_revet_before_m`)); + put(side, "revet_after_m", num(`${prefix}_revet_after_m`)); + put(side, "structure", patch[`${prefix}_type`]); + } + put(culvert.inlet, "basin_length_m", num("inlet_basin_length_m")); + put(culvert.inlet, "basin_before_m", num("inlet_basin_before_m")); + put(culvert.inlet, "basin_after_m", num("inlet_basin_after_m")); + // 연장이 바뀌면 옆 측점 링크도 달라진다 — 그 구조물이 덮는 범위만 다시 그린다. + const reach = Math.max( + culvert.inlet.revet_before_m ?? 0, + culvert.inlet.revet_after_m ?? 0, + culvert.outlet.revet_before_m ?? 0, + culvert.outlet.revet_after_m ?? 0, + num("inlet_revet_length_m") ?? 0, + num("outlet_revet_length_m") ?? 0, + ); + for (const other of sectionDetail?.cross_sections ?? []) { + if (Math.abs(other.chainage_m - owner.chainage_m) <= reach + 1e-9) { + sectionView.refreshCard(other.chainage_m); + } + } + } const dockDivider = document.createElement("hr"); dockDivider.className = "b05-structure__divider"; const actionDock = document.createElement("div"); diff --git a/B06_Section/B06_Section_UI_Page_Structures_Panel.ts b/B06_Section/B06_Section_UI_Page_Structures_Panel.ts index e6079639..947fc02b 100644 --- a/B06_Section/B06_Section_UI_Page_Structures_Panel.ts +++ b/B06_Section/B06_Section_UI_Page_Structures_Panel.ts @@ -40,6 +40,9 @@ export interface B06StructuresPanelDeps { /** 폼 [수정]으로 바뀐 관 옵션을 캐시에 예약한다 — [저장]·[확정]이 정본에 쓴다 * (2026-08-29: 조정창 구간값과 같은 경로). 없으면 안내만 한다. */ queuePipeOptions?: (chainageM: number, patch: Record) => void; + /** 바뀐 값을 그 측점 횡단 캐시(culvert 스펙)에 얹고 카드를 다시 그린다 — + * 조정창과 같은 흐름이라 폼 조작도 도면에 바로 보인다(2026-08-29 사용자 보고). */ + applyPipeOptions?: (chainageM: number, patch: Record) => void; } export interface B06StructuresPanel { @@ -112,6 +115,7 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc return; } deps.queuePipeOptions(fromChainageM, patch as Record); + deps.applyPipeOptions?.(fromChainageM, patch as Record); // 화면 캐시(목록·폼 재로드용)도 같이 맞춘다 — 저장 전에도 값이 유지된다. const hit = pipeFacilities.find( (entry) => Math.abs(entry.chainage_m - fromChainageM) < PIPE_MATCH_M,