Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0168FQuoV7vDh5nhnSowW5cp
93 lines
3.3 KiB
TypeScript
93 lines
3.3 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_Spreadsheet_Trial.ts
|
|
* ⚠ 임시 — [스프레드시트 시험] 단추(사용자 지시 · 스프레드시트 1단계 검증 뒤 지움:
|
|
* 이 파일 · `M02_MasterTemplete_UI_Main.ts` 의 시험 단추 · Api_Fetch `*SpreadsheetTrial` ·
|
|
* Router `/spreadsheet-trial` · 저장 자리 `tmp/spreadsheet_trial.json`).
|
|
* 빈 통합문서(시트 셋)를 메인 칸에 넓게 엶 · [시험 저장] = 서버가 같은 엔진으로 다시 풀어 tmp 에 적음.
|
|
* 글자는 이 파일에 둠.
|
|
* ========================================================================== */
|
|
|
|
import { createButton, el, showToast } from "@ui/ui_template_elements";
|
|
import type { SpreadsheetHandle, Workbook } from "../A00_Common/spreadsheet/spreadsheet";
|
|
import { readSpreadsheetTrial, saveSpreadsheetTrial } from "./M02_MasterTemplete_Api_Fetch";
|
|
import "./M02_MasterTemplete_Spreadsheet_Trial.css";
|
|
|
|
const TEXT = {
|
|
save: "시험 저장",
|
|
note: "임시 시험 화면 — 저장은 서버 tmp 견본 자리(작업 양식과 무관)",
|
|
saved: "시험 통합문서를 저장했음(서버 재계산)",
|
|
failed: "스프레드시트 시험 실패 — {value}",
|
|
};
|
|
|
|
const why = (error: unknown): string => (error instanceof Error ? error.message : String(error));
|
|
|
|
export interface TrialHandle {
|
|
getDoc: () => unknown;
|
|
destroy: () => void;
|
|
}
|
|
|
|
/** `onDirty` = 고침 있음 · 저장 뒤 없음(페이지의 떠날 때 물음과 이음) */
|
|
export function mountSpreadsheetTrial(
|
|
host: HTMLElement,
|
|
onDirty: (dirty: boolean) => void,
|
|
): TrialHandle {
|
|
let sheet: SpreadsheetHandle | null = null;
|
|
let alive = true;
|
|
const save = createButton({ label: TEXT.save, variant: "filled" });
|
|
const area = el("div", { className: "m02-trial__sheet" });
|
|
const root = el("div", {
|
|
className: "m02-trial",
|
|
children: [
|
|
el("div", {
|
|
className: "m02-trial__bar",
|
|
children: [el("span", { className: "m02-trial__note", text: TEXT.note }), save],
|
|
}),
|
|
area,
|
|
],
|
|
});
|
|
host.replaceChildren(root);
|
|
const fail = (error: unknown): void =>
|
|
showToast(TEXT.failed.replace("{value}", why(error)), "error");
|
|
|
|
void (async () => {
|
|
try {
|
|
const [{ createSpreadsheet }, got] = await Promise.all([
|
|
import("../A00_Common/spreadsheet/spreadsheet"),
|
|
readSpreadsheetTrial(),
|
|
]);
|
|
if (!alive) return;
|
|
sheet = createSpreadsheet(area, got.문서 as Workbook, {
|
|
onChange: () => onDirty(true),
|
|
inspect: true, // ⚠ 임시 — 브레인 검증용 문맥(window.__aisloSheet) · 산출근거 카드는 안 넘김
|
|
});
|
|
} catch (error) {
|
|
if (!alive) return;
|
|
area.replaceChildren(el("p", { className: "m02-trial__empty", text: why(error) }));
|
|
fail(error);
|
|
}
|
|
})();
|
|
|
|
save.addEventListener("click", async () => {
|
|
if (!sheet) return;
|
|
save.disabled = true;
|
|
try {
|
|
await saveSpreadsheetTrial(sheet.getDoc());
|
|
onDirty(false);
|
|
showToast(TEXT.saved, "success");
|
|
} catch (error) {
|
|
fail(error);
|
|
} finally {
|
|
save.disabled = false;
|
|
}
|
|
});
|
|
|
|
return {
|
|
getDoc: () => sheet?.getDoc() ?? null,
|
|
destroy: () => {
|
|
alive = false;
|
|
sheet?.destroy();
|
|
root.remove();
|
|
},
|
|
};
|
|
}
|