diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab.ts b/M01_MasterData/M01_MasterData_UI_LogicLab.ts index 3143cfa60..3f29328c9 100644 --- a/M01_MasterData/M01_MasterData_UI_LogicLab.ts +++ b/M01_MasterData/M01_MasterData_UI_LogicLab.ts @@ -41,6 +41,7 @@ import { tl } from "./M01_MasterData_UI_LogicLab_Text"; import { buildSplit, emptyFlow, + designFields, examplesOf, fetchFlow, fetchFlowFor, @@ -86,6 +87,11 @@ interface Opened extends Draft { /** 줄의 흐름(있으면 흐름도로 셈) */ const flowOf = (row: LogicRow | null): CfLogic | null => (row?.흐름 as CfLogic | undefined) ?? null; const OWN_FILE = "로직_자체.json"; +/** 시험 계산에 넘길 줄 — 흐름 로직은 입력 칸을 흐름의 「설계 때 정할 것」으로(옛 식 칸은 서버가 지움) */ +const calcRow = (row: LogicRow | null): LogicRow | null => { + const f = flowOf(row); + return f && row ? { ...row, 입력: designFields(f) } : row; +}; const cacheKey = "m01_logic_drafts_lab"; const ownHost = (): HTMLElement => el("div", { className: "m01lab__own" }); @@ -169,7 +175,7 @@ export async function mountM01LogicLab( else drafts[opened.id] = pick(opened, clone(opened.row)); persist(); if (!flowOf(opened.row)) scheduleFlow(opened); // 왼쪽 편집기로 고침 — 오른쪽 흐름도도 따라감 - const inputs = JSON.stringify(opened.row.입력 ?? []); + const inputs = JSON.stringify(calcRow(opened.row)?.입력 ?? []); if (inputs !== calcInputs) drawCalc(); if (isOwnLogic(opened.row)) { // 자체 로직 — 고친 뒤 잠시 쉬면 다시 계산해 호표 소계와 텍스트 수식을 새로 그림 @@ -192,11 +198,11 @@ export async function mountM01LogicLab( return; } const current = opened; - calcInputs = JSON.stringify(current.row?.입력 ?? []); + calcInputs = JSON.stringify(calcRow(current.row)?.입력 ?? []); buildCalc(calc, { savedKey: current.origKey, file: current.file, - row: current.row as LogicRow, + row: calcRow(current.row) as LogicRow, prices: current.prices, dirty: () => current.id in drafts, values: current.values, @@ -309,7 +315,7 @@ export async function mountM01LogicLab( /** 흐름 예시값 → 왼쪽 시험 계산 입력(이름이 있는 칸만) · 바뀌면 왼쪽을 다시 그리고 셈 */ const syncLeft = (o: Opened, ex: Record): void => { - const names = new Set((o.row?.입력 ?? []).map((x) => x.이름)); + const names = new Set((calcRow(o.row)?.입력 ?? []).map((x) => x.이름)); const changed = Object.entries(ex).filter(([k, v]) => names.has(k) && o.values[k] !== v); if (!changed.length) return; quiet = true; diff --git a/M01_MasterData/M01_MasterData_UI_LogicLab_Flow.ts b/M01_MasterData/M01_MasterData_UI_LogicLab_Flow.ts index 4642527d9..e673caed8 100644 --- a/M01_MasterData/M01_MasterData_UI_LogicLab_Flow.ts +++ b/M01_MasterData/M01_MasterData_UI_LogicLab_Flow.ts @@ -195,6 +195,25 @@ export function withExamples(lg: CfLogic, vals: Record): CfLogic return next; } +/** 흐름 로직의 시험 계산 입력 칸 — 「설계 때 정할 것」(변수 · 고르기 · 범위 · 단위) · 이름이 겹치면 하나 */ +export function designFields( + lg: CfLogic, +): { 이름: string; 단위?: string; 고르기?: (string | number)[]; 범위?: [number, number] }[] { + const seen = new Set(); + return varsOf(lg).flatMap((v) => { + if (!v.name || seen.has(v.name)) return []; + seen.add(v.name); + return [ + { + 이름: v.name, + ...(v.unit && v.unit !== "-" ? { 단위: v.unit } : {}), + ...(v.type === "choice" && v.choices?.length ? { 고르기: v.choices } : {}), + ...(v.range ? { 범위: v.range } : {}), + }, + ]; + }); +} + /** 예시값만 다른가 — 그 밖이 같으면 고친 것으로 안 셈 */ export function sameShape(a: CfLogic, b: CfLogic): boolean { const strip = (lg: CfLogic): string => {