feat(b08): 구조물도 모달 연결 칩 · 접기 · 카드 2:3:3 · 사본 [수정] · [업데이트] 배지(163-1~4)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01STqEqztUthVFBmEP18wBSz
This commit is contained in:
@@ -90,11 +90,12 @@ def test_집계_모든_시설_칸_끊으면_미연결(root, monkeypatch):
|
||||
|
||||
def test_화면_연결된_칸만_끊기_닫기_양식():
|
||||
ui = (ROOT / "B08_Quantity/B08_Quantity_UI_Link.ts").read_text(encoding="utf-8")
|
||||
assert 'if (slot.linked) buttons.append(act(L("B08_Quantity_Link_Unlink"), unlink))' in ui
|
||||
assert "if (slot.linked) {" in ui
|
||||
assert 'act(L("B08_Quantity_Link_Unlink"), () => unlink(projectId, facility, slot))' in ui
|
||||
assert ".link(slot.copy, facility.facility, null)" in ui
|
||||
assert 'showConfirmDialog(L("B08_Quantity_Link_UnlinkAsk")' in ui
|
||||
assert ui.count("hasPendingDesign(projectId)") == 2 # 선택 · 끊기 둘 다 막음
|
||||
assert 'size: "sm"' not in ui # 모달 [닫기] = ghost · 기본 크기
|
||||
assert 'variant: "ghost",\n size: "sm"' in ui # 칩 안 작은 ghost(163-1)
|
||||
modal = (ROOT / "ui_template/ui_template_modal.ts").read_text(encoding="utf-8")
|
||||
assert 'label: opts.closeLabel,\n variant: "ghost",\n onClick' in modal
|
||||
page = (ROOT / "B08_Quantity/B08_Quantity_UI_Summary.ts").read_text(encoding="utf-8")
|
||||
@@ -108,5 +109,7 @@ def test_156_4_구조물도_모달_큰_창_세_칸():
|
||||
assert "wide: true" in sheets
|
||||
css = (ROOT / "B08_Quantity/B08_Quantity_UI_Drawing.css").read_text(encoding="utf-8")
|
||||
assert "min(1320px" not in css # 자기 폭 없음 — 공용 wide 그대로
|
||||
assert "minmax(0, 3fr) minmax(0, 2fr) minmax(0, 2fr)" in css # 도면 · 일위대가 · 면적산출
|
||||
# 163-2 — 일위대가 · 면적산출 넓게(왼쪽) · 도면 좁게 맨 오른쪽(order 3)
|
||||
assert "minmax(0, 3fr) minmax(0, 3fr) minmax(0, 2fr)" in css
|
||||
assert ".b08-sheets .m02-struct > :first-child {\n order: 3;" in css
|
||||
assert ".b08-sheets__combo + .b08-sheets__combo" in css
|
||||
|
||||
@@ -11,8 +11,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 'labor: () => openEdit(copy, name, "inputs", load)' in call # 163-3 넣을 값만
|
||||
assert "editable: () => true" in call
|
||||
assert "const laborCard = opts.labor" in CARDS
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""163 B08 구조물도 모달 — 연결 칩 · 접기(163-1) · 사본 고침(163-3) · [업데이트](163-4) · 콘크리트소요 줄(163-5).
|
||||
|
||||
화면 글 판정 — 서버 · 짝 계산(Material_Calc)은 안 고침 · 고르기 모달 편집 화면은 재사용만.
|
||||
"""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
LINK = (ROOT / "B08_Quantity/B08_Quantity_UI_Link.ts").read_text(encoding="utf-8")
|
||||
DRAWING = (ROOT / "B08_Quantity/B08_Quantity_UI_Drawing.ts").read_text(encoding="utf-8")
|
||||
CSS = (ROOT / "B08_Quantity/B08_Quantity_UI_Drawing.css").read_text(encoding="utf-8")
|
||||
MATERIAL = (ROOT / "B08_Quantity/B08_Quantity_UI_Material.ts").read_text(encoding="utf-8")
|
||||
LOCALE = (ROOT / "ui_template/ui_template_locale_b4.ts").read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_163_1_칩_한_줄_공용_접기():
|
||||
assert 'line.className = "b08-link__row"' in LINK # 시설마다 한 줄
|
||||
assert '"b08-link__chip"' in LINK and "chip.dataset.b08LinkSlot = slot.copy" in LINK
|
||||
# 모두 연결이면 접힘 · 미연결 있으면 펼침
|
||||
assert 'ui-collapsible${missing ? "" : " is-collapsed"}' in LINK
|
||||
assert "ui-collapsible__title" in LINK and "attachCollapsible(section)" in LINK
|
||||
assert "state.title = state.textContent" in LINK # 긴 이름 = 툴팁
|
||||
assert re.search(r"\.b08-link__row \{[^}]*flex-wrap: wrap", CSS)
|
||||
assert ".b08-link__slot" not in CSS + LINK # 옛 줄 꼴 없음
|
||||
|
||||
|
||||
def test_163_3_수정_사본_편집_화면():
|
||||
assert "editable: () => true" in DRAWING
|
||||
assert "onEdit: (kind) => openEdit(copy, name, kind, load)" in DRAWING
|
||||
assert 'labor: () => openEdit(copy, name, "inputs", load)' in DRAWING
|
||||
assert 'import("@ui/ui_template_item_picker_edit")' in DRAWING
|
||||
assert "createEditView(" in DRAWING and "items: projectItems(request.projectId)" in DRAWING
|
||||
assert "info: { 폴더: copy.폴더, 원본: copy.항목 }" in DRAWING
|
||||
# [뒤로] = 몸통 되돌림 · 저장했으면 카드 다시 읽음 · 닫을 때 집계표 다시 셈
|
||||
assert "body.replaceChildren(...kept)" in DRAWING and "if (saved) reload()" in DRAWING
|
||||
assert "if (edited) request.onLinked()" in DRAWING
|
||||
assert "if (editView && !(await editView.leave())) return false" in DRAWING
|
||||
assert 'kind === "inputs" ? [note(L("B08_Quantity_Sheets_InputsOnly"))]' in DRAWING
|
||||
assert "saveTemplate" not in DRAWING # 층 쓰기 없음 — 사본 PUT 만(편집 화면 `items.write`)
|
||||
|
||||
|
||||
def test_163_4_배지_업데이트():
|
||||
assert ".list(folder)" in LINK and "structureFolder(slot.copy)" in LINK
|
||||
for key in ("Edited", "Gone", "Changed"):
|
||||
assert f'badge("B08_Quantity_Link_{key}"' in LINK, key
|
||||
assert "button.disabled = !info.마스터바뀜 || !!info.원본없음" in LINK
|
||||
assert "updateButton.disabled = true" in LINK # 대조 받기 전 꺼짐
|
||||
assert "projectItems(projectId).reapply(info)" in LINK
|
||||
assert 'showConfirmDialog(ask, L("B08_Quantity_Link_Update"))' in LINK
|
||||
assert 'info.고침 ? ` ${L("B08_Quantity_Link_UpdateEdited")}`' in LINK
|
||||
# 저장 뒤 = [선택]과 같은 흐름(onLinked)
|
||||
assert "saved\n ? onLinked()" in LINK
|
||||
|
||||
|
||||
def test_163_5_콘크리트_5줄_늘_까닭():
|
||||
table = MATERIAL[
|
||||
MATERIAL.index("function concreteTable") : MATERIAL.index("function totalTable")
|
||||
]
|
||||
assert "const keep = rows.map((_row, i) => i)" in table
|
||||
assert 'editable: (_i, key) => key.startsWith("per:")' in table # 배합 늘 고침
|
||||
assert "function concreteWhy(" in MATERIAL
|
||||
assert "matched(m.name, m.spec, m.unit)" in MATERIAL # 짝 계산 맞춤 그대로
|
||||
assert "source.snapshot?.units?.[row.id]" in MATERIAL
|
||||
assert "concreteNote.textContent = concreteWhy(sheets, payload.source)" in MATERIAL
|
||||
assert "Material_Calc" in MATERIAL and "concreteWhy" not in (
|
||||
ROOT / "B08_Quantity/B08_Quantity_Material_Calc.ts"
|
||||
).read_text(encoding="utf-8")
|
||||
|
||||
|
||||
def test_locale_keys_exist():
|
||||
for text in (LINK, DRAWING):
|
||||
for key in set(re.findall(r'L\("([A-Za-z0-9_]+)"\)', text)) | set(
|
||||
re.findall(r'badge\("([A-Za-z0-9_]+)"', text)
|
||||
):
|
||||
assert f"{key}:" in LOCALE or key.startswith(("B08_Quantity_Summary_", "Common_")), key
|
||||
@@ -25,11 +25,11 @@ def test_modal_own_class_and_cleanup():
|
||||
assert 'dialogClass: "b08-sheets"' in DRAWING
|
||||
|
||||
|
||||
def test_read_only():
|
||||
# 쓰는 길이 없음 — 저장 · 고침 · PUT/POST 없음 · 카드는 고칠 수 없음
|
||||
def test_no_layer_write():
|
||||
# 층 쓰기 · 카드 안 저장 없음 — 고침은 [수정] → 사본 편집 화면만(163-3 · 사본 PUT)
|
||||
for word in ("saveTemplate", "write:", "method:", "sheetEdit", "onImport", "onClear"):
|
||||
assert word not in DRAWING, word
|
||||
assert "editable: () => false" in DRAWING
|
||||
assert "editable: () => true" in DRAWING
|
||||
|
||||
|
||||
def test_copy_only():
|
||||
|
||||
Reference in New Issue
Block a user