From 0a3bab12238f55d1fd488dfc68eb6991c865d62c Mon Sep 17 00:00:00 2001 From: umsangdon Date: Mon, 26 Oct 2026 22:02:54 +0900 Subject: [PATCH] =?UTF-8?q?refactor(D04):=20=EC=97=85=EC=B2=B4=20=ED=91=9C?= =?UTF-8?q?=EB=A5=BC=20=ED=91=9C=20=EB=B6=80=ED=92=88=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?(PLAN=20553-4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 5.5 --- D04_PlanConfirm/D04_PlanConfirm_UI_Page.ts | 59 ++++++++++---------- D04_PlanConfirm/D04_PlanConfirm_UI_Style.css | 23 -------- resources/tester/test_553_4_de_parts.py | 2 + 3 files changed, 31 insertions(+), 53 deletions(-) diff --git a/D04_PlanConfirm/D04_PlanConfirm_UI_Page.ts b/D04_PlanConfirm/D04_PlanConfirm_UI_Page.ts index aa595d520..654cc0f3b 100644 --- a/D04_PlanConfirm/D04_PlanConfirm_UI_Page.ts +++ b/D04_PlanConfirm/D04_PlanConfirm_UI_Page.ts @@ -25,6 +25,7 @@ import { import { createBanner } from "@ui/ui_template_banner"; import { createCheckbox } from "@ui/ui_template_checkbox"; import { createPanelCard } from "@ui/ui_template_collapsible"; +import { tableRow, tableShell, type Column } from "@ui/ui_template_table"; import { t } from "@ui/ui_template_locale"; import { stationLabel } from "../common_util/common_util_station"; import { clearState, readState, writeState } from "../A00_Common/b_page_state"; @@ -212,42 +213,40 @@ export async function renderD04PlanConfirm(root: HTMLElement): Promise { function draw(): void { const list = current(); - const head = el("tr", { - children: [ - "D04_Col_Year", - "D04_Col_Length", - "D04_Col_Start", - "D04_Col_End", - "D04_Col_Chainage", - "D04_Col_Confirmed", - "D04_Col_Assignees", - ].map((key) => el("th", { text: t(key as Parameters[0]) })), - }); - const rows = summary.years.map((row) => { + const columns: Column[] = [ + "D04_Col_Year", + "D04_Col_Length", + "D04_Col_Start", + "D04_Col_End", + "D04_Col_Chainage", + "D04_Col_Confirmed", + "D04_Col_Assignees", + ].map((key, i) => ({ + label: t(key as Parameters[0]), + ...(i === 1 ? { align: "end" as const } : {}), + })); + const { root: tableRoot, tbody } = tableShell(columns); + tableRoot.querySelector("table")?.classList.add("d04-confirm__table"); + for (const row of summary.years) { const firms = list.filter((item) => item.year === row.year).map(firmChip); const chain = row.saved ? `${station(row.start_chainage_m)} ~ ${station(row.end_chainage_m)}` : t("D04_NotSaved"); - return el("tr", { - attrs: { "data-year": String(row.year) }, - children: [ - el("td", { text: String(row.year) }), - el("td", { text: fmt(row.length_m), attrs: { "data-num": "" } }), - el("td", { text: where(row.start) }), - el("td", { text: where(row.end) }), - el("td", { text: chain }), - el("td", { text: kstText(row.confirmed_at) }), - el("td", { children: editable ? [...firms, addForm(row.year)] : firms }), - ], - }); - }); - const table = el("table", { - className: "d04-confirm__table", - children: [el("thead", { children: [head] }), el("tbody", { children: rows })], - }); + const tr = tableRow(columns, [ + String(row.year), + fmt(row.length_m), + where(row.start), + where(row.end), + chain, + kstText(row.confirmed_at), + el("div", { children: editable ? [...firms, addForm(row.year)] : firms }), + ]); + tr.dataset.year = String(row.year); + tbody.append(tr); + } const notes = draft() ? [createBanner({ tone: "warning", text: t("D04_Dirty") })] : []; notes[0]?.classList.add("d04-confirm__dirty"); - main.replaceChildren(el("h2", { text: summary.name }), ...notes, table); + main.replaceChildren(el("h2", { text: summary.name }), ...notes, tableRoot); pickList.replaceChildren( ...summary.years diff --git a/D04_PlanConfirm/D04_PlanConfirm_UI_Style.css b/D04_PlanConfirm/D04_PlanConfirm_UI_Style.css index 2260840d3..53c4fb41b 100644 --- a/D04_PlanConfirm/D04_PlanConfirm_UI_Style.css +++ b/D04_PlanConfirm/D04_PlanConfirm_UI_Style.css @@ -10,29 +10,6 @@ overflow: auto; } -.d04-confirm__table { - border-collapse: collapse; - font-size: var(--text-body-sm); - color: var(--color-text-body); -} - -.d04-confirm__table th, -.d04-confirm__table td { - padding: var(--spacing-8); - border: 1px solid var(--color-border); - text-align: left; - vertical-align: top; -} - -.d04-confirm__table thead th { - background: var(--color-surface); -} - -.d04-confirm__table td[data-num] { - text-align: right; - font-variant-numeric: tabular-nums; -} - .d04-confirm__firm, .d04-confirm__add { display: flex; diff --git a/resources/tester/test_553_4_de_parts.py b/resources/tester/test_553_4_de_parts.py index 9fc87bb68..f22a3a7e0 100644 --- a/resources/tester/test_553_4_de_parts.py +++ b/resources/tester/test_553_4_de_parts.py @@ -57,6 +57,8 @@ def test_d04_parts(): assert "input:checked" in ts # [확정] 이 고른 연도를 읽는 길 assert "border:" not in css.split(".d04-confirm__input")[1].split("}")[0] assert ".d04-confirm__dirty" not in css + assert 'el("table"' not in ts and "tableShell(columns)" in ts + assert "d04-confirm__table" not in css # 표 모양은 표 부품 · 이름은 촬영 장면용 걸이 def test_e01_missing_is_banner_part():