diff --git a/ui_template/ui_template_provenance.ts b/ui_template/ui_template_provenance.ts index be53625e..396023ee 100644 --- a/ui_template/ui_template_provenance.ts +++ b/ui_template/ui_template_provenance.ts @@ -52,7 +52,14 @@ const TINT_KEY = "aislo.provenance.tint"; const STYLE_ID = "ui-provenance-style"; const CARD_ID = "ui-provenance-card"; -/** 칸에 심는 표시 — 열 키와 등급. 표를 그리는 쪽이 칸마다 한 번 부른다. */ +/** + * 칸에 심는 표시 — 열 키와 등급. 표를 그리는 쪽이 칸마다 한 번 부른다. + * + * `tier` 를 주면 **그 칸만 열 등급을 이긴다.** 같은 열이라도 줄마다 성격이 갈리는 + * 자리가 있기 때문이다 — 원가계산서 「금액」은 중간줄(간접노무비 따위)이 `calc` 인데 + * 마지막줄(총원가·도급금액·총계)은 `final` 이다(2026-09-12 데스크탑 보조 B09 배선). + * 칸 등급을 심지 않으면 열 등급이 그대로 선다. + */ export function markProvenanceCell(cell: HTMLElement, columnKey: string, tier?: string): void { cell.dataset.provCol = columnKey; if (tier) cell.dataset.provTier = tier; @@ -137,7 +144,15 @@ function place(element: HTMLElement, x: number, y: number): void { } /** 카드 한 장을 채운다. 값은 **화면에 적힌 글자 그대로** 보인다 — 자리수까지 같은 것이 요점. */ -function fill(target: HTMLElement, column: ProvenanceColumn, value: string, extra: string[]): void { +/** 카드 한 장을 채운다. 배지는 **칸 등급**을 먼저 본다 — 띄는 띄었는데 배지가 다른 말을 + * 하면 읽는 사람이 둘 중 어느 것을 믿을지 모른다. */ +function fill( + target: HTMLElement, + cell: HTMLElement, + column: ProvenanceColumn, + value: string, + extra: string[], +): void { target.replaceChildren(); const head = document.createElement("div"); head.className = "ui-prov-card__head"; @@ -145,8 +160,9 @@ function fill(target: HTMLElement, column: ProvenanceColumn, value: string, extr title.textContent = column.label; const badge = document.createElement("span"); badge.className = "ui-prov-card__badge"; - badge.dataset.provTier = column.tier; - badge.textContent = TIER_LABELS[column.tier] ?? column.tier; + const tier = cell.dataset.provTier || column.tier; + badge.dataset.provTier = tier; + badge.textContent = TIER_LABELS[tier] ?? tier; head.append(title, badge); target.append(head); @@ -171,6 +187,14 @@ export function attachProvenance( ): void { if (!sheet) return; injectProvenanceStyles(); + // 등급을 안 심은 칸은 **여기서 열 등급으로 채운다.** + // 색칠은 CSS 가 `data-prov-tier` 를 보고 하므로, 그 칸은 배지만 띄고 띄는 안 붙어 + // 「색이 안 붙는 칸」이 생긴다. 부르는 쪽이 등급을 빼먹는 것은 흔한 일이라 여기서 맞춘다. + for (const cell of root.querySelectorAll("[data-prov-col]")) { + if (cell.dataset.provTier) continue; + const tier = sheet.columns[cell.dataset.provCol ?? ""]?.tier; + if (tier) cell.dataset.provTier = tier; + } const hide = (): void => { const element = document.getElementById(CARD_ID); if (element) element.style.display = "none"; @@ -183,6 +207,7 @@ export function attachProvenance( const target = card(); fill( target, + cell, column, cell.textContent?.trim() ?? "", resolveExtra?.(cell, cell.dataset.provCol ?? "") ?? [],