/* ============================================================================= * M02_SO_Def_Spec_Model.ts * 구조물 명세(PLAN 52 · `design_structure_spec`) 이름 고치기(52-11)의 자료 손질 — 화면 그리기 없음. * * · 명세 = 구조 정본(키 · 컨테이너 · 필수/선택 · 꼴) — 여기서는 **이름만** 고침 * · 이름 자리 = 정의 `종류.{종류}.이름`(키 `{컨테이너}` · `{컨테이너}.{항목}` · `{컨테이너}.{항목}={값}`) * · 필수 컨테이너 제목 = 이름 표에 없으면 정의 그룹(`그룹.{종류}` 의 `id = link`) 이름 — B05 그리기 * (`containerTitle`)와 같은 차례로 읽고 그 자리에 씀 * import 는 꼴만 — 시험이 이 파일만 옮겨 돌림. * ========================================================================== */ import type { StructureSpec } from "../../A00_Common/design/design_structure_spec"; import type { StructDef } from "./M02_SO_Def_Model"; export interface SpecNameRow { /** 0 = 컨테이너 · 1 = 항목 · 2 = 값 */ level: 0 | 1 | 2; /** 이름 표 키 */ nameKey: string; /** 읽기만 표시 — 컨테이너 id · 항목 id · 값 */ key: string; /** 지금 이름 */ label: string; /** 읽기만 표시 — 필수/선택 · 꼴 */ tag: "required" | "optional" | "select" | "number" | "auto" | null; /** 필수 컨테이너 제목이 정의 그룹 이름에서 옴 — 고치면 그 그룹 이름에 씀 */ group: string | null; } /** 명세 차례대로 이름 줄 — 같은 이름 키(갈래마다 겹친 값)는 한 줄. */ export function specNameRows(def: StructDef, spec: StructureSpec): SpecNameRow[] { const names = def.종류[spec.typeId]?.이름 ?? {}; const groups = def.그룹[spec.typeId] ?? []; const rows: SpecNameRow[] = []; const seen = new Set(); const push = (row: SpecNameRow): void => { if (seen.has(row.nameKey)) return; seen.add(row.nameKey); rows.push(row); }; for (const c of spec.containers) { const group = c.required && names[c.id] === undefined ? groups.find((g) => g.id === c.link) : undefined; push({ level: 0, nameKey: c.id, key: c.id, label: names[c.id] ?? group?.이름 ?? c.title, tag: c.required ? "required" : "optional", group: group ? group.id : null, }); for (const item of c.items) { const itemKey = `${c.id}.${item.id}`; push({ level: 1, nameKey: itemKey, key: item.id, label: names[itemKey] ?? item.label, tag: item.kind, group: null, }); const choices = [ ...(item.choices ?? []), ...Object.values(item.by?.map ?? {}).flatMap((b) => b.choices ?? []), ]; for (const ch of choices) { const choiceKey = `${itemKey}=${ch.value}`; push({ level: 2, nameKey: choiceKey, key: ch.value, label: names[choiceKey] ?? ch.label, tag: null, group: null, }); } } } return rows; } /** 이름 하나를 사본에 씀 — 그룹에서 온 제목은 그 그룹 이름 · 나머지는 이름 표. */ export function setSpecName(def: StructDef, typeId: string, row: SpecNameRow, value: string): void { const group = row.group ? def.그룹[typeId]?.find((g) => g.id === row.group) : undefined; if (group) { group.이름 = value; return; } const kind = (def.종류[typeId] ??= {}); (kind.이름 ??= {})[row.nameKey] = value; }