From 8c9f45c372804e6bbfde90a8c20023cb19f38790 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Sat, 10 Oct 2026 08:34:19 +0900 Subject: [PATCH] =?UTF-8?q?fix(b08):=20=EC=82=AC=EB=B3=B8=20=ED=8E=B8?= =?UTF-8?q?=EC=A7=91=20=ED=99=94=EB=A9=B4=20[=E2=86=90=20=EB=92=A4?= =?UTF-8?q?=EB=A1=9C]=20=C2=B7=20[=EC=A0=80=EC=9E=A5]=20=3D=20=EB=AA=A8?= =?UTF-8?q?=EB=8B=AC=20=EB=A8=B8=EB=A6=AC=20[=EB=8B=AB=EA=B8=B0]=20?= =?UTF-8?q?=EC=99=BC=EC=AA=BD=20=C2=B7=20=EA=B0=99=EC=9D=80=20=ED=81=AC?= =?UTF-8?q?=EA=B8=B0(170-2)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01STqEqztUthVFBmEP18wBSz --- B08_Quantity/B08_Quantity_UI_Drawing.css | 5 ++++ B08_Quantity/B08_Quantity_UI_Drawing.ts | 16 ++++++++++++ resources/tester/test_170_b08_modal_head.py | 27 +++++++++++++++++++++ ui_template/ui_template_item_picker_edit.ts | 5 +++- 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/B08_Quantity/B08_Quantity_UI_Drawing.css b/B08_Quantity/B08_Quantity_UI_Drawing.css index b6133d76d..1b54d1c94 100644 --- a/B08_Quantity/B08_Quantity_UI_Drawing.css +++ b/B08_Quantity/B08_Quantity_UI_Drawing.css @@ -51,6 +51,11 @@ } } +/* 머리 단추 칸(170-2) — 편집 화면 밖에선 숨김 */ +.b08-sheets .ui-modal__actions[hidden] { + display: none; +} + /* 카드 [수정] → 사본 편집 화면(163-3) — 모달 몸통을 채움 · 넣을 값이면 안내 한 줄 위 */ .b08-sheets .ui-item-picker__edit-host { flex-direction: column; diff --git a/B08_Quantity/B08_Quantity_UI_Drawing.ts b/B08_Quantity/B08_Quantity_UI_Drawing.ts index 3270e135e..785ef79c4 100644 --- a/B08_Quantity/B08_Quantity_UI_Drawing.ts +++ b/B08_Quantity/B08_Quantity_UI_Drawing.ts @@ -145,6 +145,14 @@ export function openStructureSheets(request: SheetsRequest): void { let edited = false; // 사본을 고쳐 저장함 — 닫을 때 집계표 다시 셈(163-3) let editView: EditView | null = null; let modalBody: HTMLElement | null = null; + // 머리 단추 칸(170-2) — 공용 모달은 열 때 단추가 있어야 머리에 붙임 → 빈 칸을 미리 넘김 · 편집 화면에서만 채움 + const head = document.createElement("div"); + head.className = "ui-modal__actions"; + head.hidden = true; + const clearHead = (): void => { + head.replaceChildren(); + head.hidden = true; + }; /** 카드 [수정] — 몸통을 사본 편집 화면으로 · [뒤로] = 몸통 되돌리고 그 카드 다시 읽음 */ const openEdit: OpenEdit = (copy, name, kind, reload) => { const body = modalBody; @@ -170,12 +178,18 @@ export function openStructureSheets(request: SheetsRequest): void { (saved) => { view.destroy(); editView = null; + clearHead(); body.replaceChildren(...kept); edited ||= saved; if (saved) reload(); }, ); editView = view; + // [← 뒤로] · [저장] = 머리 [닫기] 왼쪽 · 크기 = [닫기](sm 뗌) + view.back.classList.remove("ui-btn--sm"); + view.save.classList.remove("ui-btn--sm"); + head.replaceChildren(view.back, view.save); + head.hidden = false; host.append( ...(kind === "inputs" ? [note(L("B08_Quantity_Sheets_InputsOnly"))] : []), view.root, @@ -192,9 +206,11 @@ export function openStructureSheets(request: SheetsRequest): void { closeLabel: L("Common_Btn_Close"), wide: true, // 공용 큰 창(96vw × 94vh · 156-4) dialogClass: "b08-sheets", + actions: [head], beforeClose: async () => { if (editView && !(await editView.leave())) return false; // 저장 안 한 고침 — 버릴지 물음 editView?.destroy(); + clearHead(); closed = true; // 아직 불러오는 중이면 뒤늦게 카드를 만들지 않음 handles.forEach((cards) => cards.destroy()); if (edited) request.onLinked(); // 사본을 고쳤으면 집계표 다시 셈(연결 저장과 같은 꼴) diff --git a/resources/tester/test_170_b08_modal_head.py b/resources/tester/test_170_b08_modal_head.py index e3a9fdb21..df73e7398 100644 --- a/resources/tester/test_170_b08_modal_head.py +++ b/resources/tester/test_170_b08_modal_head.py @@ -52,3 +52,30 @@ def test_170_3_칩_테두리_상태_색(): "border-style: dashed;" in DRAWING_CSS.split(".b08-link__chip.is-gone {", 1)[1].split("}", 1)[0] ) + + +DRAWING = (ROOT / "B08_Quantity/B08_Quantity_UI_Drawing.ts").read_text(encoding="utf-8") +EDIT = (ROOT / "ui_template/ui_template_item_picker_edit.ts").read_text(encoding="utf-8") +PICKER = (ROOT / "ui_template/ui_template_item_picker.ts").read_text(encoding="utf-8") +MODAL = (ROOT / "ui_template/ui_template_modal.ts").read_text(encoding="utf-8") + + +def test_170_2_편집_화면_단추_모달_머리(): + # 편집 화면이 두 단추를 내보냄 · 고르기 모달(142-1)은 그대로 안 씀 + assert "back: HTMLButtonElement;" in EDIT and "save: HTMLButtonElement;" in EDIT + assert "return { root, back, save," in EDIT + assert "view.back" not in PICKER and "view.save" not in PICKER + # 빈 머리 칸을 열 때 미리 넘김(공용 모달은 mount 때 자식 있을 때만 머리에 붙임) + assert "if (actions.childElementCount) closeButton.before(actions)" in MODAL + assert "actions: [head]," in DRAWING and "head.hidden = true;" in DRAWING + # 들어갈 때 옮김 · 크기 = [닫기](md) · 차례 [← 뒤로] [저장] [닫기] + assert 'view.back.classList.remove("ui-btn--sm")' in DRAWING + assert 'view.save.classList.remove("ui-btn--sm")' in DRAWING + assert "head.replaceChildren(view.back, view.save);\n head.hidden = false;" in DRAWING + # 나올 때([뒤로] · 닫기) 거둠 + back = DRAWING.split("(saved) => {", 1)[1].split("},", 1)[0] + assert "clearHead();" in back + closing = DRAWING.split("beforeClose: async () => {", 1)[1].split("return true;", 1)[0] + assert "clearHead();" in closing + css = DRAWING_CSS + assert ".b08-sheets .ui-modal__actions[hidden] {\n display: none;" in css diff --git a/ui_template/ui_template_item_picker_edit.ts b/ui_template/ui_template_item_picker_edit.ts index 0958442c7..c39f4385b 100644 --- a/ui_template/ui_template_item_picker_edit.ts +++ b/ui_template/ui_template_item_picker_edit.ts @@ -20,6 +20,9 @@ import { laborValueData, PART_OF } from "./ui_template_item_picker_project"; export interface EditView { root: HTMLElement; + /** [← 뒤로] · [저장] — 모달 머리로 옮겨 쓸 수 있음(B08 · 170-2) */ + back: HTMLButtonElement; + save: HTMLButtonElement; /** 붙인 뒤 부름 — 편집 부품을 받아 세움 */ start: () => void; isDirty: () => boolean; @@ -212,5 +215,5 @@ export function createEditView(req: EditRequest, onBack: (saved: boolean) => voi if (await leave()) onBack(saved); }); - return { root, start: () => void start(), isDirty: () => dirty, leave, destroy }; + return { root, back, save, start: () => void start(), isDirty: () => dirty, leave, destroy }; }