refactor(b09): 옛 탭 옮기기 ② 산출기초 — 새 틀 탭 파일로
- 화면 확인: 옮기기 전후 같음 — 표 3 · 줄 192 · 판 12 · 근거 공종 92 · 못 채운 자리 88 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
This commit is contained in:
@@ -24,6 +24,7 @@ import { priceCompareTab } from "./B09_Estimation_UI_Tab_PriceCompare";
|
||||
import { summaryTab } from "./B09_Estimation_UI_Tab_Summary";
|
||||
import { listsTab } from "./B09_Estimation_UI_Tab_Lists";
|
||||
import { designDocTab } from "./B09_Estimation_UI_Tab_DesignDoc";
|
||||
import { basisSheetTab } from "./B09_Estimation_UI_Tab_BasisSheet";
|
||||
|
||||
/** 탭 등록 — 한 줄에 탭 하나. 옛 탭(`legacyTab`)은 새 탭 파일이 서면 그 줄만 바꿈. */
|
||||
const TABS: B09Tab[] = [
|
||||
@@ -39,7 +40,7 @@ const TABS: B09Tab[] = [
|
||||
legacyTab("supply", "B09_Estimation_Tab_Supply"),
|
||||
legacyTab("base_data", "B09_Estimation_Tab_BaseData"),
|
||||
designDocTab,
|
||||
legacyTab("basis_sheet", "B09_Estimation_Tab_BasisSheet"),
|
||||
basisSheetTab,
|
||||
];
|
||||
|
||||
export async function renderB09Estimation(root: HTMLElement): Promise<void> {
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/* =============================================================================
|
||||
* B09_Estimation_UI_Tab_BasisSheet.ts
|
||||
* B09 산출기초 탭 — 줄에 달린 근거를 한 장으로 모은 장(별표2 (5)(가) 열셋째)
|
||||
*
|
||||
* - 옛 `B09_Estimation_UI_BaseData.ts` 의 산출기초를 그대로 옮김(PLAN 12장 옛 탭 옮기기).
|
||||
* - ⚠ 여기서 값을 다시 계산하지 않음 — 모으기만 함. 네 구획: 판 · 고른 값 · 공종별 근거 · 못 채운 자리.
|
||||
* ========================================================================== */
|
||||
|
||||
import { API_BASE_URL } from "@config/config_frontend";
|
||||
import type { ProvenancePayload } from "@ui/ui_template_provenance";
|
||||
import type { B09Tab } from "./B09_Estimation_UI_Shell_Types";
|
||||
import { L, hint } from "./B09_Estimation_UI_Sheet";
|
||||
import { head, infoTable, note } from "./B09_Estimation_UI_Table";
|
||||
|
||||
interface BasisSheetDto {
|
||||
provenance?: ProvenancePayload;
|
||||
note: string;
|
||||
summary: string;
|
||||
dataset_versions: Array<{
|
||||
dataset_id: string;
|
||||
file: string;
|
||||
effective_date: string;
|
||||
sha256: string;
|
||||
}>;
|
||||
chosen_conditions: Array<{ item: string; value: string }>;
|
||||
work_items: Array<{ code: string; name: string; unit: string; notes: string[] }>;
|
||||
gaps: Array<{ kind: string; code: string; reason: string }>;
|
||||
}
|
||||
|
||||
function draw(body: HTMLElement, data: BasisSheetDto): void {
|
||||
const sheets = data.provenance?.sheets;
|
||||
body.append(head("산출기초"));
|
||||
body.append(note(data.summary));
|
||||
body.append(note(data.note));
|
||||
|
||||
body.append(head(`① 어느 판으로 계산했나 (${data.dataset_versions.length})`));
|
||||
body.append(
|
||||
infoTable(
|
||||
["자료", "파일", "기준일", "지문(앞 12)"],
|
||||
data.dataset_versions.map((row) => [
|
||||
row.dataset_id,
|
||||
row.file,
|
||||
row.effective_date,
|
||||
row.sha256 || "—",
|
||||
]),
|
||||
[0, 1, 2, 3],
|
||||
["dataset_id", "file", "effective_date", "sha256"],
|
||||
sheets?.basis_versions,
|
||||
),
|
||||
);
|
||||
|
||||
body.append(head(`② 무엇을 골랐나 (${data.chosen_conditions.length})`));
|
||||
if (data.chosen_conditions.length === 0) {
|
||||
body.append(note("고른 값이 없습니다 — 전부 확정 기본값으로 돌고 있습니다."));
|
||||
} else {
|
||||
body.append(
|
||||
infoTable(
|
||||
["항 목", "고른 값"],
|
||||
data.chosen_conditions.map((row) => [row.item, row.value]),
|
||||
[0, 1],
|
||||
["item", "value"],
|
||||
sheets?.basis_chosen,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
body.append(head(`③ 공종마다 무엇을 근거로 했나 (${data.work_items.length})`));
|
||||
body.append(
|
||||
infoTable(
|
||||
["코드", "공 종", "단위", "근 거"],
|
||||
data.work_items.map((row) => [row.code, row.name, row.unit, row.notes.join(" · ")]),
|
||||
[0, 1, 2, 3],
|
||||
["code", "name", "unit", "notes"],
|
||||
sheets?.basis_items,
|
||||
),
|
||||
);
|
||||
|
||||
body.append(head(`④ 못 채운 자리 (${data.gaps.length})`));
|
||||
if (data.gaps.length === 0) {
|
||||
body.append(note("못 채운 자리가 없습니다."));
|
||||
return;
|
||||
}
|
||||
body.append(
|
||||
infoTable(
|
||||
["갈 래", "코드", "사 유"],
|
||||
data.gaps.map((row) => [row.kind, row.code, row.reason]),
|
||||
[0, 1, 2],
|
||||
["kind", "code", "reason"],
|
||||
sheets?.basis_gaps,
|
||||
),
|
||||
);
|
||||
body.append(note("⚠ 여기 있는 것은 0 으로 때우지 않고 남겨 둔 자리입니다."));
|
||||
}
|
||||
|
||||
export const basisSheetTab: B09Tab = {
|
||||
key: "basis_sheet",
|
||||
label: () => L("B09_Estimation_Tab_BasisSheet"),
|
||||
render(ctx) {
|
||||
if (!ctx.projectId) {
|
||||
ctx.body.append(hint(L("B09_Sheet_NoProject")));
|
||||
return;
|
||||
}
|
||||
// 고른 값이 바뀌면 근거도 바뀜 — 고를 때마다 새로 받음.
|
||||
ctx.body.append(hint(L("B09_Sheet_Loading")));
|
||||
fetch(`${API_BASE_URL}/projects/${encodeURIComponent(ctx.projectId)}/estimation/basis-sheet`, {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((response) => {
|
||||
if (!response.ok) throw new Error(String(response.status));
|
||||
return response.json() as Promise<BasisSheetDto>;
|
||||
})
|
||||
.then((data) => {
|
||||
ctx.body.replaceChildren();
|
||||
draw(ctx.body, data);
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
ctx.body.replaceChildren(hint(`${L("B09_Sheet_LoadFailed")} ${error.message}`, true));
|
||||
});
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user