feat(504-3 계산 자리 45줄): 창 = 묶음 머리 8 + 계산 45 줄 · 이름 = 등록부 label · 켤 수 있는 줄 G1 · D3 만 · 머리 체크 = 묶음 전부 · 판 꼴 그대로

- B01_Dashboard_UI_CalcSites: 머리 줄 + 계산 줄(번호 · 이름) · 잠긴 줄 까닭 글 · 머리 · 줄 체크 서로 따라감
- 시험: test_309_2 두 파일 줄 수 · 켤 수 있는 줄 · 머리 따라 줄 꺼짐

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-21 16:06:17 +09:00
co-authored by Claude Sonnet 5.5
parent 026ca74c52
commit 3866025475
4 changed files with 88 additions and 25 deletions
@@ -258,3 +258,4 @@ def test_카드_시스템_관리자만_글_다_있음():
ui = _text("B01_Dashboard/B01_Dashboard_UI_CalcSites.ts")
assert 'check(group.fixed !== "browser", true)' in ui # 서버 정본 칸 = 늘 잠금
assert "saveCalcSites(changes)" in ui and "dirty()" in ui # 바뀐 줄만 PUT
assert "CALC_REGISTRY" in ui and "group.nos.map" in ui # 묶음 머리 아래 계산 줄(등록부 label)
@@ -121,12 +121,18 @@ def test_시스템_관리자_카드_창_G1_서버_길(browser):
dialog = page.wait_for_selector(".b01-dashboard__calc-sites", timeout=30000)
rows = page.eval_on_selector_all(
".b01-dashboard__calc-sites tbody tr",
"(trs) => trs.map((tr) => [...tr.querySelectorAll('input')]"
".map((i) => [i.checked, i.disabled]))",
"(trs) => trs.map((tr) => ({ head: tr.classList.contains('b01-dashboard__calc-group'),"
" name: tr.cells[0].textContent.trim(),"
" boxes: [...tr.querySelectorAll('input')].map((i) => [i.checked, i.disabled]) }))",
)
assert len(rows) == 8
assert rows[0] == [[True, False], [True, True]] # G1 바꿀 수 있음 · 서버 정본 잠금
assert all(row[0][1] and row[1][1] for row in rows[2:]) # 나머지 잠금
heads = [row for row in rows if row["head"]]
calcs = [row for row in rows if not row["head"]]
assert len(heads) == 8 and len(calcs) == 45
assert heads[0]["boxes"] == [[True, False], [True, True]] # G1 묶음 머리 = 바꿀 수 있음
editable = [row["name"] for row in calcs if not row["boxes"][0][1]]
assert [name.split(" · ")[0] for name in editable] == ["G1", "D3"] # 줄도 둘만 켬
assert all(row["name"].split(" · ")[1] for row in calcs) # 이름 = 등록부 label
assert all(row["boxes"][1][1] for row in calcs) # 서버 정본 칸은 늘 잠금
assert "지금 서버 0 줄" in dialog.inner_text()
SHOTS.mkdir(parents=True, exist_ok=True)
dialog.screenshot(path=str(SHOTS / "light.png"))
@@ -136,6 +142,7 @@ def test_시스템_관리자_카드_창_G1_서버_길(browser):
page.click("input[data-calc-site='ground_sample']")
assert "지금 서버 1 줄" in dialog.inner_text()
assert not page.is_checked("input[data-calc-no='G1']") # 머리 따라 줄도 꺼짐
page.locator(".b01-dashboard__calc-sites .ui-modal__actions button").click()
page.wait_for_selector(".b01-dashboard__calc-sites", state="detached", timeout=30000)
got = ctx.request.get(f"{BASE}/api/dashboard/calc-sites").json()["sites"]