- 화면 확인: 설계서 구성 13줄 · 요약·법 문구 그대로 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016VBGFXB9AbJBwXP19z75Qq
83 lines
2.6 KiB
TypeScript
83 lines
2.6 KiB
TypeScript
/* =============================================================================
|
|
* B09_Estimation_UI_Tab_DesignDoc.ts
|
|
* B09 설계서 구성 탭 — 법이 정한 목차와 우리가 내는 것을 맞대 봄(별표2 (5)(가))
|
|
*
|
|
* - 옛 `B09_Estimation_UI_BaseData.ts` 의 설계서 구성표를 그대로 옮김(PLAN 12장 옛 탭 옮기기).
|
|
* - ⚠ 「없음」과 「우리 몫 아님」을 갈라 보임 — 갈라야 다음에 할 일이 달라짐.
|
|
* ========================================================================== */
|
|
|
|
import { API_BASE_URL } from "@config/config_frontend";
|
|
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 DesignDocDto {
|
|
law: string;
|
|
summary: string;
|
|
items: Array<{
|
|
order: number;
|
|
name: string;
|
|
status: string;
|
|
owner: string;
|
|
where: string;
|
|
note: string;
|
|
}>;
|
|
notes: string[];
|
|
}
|
|
|
|
let cached: DesignDocDto | null = null;
|
|
|
|
function draw(body: HTMLElement, data: DesignDocDto): void {
|
|
body.append(head(`설계서 구성 (법이 정한 ${data.items.length})`));
|
|
body.append(note(data.summary));
|
|
body.append(note(data.law));
|
|
body.append(
|
|
infoTable(
|
|
["차례", "이 름", "상 태", "누가 만드나", "어디서 나오나", "비 고"],
|
|
data.items.map((row) => [
|
|
String(row.order),
|
|
row.name,
|
|
row.status,
|
|
row.owner,
|
|
row.where || "—",
|
|
row.note,
|
|
]),
|
|
[0, 1, 2, 3, 4, 5],
|
|
),
|
|
);
|
|
for (const line of data.notes) body.append(note(line));
|
|
}
|
|
|
|
export const designDocTab: B09Tab = {
|
|
key: "design_doc",
|
|
label: () => L("B09_Estimation_Tab_DesignDoc"),
|
|
render(ctx) {
|
|
if (!ctx.projectId) {
|
|
ctx.body.append(hint(L("B09_Sheet_NoProject")));
|
|
return;
|
|
}
|
|
// 프로젝트 값이 아니라 **우리가 무엇을 내는가**의 표 — 한 번 받으면 그대로 씀.
|
|
if (cached) {
|
|
draw(ctx.body, cached);
|
|
return;
|
|
}
|
|
ctx.body.append(hint(L("B09_Sheet_Loading")));
|
|
fetch(
|
|
`${API_BASE_URL}/projects/${encodeURIComponent(ctx.projectId)}/estimation/design-doc-index`,
|
|
{ credentials: "include" },
|
|
)
|
|
.then((response) => {
|
|
if (!response.ok) throw new Error(String(response.status));
|
|
return response.json() as Promise<DesignDocDto>;
|
|
})
|
|
.then((data) => {
|
|
cached = data;
|
|
ctx.body.replaceChildren();
|
|
draw(ctx.body, data);
|
|
})
|
|
.catch((error: Error) => {
|
|
ctx.body.replaceChildren(hint(`${L("B09_Sheet_LoadFailed")} ${error.message}`, true));
|
|
});
|
|
},
|
|
};
|