feat(M01): 로직 컨테이너를 셋으로 — 「로직 흐름 보기」(예전 C형 단독 · 읽기 + 시험 계산) 되살림 · 거름 기억과 캐시 열쇠 셋이 따로

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016WRFJmmhPi4exAzHgPZHMT
This commit is contained in:
2026-09-21 12:22:05 +09:00
co-authored by Claude Sonnet 5
parent 83752f8698
commit ce5184348d
7 changed files with 788 additions and 25 deletions
+13 -2
View File
@@ -77,6 +77,7 @@ export interface SideHandle {
logicHost: HTMLElement;
/** 「로직 쉽게 보기·만들기」 컨테이너 안(같은 로직 목록이 들어갈 자리) */
easyHost: HTMLElement;
cviewHost: HTMLElement;
/** 그룹의 파일 판본을 다시 받음(저장 뒤) — 돌려받는 것 = 새 목록 */
refresh: (group: string) => Promise<FileInfo[]>;
setActive: (id: string | null) => void;
@@ -131,11 +132,13 @@ const LEAF: Group[] = ["환율", "요율"];
const FILTERED: Group[] = ["인력", "기계", "소요량", "계수"];
const LOGIC_ID = "로직|";
const EASY_ID = "쉬움|";
const CVIEW_ID = "흐름|";
export function buildSide(
onOpen: (pick: Pick) => void,
onLogic: () => void,
onEasy: () => void,
onCView: () => void,
): SideHandle {
const lists = new Map<Group, FileInfo[]>();
const bodies = new Map<Group, HTMLElement>();
@@ -419,10 +422,18 @@ export function buildSide(
onEasy();
});
const root = el("div", { className: "m01-side", children: [...groups, logic, easy] });
const cviewHost = el("div", { className: "m01-side__items" });
const cview = section(tx("CView_Title"), cviewHost);
cview.querySelector(".ui-collapsible__title")?.addEventListener("click", () => {
if (!cview.classList.contains("is-collapsed")) return;
setActive(buttons.has(CVIEW_ID) ? CVIEW_ID : null);
onCView();
});
const root = el("div", { className: "m01-side", children: [...groups, logic, easy, cview] });
attachCollapsible(root);
void Promise.all(GROUPS.map(refresh)).catch((error) =>
showToast(error instanceof Error ? error.message : L("M01_LoadFailed"), "error"),
);
return { root, logicHost, easyHost, refresh, setActive, filter };
return { root, logicHost, easyHost, cviewHost, refresh, setActive, filter };
}