feat(B08): 구조물 집계표를 공용 많은 자료 표로(70-2)

- 집계표 = createDataTable — 머리 두 줄(조합 구분 · 이름) · 측점 열 고정 · 칸은 빈칸 · 빠진 조합 빨강 · 풍선 글 그대로
- 공용 표 하위 호환 옵션 — empty(빈 값 글) · 열 title · className · 빠진 항목 머리 색 · 틀 폭은 표만큼

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
This commit is contained in:
2026-10-06 23:15:42 +09:00
co-authored by Claude Opus 5.5
parent 184d79cbdf
commit 53d839cb1d
6 changed files with 82 additions and 55 deletions
@@ -73,6 +73,15 @@ console.log(
.filter(Boolean);
return { n: b.length, top: b[0], second: b[1].slice(0, 20), bottom: b[b.length - 1] };
})(),
opts: m.renderDataTableHtml({
columns: [
{ key: "sta", label: "측점" },
{ key: "c1", label: "메쌓기", group: ["기슭막이"], title: "풍선", className: "is-missing" },
],
rows: [{ sta: "0+0" }],
frozen: 1,
empty: "",
}),
escaped: m.renderDataTableHtml({ columns: [{ key: "x", label: "<b>" }], rows: [{ x: "a&<" }] }),
noTotal: m.renderDataTableHtml({ columns: [tc], rows: [] }).includes("<tfoot>"),
}),
@@ -70,3 +70,11 @@ def test_빈_목록():
" summaryColumns([{ chainage_m: 5 }], () => null), groupSpans([])]));"
)
assert out == [[], [], []]
def test_집계표는_공용_표():
# PLAN 70-2 — 공용 많은 자료 표 · 측점 열 고정 · 칸은 빈칸(「—」 아님)
ui = (ROOT / "B08_Quantity" / "B08_Quantity_UI_Summary.ts").read_text(encoding="utf-8")
assert "createDataTable(" in ui and "@ui/ui_template_data_table" in ui
assert "frozen: 1" in ui and 'empty: ""' in ui
assert 'document.createElement("table")' not in ui
+7
View File
@@ -85,3 +85,10 @@ def test_보이는_줄만_그림(r):
'<tr class="is-alt">'
) # 61 번째(홀수) 줄 — 번갈아 색은 전체 줄 번호로
assert 'style="height:21975px"' in w["bottom"] # (1000 - 121) × 25
def test_빈_칸_글_풍선_꾸밈_옵션(r):
o = r["opts"]
assert '<td class="is-empty"></td>' in o # empty="" — 「—」 대신 빈칸
assert '<th scope="col" rowspan="1" class="is-missing" title="풍선">메쌓기</th>' in o
assert 'rowspan="2" class="is-frozen is-edge" style="left:0px" title="측점">측점</th>' in o