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
@@ -235,6 +235,9 @@ export interface LogicFlowOpts {
/** 흐름 로직이면 왼쪽 「지금 내용」 자리(LogicLab_Detail 의 flowHost) */
leftHost(): HTMLElement | null;
onChange(lg: CfLogic): void;
/** 패널 접힘 — 부르는 쪽(오른쪽 두 패널)이 정함 */
folded?: boolean;
onFold?(on: boolean): void;
}
export interface LogicFlow {
@@ -244,6 +247,8 @@ export interface LogicFlow {
redrawLeft(): void;
/** 왼쪽 시험 계산 입력이 바뀜 — 같은 이름 변수의 예시값으로(고친 것 아님) */
setExamples(vals: Record<string, string>): void;
/** 패널 접기 · 펴기 */
fold(on: boolean): void;
destroy(): void;
}
@@ -312,6 +317,8 @@ export async function mountLogicFlow(opts: LogicFlowOpts): Promise<LogicFlow> {
readOnly: opts.readOnly,
logics: getLogic,
onResize: (px) => opts.split.setRight(px),
folded: opts.folded,
onFold: opts.onFold,
onChange: (next) => {
lg = next;
opts.onChange(next);
@@ -329,6 +336,7 @@ export async function mountLogicFlow(opts: LogicFlowOpts): Promise<LogicFlow> {
refresh();
},
redrawLeft: left,
fold: (on) => panel.fold(on),
setExamples: (vals) => {
const next = withExamples(lg, vals);
if (JSON.stringify(next) === JSON.stringify(lg)) return;