fix(b08): 구조물도 모달 일위대가 카드 — labor 손잡이 · 사본 일위대가 읽기(161-1)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01STqEqztUthVFBmEP18wBSz
This commit is contained in:
2026-10-09 23:07:42 +09:00
co-authored by Claude Opus 5.5
parent 7a6d93cdcd
commit 9323198912
2 changed files with 52 additions and 2 deletions
+18 -2
View File
@@ -13,7 +13,9 @@
import "./B08_Quantity_UI_Drawing.css";
import { ui_locales, currentLanguageIndex } from "@ui/ui_template_locale";
import { openModal } from "@ui/ui_template_modal";
import { PART_OF, projectItems } from "@ui/ui_template_item_picker_project";
import { PART_OF, projectItems, withCopyValues } from "@ui/ui_template_item_picker_project";
import type { LaborDoc } from "../M02_MasterTemplete/M02_MasterTemplete_Labor_Api";
import type { ValueDoc } from "../M02_MasterTemplete/M02_Labor_Values_Model";
import type { ItemCardsHandle } from "../M02_MasterTemplete/M02_MasterTemplete_ItemCards";
import type { ItemSource } from "../M02_MasterTemplete/M02_MasterTemplete_ItemSource";
import { summaryTooltip, type SummaryItem } from "../common_util/common_util_summary_item";
@@ -50,7 +52,8 @@ export interface SheetsRequest {
onLinked: () => void;
}
/** 사본 폴더 읽기 — 그 부분 파일이 없으면 던짐(카드가 「없음」). */
/** 사본 폴더 읽기 — 그 부분 파일이 없으면 던짐(카드가 「없음」) ·
* 일위대가 = 사본 `일위대가` · 입력값 · 고른자재 그대로(142-1 고르기 모달과 같은 길 · 161-1). */
function sourceOf(projectId: string, folder: string): ItemSource {
const items = projectItems(projectId);
return {
@@ -61,6 +64,18 @@ function sourceOf(projectId: string, folder: string): ItemSource {
if (doc == null) throw new Error(L("B08_Quantity_Sheets_NoCopy"));
return { 문서: doc };
},
labor: {
read: async () => {
const [labor, values, picks] = await Promise.all([
items.read(folder, "일위대가") as Promise<{ 줄?: LaborDoc } | null>,
items.read(folder, "입력값") as Promise<ValueDoc | null>,
items.read(folder, "고른자재") as Promise<Record<string, unknown> | null>,
]);
if (!labor?.줄) throw new Error(L("B08_Quantity_Sheets_NoCopy"));
return { 문서: withCopyValues(labor.줄, values, picks) };
},
calc: () => items.calcLabor(folder),
},
};
}
@@ -99,6 +114,7 @@ function comboSection(
editable: () => false,
onEdit: () => undefined,
warnOnFail: () => false, // 못 읽으면 카드에 「없음」
labor: () => undefined, // 일위대가 카드(161-1) — 보기 전용이라 [수정] 숨김(editable false)
});
handles.push(cards);
section.append(cards.root);
@@ -0,0 +1,34 @@
"""161-1 B08 구조물도 모달 — 일위대가 카드(보기 전용) · 사본 일위대가 읽기 · 카드 차례 도면 · 일위대가 · 면적산출."""
import re
from pathlib import Path
DRAWING = Path("B08_Quantity/B08_Quantity_UI_Drawing.ts").read_text(encoding="utf-8")
CARDS = Path("M02_MasterTemplete/M02_MasterTemplete_ItemCards.ts").read_text(encoding="utf-8")
def test_labor_handle_passed():
# createItemCards 에 labor 손잡이 — 없으면 카드 자체를 안 만듦(ItemCards `opts.labor ?`)
call = DRAWING[DRAWING.index("createItemCards({") :]
call = call[: call.index("});")]
assert "labor: () => undefined" in call
assert "editable: () => false" in call # [수정] 숨김
assert "const laborCard = opts.labor" in CARDS
def test_source_reads_copy_labor():
# 142-1 고르기 모달과 같은 길 — 사본 일위대가 · 입력값 · 고른자재 → withCopyValues · 셈도 사본
src = DRAWING[DRAWING.index("function sourceOf") : DRAWING.index("function comboSection")]
assert "labor: {" in src
for part in ('"일위대가"', '"입력값"', '"고른자재"'):
assert f"items.read(folder, {part})" in src, part
assert "withCopyValues(labor.줄, values, picks)" in src
assert "items.calcLabor(folder)" in src
assert re.search(r"if \(!labor\?\.줄\) throw", src) # 없으면 카드 「없음」
assert "src.labor ? src.labor.read(at)" in CARDS
def test_card_order_and_heads():
assert "const cards: Card[] = [info, ...(laborCard ? [laborCard] : []), ...sheets]" in CARDS
assert 'drawingInfo: "도면 정보"' in CARDS
assert 'labor: "일위대가"' in CARDS and 'area: "면적산출"' in CARDS