refactor(M02): 자재 조합(UM) 지움 — 좌측 컨테이너 · 재료산출 옆 판 · 길(material-combos · 갈라 내기 · 키 적기 자재조합) · 저장소 · 틀 검사 · 복사 길의 UM 줄 · 시스템 층 표 · fixture · 시험

- 자재 고르기 창은 M02_Material_Pick.ts 로 옮겨 남김
- storage 층(회사 · 개인 · 프로젝트) 자재조합.json 은 지우지 않음(읽기만 끊음)
- check_master 틀 검사 · _틀.md 11장 · _화면_계약.md 자재 조합 절 정리

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-04 17:39:16 +09:00
co-authored by Claude Opus 5.5
parent 8fde124df5
commit 54ce67ceb8
51 changed files with 129 additions and 1645 deletions
@@ -45,7 +45,6 @@ import {
type SheetEditOptions,
type SheetKind,
} from "./M02_MasterTemplete_ItemCards";
import { buildMaterialPanel, loadMaterialState, toPills } from "./M02_MasterTemplete_Materials";
import { layerSource } from "./M02_MasterTemplete_ItemSource";
import { createInputsCard, inputPills, type InputsCardHandle } from "./M02_MasterTemplete_Inputs";
import "./M02_MasterTemplete_Structure.css";
@@ -302,61 +301,12 @@ export async function pillsFor(
}
}
/** 카드 미리보기 수정의 알약 · 자재 조합 판(31-3) — 전체 편집기(`UI_Main` `mountSheet`)와 같은 부품 ·
* 면적 = 그 열 일위대가 입력값(`pillsFor`) · 재료 = 자재 조합 담은 자재 + 선택 입력 · 아래 자재 조합 판 */
/** 카드 미리보기 수정의 알약(31-3) — 전체 편집기(`UI_Main` `mountSheet`)와 같은 부품(`pillsFor`) */
async function cardLinks(
kind: SheetKind,
ctl: SheetCardControl,
isAdmin: boolean,
): ReturnType<SheetEditOptions["links"]> {
if (kind === "area") return { links: (await pillsFor("area", ctl.column)).links };
const [state, own] = await Promise.all([
loadMaterialState(ctl.column),
inputPills(ctl.column, "재료"), // 「선택 입력」 카드가 재료산출로 고른 입력
]);
let items = state.combo?.담은자재 ?? [];
const links = (): LinkOptions => ({
항목: [...toPills(items), ...own],
모드: "자재",
자재찾기: searchMaterials,
// 알약 막대에서 추가 · 빼기 — 아래 판 표를 같은 목록으로
onItemsChange: (list) => {
items = list.flatMap((i) => (i.자재 ? [{ ...i.자재 }] : []));
panel.setItems(items);
},
});
const panel = buildMaterialPanel({
column: ctl.column,
label: ctl.label,
isAdmin,
state,
links: () =>
ctl
.handle()
?.getDoc()
.시트.flatMap((s) => s.연결 ?? []) ?? [],
// 판 표에서 고침 — 알약 막대만 이 목록으로 다시 만듦(저장 안 한 시트 고침은 그대로)
onChange: (list) => {
items = list;
ctl.remount(links());
},
goTo: (code) =>
ctl.host
.querySelector<HTMLElement>(`.ss-link.is-linked[data-key="${CSS.escape(code)}"]`)
?.click(),
unlink: (codes) => {
const book = ctl.handle()?.getDoc();
if (!book) return;
for (const sheet of book.시트) {
const rest = (sheet.연결 ?? []).filter((l) => !codes.includes(l.자재?.코드 ?? l.키));
if (rest.length) sheet.연결 = rest;
else delete sheet.연결;
}
ctl.handle()?.setDoc(book);
ctl.touched();
},
});
return { links: links(), below: panel.root, refresh: panel.refresh };
return { links: (await pillsFor(kind, ctl.column)).links };
}
export interface StructurePanelOptions {
@@ -417,7 +367,7 @@ export function createStructurePanel(opts: StructurePanelOptions): StructurePane
// 면적산출 · 재료산출 카드 미리보기 수정(31-3) — 전체 편집기와 같은 알약 · 저장 길
sheetEdit: {
can: () => opts.isAdmin,
links: (kind, ctl) => cardLinks(kind, ctl, opts.isAdmin),
links: (kind, ctl) => cardLinks(kind, ctl),
save: async (kind, at, doc, version) =>
(await saveTemplate(getActiveLayer(), kind, at, null, version, doc)).판,
},