refactor(m01): 흐름 왼쪽 보기 — 식 보기를 sub2 formulaLines 직접 import 로

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EauA2ATmqNRbeV48s9CcBr
This commit is contained in:
2026-10-01 23:40:53 +09:00
co-authored by Claude Sonnet 5.5
parent d584cdeb9e
commit 3ea0c0fdf2
@@ -1,7 +1,7 @@
/* =============================================================================
* M01_MasterData_UI_LogicLab_FlowView.ts
* 흐름 로직의 왼쪽 「지금 내용」 — ② 단가산출 상세(출력 상자를 비용 종류별 줄 · 소계 · 계) · ③ 텍스트 수식(함수 상자마다
* 식 두 줄 — sub2 `formulaLines` 가 있으면 그것 · 없으면 함수 이름 · 결과 값만). 기본정보 · 시험 계산은 Detail 이 둠.
* 식 두 줄 — sub2 `formulaLines`). 기본정보 · 시험 계산은 Detail 이 둠.
* 값은 DataFlow 계산(Eval · 같은 코드)으로 바로 — 오른쪽 패널이 고치면 LogicLab 이 이 함수를 다시 부름.
* 화면은 `buildFlowView(host, lg, values)` 하나. 이 파일은 DataFlow 를 정적으로 가져오므로 LogicLab 은 import() 로 늦게 부름.
* 모양은 docs/raw/M01_쉬운단가/흐름도_적용_정함.md 7 · 8.
@@ -15,7 +15,12 @@ import {
type CfEvalResult,
type CfValues,
} from "../M02_MasterTemplete/DataFlow/M02_DF_Eval";
import type { CfBox, CfLogic } from "../M02_MasterTemplete/DataFlow/M02_DF_Model";
import {
cellValuesOf,
formulaLines,
type FormulaLine,
} from "../M02_MasterTemplete/DataFlow/M02_DF_FormulaView";
import type { CfLogic } from "../M02_MasterTemplete/DataFlow/M02_DF_Model";
import { itemRoundNow, totalRoundNow } from "../M02_MasterTemplete/DataFlow/M02_DF_Round";
import {
flowRows,
@@ -51,22 +56,6 @@ const GROUP_TITLE: Record<FlowGroupKey, TextKey> = {
plain: "Plain",
};
/** sub2 의 식 보기(`M02_DF_FormulaView.ts` · 정함 8) — 아직 없으면 비어 있음 */
interface FormulaLine {
name: string;
named: string;
valued: string;
branches?: { when: string; then: string; now: boolean }[];
}
type FormulaFn = (box: CfBox, values: CfValues) => FormulaLine[];
const FORMULA = import.meta.glob<{ formulaLines?: FormulaFn }>(
"../M02_MasterTemplete/DataFlow/M02_DF_FormulaView.ts",
);
const loadFormula = async (): Promise<FormulaFn | null> => {
const load = Object.values(FORMULA)[0];
return load ? ((await load()).formulaLines ?? null) : null;
};
const section = (title: string, body: HTMLElement[]): HTMLElement =>
el("section", {
className: "m01-logic__section m01lab__box",
@@ -182,26 +171,20 @@ export function buildFlowView(
el("p", { className: "m01-logic__muted", text: tf("TotalNote") }),
...rows.errors.slice(0, 3).map((t) => el("p", { className: "m01flow__warn", text: t })),
]);
const bodies = rows.funcs.map((f) => funcBlock(f, null));
/** 함수 상자마다 식 두 줄(sub2 식 보기 · 받는 알약 값을 칸에 넣고 셈) — 못 그리면 이름 = 값만 */
const linesOf = (id: string): FormulaLine[] | null => {
const box = lg.boxes.find((b) => b.id === id);
if (!box?.func) return null;
try {
return formulaLines(box, cellValuesOf(box, ev.arrived?.[id]));
} catch {
return null;
}
};
const bodies = rows.funcs.map((f) => funcBlock(f, linesOf(f.box)));
const text = section(
tf("Formula"),
bodies.length ? bodies : [el("p", { className: "m01-logic__muted", text: tf("NoFunc") })],
);
host.replaceChildren(detail, text);
// sub2 식 보기가 올라와 있으면 함수 상자마다 식 두 줄을 더함
void loadFormula().then((fn) => {
if (!fn || !bodies.length) return;
const boxes = lg.boxes.filter((b) => b.kind === "function" && b.func);
const merged = { ...ev.ports, ...ev.arrived } as CfValues;
text.replaceChildren(
text.firstElementChild!,
...rows.funcs.map((f, i) => {
try {
return funcBlock(f, fn(boxes[i], merged));
} catch {
return bodies[i];
}
}),
);
});
}