feat(M01): 단가산출 로직 상세 차례 · 오른쪽 흐름도/원문 두 패널

- 좌측 차례 = 기본정보 › 시험 계산 › 단가산출 상세 › 텍스트 수식
- 오른쪽 패널 둘(흐름도 · 원문) — 하나만 열림 · 둘 다 접기 · 머리 토글 단추 · 열린 패널 계정 취향(m01-logic-panel)
- 흐름도 패널 접힘을 부르는 쪽이 정하는 길(folded · onFold · fold)
- 원문 패널 = 출처 글로 품셈 본문 절을 찾아 보임(GET /api/m01/logic/source) · 못 찾으면 「원문 연결 없음」 + 출처
- 시험 test_m01_logic_source.py · 화면 시나리오 ui_checks/44-4_로직상세_패널.js

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
This commit is contained in:
2026-10-05 11:31:09 +09:00
co-authored by Claude Opus 5.5
parent 576b12eb7d
commit 7d39f90a0e
11 changed files with 520 additions and 11 deletions
+13 -3
View File
@@ -52,6 +52,7 @@ import {
type LogicFlow,
} from "./M01_MasterData_UI_LogicLab_Flow";
import { askBasicInfo } from "./M01_MasterData_UI_LogicLab_Basic";
import { buildLogicSide } from "./M01_MasterData_UI_LogicLab_Side";
import { buildHeadBar } from "./M01_MasterData_UI_Head";
import { fetchSessionUser } from "../A06_Login/A06_Login_Api_Fetch";
import type { CfLogic } from "../M02_MasterTemplete/DataFlow/M02_DF_Model";
@@ -129,6 +130,8 @@ export async function mountM01LogicLab(
const editor = el("div", { className: "m01-logic__editor" });
// 로직 상세 두 칸 — 왼쪽 지금 내용 · 오른쪽 흐름도(패널 자리) · 너비 비율 기억
const split = buildSplit(editor);
// 오른쪽 두 패널(흐름도 · 원문) — 하나만 열림 · 흐름도는 이 칸 안에 띄움
const panes = buildLogicSide(split);
const errors = el("div", { className: "m01-logic__reasons", attrs: { hidden: "" } });
const calc = el("div", { className: "m01lab__calc" });
const filterHost = el("div");
@@ -273,7 +276,9 @@ export async function mountM01LogicLab(
const startFlow = async (o: Opened): Promise<void> => {
const row = o.row;
if (!row) return;
split.right.replaceChildren(el("p", { className: "m01lab-flow__wait", text: tf("Waiting") }));
panes.flowSplit.right.replaceChildren(
el("p", { className: "m01lab-flow__wait", text: tf("Waiting") }),
);
const own = flowOf(row);
const got = own || o.origKey === null ? null : await fetchFlow(o.origKey, o.file);
// 시험 입력 한 벌 — 열 때 왼쪽 시험 계산 입력을 흐름 변수 예시값으로
@@ -284,7 +289,9 @@ export async function mountM01LogicLab(
if (opened !== o) return;
try {
const made = await mountLogicFlow({
split,
split: panes.flowSplit,
folded: panes.flowFolded(),
onFold: (on) => panes.pick(on ? "none" : "flow"),
flow: clone(o.flowBase),
title: row.이름 || row.키,
readOnly: !admin,
@@ -307,9 +314,10 @@ export async function mountM01LogicLab(
});
if (opened !== o) return made.destroy();
flowNow = made;
panes.bindFlow(made.fold);
made.setExamples(o.values); // 띄우는 사이에 온 자동값까지
} catch (e) {
split.right.replaceChildren(
panes.flowSplit.right.replaceChildren(
el("p", { className: "m01-logic__muted", text: tf("Failed", String(e)) }),
);
}
@@ -344,7 +352,9 @@ export async function mountM01LogicLab(
const show = (next: Opened | null): void => {
flowNow?.destroy();
flowNow = null;
panes.bindFlow(null);
opened = next;
panes.showSource(next?.row?.출처 ?? "");
errors.hidden = true;
drawEditor();
drawCalc();