Files
Aislo/old_code/B09_Estimation/B09_Estimation_UI_Tab_BasisSheet.ts
T
eomsangdonandClaude Opus 5 8472fc9f40 refactor(B08,B09): 폴더째 old_code 로 옮기고 빈 화면 둘만 남김 (PLAN 7-3)
B08_Quantity 86 · B09_Estimation 111 파일을 old_code/ 로 옮김(지우지 않음).
화면은 메뉴·주소·단계 막대만 남은 빈 틀 둘 — main.py 라우터 13 개는 끊음.
B07 이 빌려 쓰던 비탈 길이·면적은 필요한 함수만 B07_DesignDetail_Engine_SlopeGeometry
로 옮겨 적음(면적 적분·노면 면적·측점 묶음은 안 옮김) · 시험 하나를 새로 둠.
B07 구조물도 조립(Cad_StandardSheet)은 2026-09-13 에 이미 도면 목록에서 빠져
부르는 곳이 없어 old_code 로 같이 보냄 — 구조물 그림은 되살리지 않음.
B06 구조물 몫 조회는 빈 값으로 두어 화면이 그대로 서게 함.
B08·B09 를 부르던 시험 25 개도 old_code/resources/tester 로 옮김.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PAdA5ThqmtVSsbzjusk1cJ
2026-09-22 12:27:45 +09:00

121 lines
4.1 KiB
TypeScript

/* =============================================================================
* 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));
});
},
};