/* ============================================================================= * B05_Profile_UI_Drainage_Suggest.ts * 배수유역 칸 제안 목록(347-3) — 관경 · 시설 종류 · 관 자리 후보를 보여 주고 [적용] 한 번에 관 초안으로. * 모으기 · 얹기 규칙은 `logic/B05_Profile_Drainage_Suggest.ts` · 자동 바꿈 없음. * 관 자리 후보는 배수유역도에도 점선 원으로 그림(`candidates()` → 그리기 판). * ========================================================================== */ import type { DetailBasinResponse, DetailPipeInput, } from "../B04_PreProcess/B04_PreProcess_Api_Fetch"; import { applySuggestions, collectSuggestions, type Suggestion, } from "./logic/B05_Profile_Drainage_Suggest"; const FACILITY_NAME: Record = { pipe: "배관", box_culvert: "BOX암거", ford_bridge: "세월교", }; const facilityName = (id: string): string => FACILITY_NAME[id] ?? id; /** 제안 한 줄 글. */ export function suggestionText(item: Suggestion): string { const at = `측점 ${Math.round(item.chainageM)} m`; if (item.kind === "position") return `${at} — 관 자리 후보(흐름이 모이는 오목 자리)`; if (item.kind === "facility") return `${at} — ${facilityName(item.from)} → ${facilityName(item.to)} 검토`; return `${at} — 관경 ${item.from === null ? "미정" : `Ø${item.from}`} → Ø${item.to}`; } export interface DrainageSuggest { root: HTMLElement; update(response: DetailBasinResponse): void; /** 노선 · 관이 바뀌어 낡음 — [적용] 끔(옛 노선 기준 제안이 새 노선에 안 들어가게). */ setStale(stale: boolean): void; /** 관 자리 후보 누가거리 — 배수유역도 점선 원. */ candidates(): number[]; } export function createDrainageSuggest( pipeRequest: () => DetailPipeInput[], applyPoints: (points: DetailPipeInput[]) => void, ): DrainageSuggest { const root = document.createElement("div"); root.className = "b05-drainage__suggest"; root.hidden = true; const head = document.createElement("div"); head.className = "b05-drainage__suggest-head"; const title = document.createElement("span"); const apply = document.createElement("button"); apply.type = "button"; apply.className = "b05-drainage__analyze"; apply.textContent = "적용"; const applyTitle = "제안을 관 초안에 한 번에 얹습니다(관 더함 · 관경 · 시설 바꿈) — [저장] 때 남습니다."; apply.title = applyTitle; head.append(title, apply); const list = document.createElement("ul"); list.className = "b05-drainage__suggest-list"; root.append(head, list); let suggestions: Suggestion[] = []; apply.addEventListener("click", () => { if (suggestions.length && !apply.disabled) applyPoints(applySuggestions(pipeRequest(), suggestions)); }); return { root, update(response) { suggestions = response.stale ? [] : collectSuggestions(response.pipe_points, response.basins, response.pipe_candidates ?? []); root.hidden = suggestions.length === 0; title.textContent = `제안 ${suggestions.length}건`; list.replaceChildren( ...suggestions.map((item) => { const row = document.createElement("li"); row.textContent = suggestionText(item); return row; }), ); }, setStale(stale) { apply.disabled = stale; apply.title = stale ? "노선이 바뀌어 제안이 낡음 — 새 계산 뒤 적용" : applyTitle; }, candidates: () => suggestions.filter((item) => item.kind === "position").map((item) => item.chainageM), }; }