/* ============================================================================= * A00_Common/design/design_structure_status.ts * 구조물 현황 한 벌(322-3) — 저장분 둘(관 `pipe_points.json` · 구조물 `structures.json`) + 초안 둘(세션) * → 한 목록(초안이 있으면 초안 · 없으면 저장분 · 종류마다 따로) · 측점 계획 한 벌(`planStations`) → * 종단 측점 목록(B05 종단 · 3D 막대 · B06 종단 띠가 같은 꼴). * * 구조물 id = 구조물은 structure_id · 관은 세션 id(`design_pipe_ids` · 323-5 · 파일 모양 그대로 · 저장 안 함). * ========================================================================== */ import type { IrregularStation } from "../../B05_Profile/B05_Profile_UI_IrregularStations"; import type { PlannedStation } from "../../common_util/common_util_structure_station"; import { useDesignStore, type DesignStoreValues } from "./design_store"; /** 현황 — 종류마다 초안이 앞섬(초안 null = 만진 적 없음 · 빈 목록 = 다 지움). */ export function structureStatus( saved: readonly [ReadonlyArray

, ReadonlyArray], drafts: readonly [ReadonlyArray

| null, ReadonlyArray | null], ): { pipes: P[]; structures: S[] } { return { pipes: [...(drafts[0] ?? saved[0])], structures: [...(drafts[1] ?? saved[1])] }; } /** * 측점 계획 → 종단 측점(측점번호 · 잔여거리 = 간격 기준) — 기준 측점 id = 첫 주인 id(관 = `pipe-…` · * 구조물 = structure_id) · 시작 · 끝 = `{id}:{역할}`(옮겨도 계획고 편집이 따라감 · 272) · 관 기준 측점 = * 「배관」 꼴(관 끌기 · 지우기 길). */ export function plannedIrregular( planned: ReadonlyArray, intervalM: number, ): IrregularStation[] { const interval = intervalM > 0 ? intervalM : 20; return planned.map((station) => { const owner = station.owners[0]; const pipe = owner.startsWith("pipe-") && station.role === "anchor"; const number = Math.floor(station.chainage_m / interval); return { id: station.role === "anchor" ? owner : `${owner}:${station.role}`, station: number, remainder: station.chainage_m - number * interval, chainage_m: station.chainage_m, structure: station.title, ...(pipe ? { structureType: "배관" as const, origin: "pipe" as const } : {}), }; }); } /** * 바뀜 신호 하나(323-6) — 관 · 구조물 초안을 구독(어느 길로 쓰든 설계 가게 한 곳). 구조물 = 늘 · 관 = 자리 · 종류 · * 구간 · 잇기가 바뀔 때만(옵션만 고친 것은 폼 길 `applyPipeOptions` 가 그 카드만 고침 — 카드 줌 · 팬 지킴). * 돌려주는 함수로 끊음. */ export function watchDrafts(projectId: string | null, onChange: () => void): () => void { const shop = useDesignStore(projectId, null); type Pipe = NonNullable[number]; const layout = (pipes: ReadonlyArray | null): string => JSON.stringify( (pipes ?? []).map((p) => [ p.chainage_m, p.facility ?? "pipe", p.start_m ?? null, p.end_m ?? null, p.summary_item ?? null, p.group_items ?? null, ]), ); let seen = layout(shop.get("pipes")); const offs = [ shop.subscribe("structures", onChange), shop.subscribe("pipes", (pipes) => { const key = layout(pipes); if (key === seen) return; seen = key; onChange(); }), ]; return () => offs.forEach((off) => off()); }