feat(M02): 면적 값 고침이 저장 전 도면 패널 표에 바로 비침 · 이름 · 보내기 취소는 [저장] 때 서버가 기록(112-1·112-2)

- 112-1 면적 표 변환을 공용 파일(spreadsheet_area_table.ts)로 빼 서버 Node 와 브라우저가 한 벌로 씀 · 도면 패널이 칸 고침마다(값 바뀐 표만 · 펼친 동안만) CAD 연결 표 갈기를 보기 전용 갈음(preview)으로 보냄
- 112-2 보낸 범위 이름은 도면 [저장] 요청 안에서 서버가 면적 문서에 둠(놓기만 하고 저장 안 하면 안 생김) · [보내기 취소]는 화면에서만 빼고 면적 [저장] 때 서버가 연결표 줄 · 이름을 뺌 · /name · /unlink 길 삭제

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MgChuAcyBqUkhHMTXomQC7
This commit is contained in:
2026-10-08 17:36:44 +09:00
co-authored by Claude Sonnet 5.5
parent 2a830980c7
commit 5638bd5101
17 changed files with 797 additions and 322 deletions
@@ -4,7 +4,8 @@
* · 「일위대가」 = 그 열 일위대가의 담은 로직 + 자재목록(기준 · 반영) · 몸 = 일위대가 보기 갈래(`Labor_View`)
* · 「도면」 = 그 열 구조물 도면 보기 · 고르기(`AreaDrawing` · 처음 펼 때 그림) · [면적산출로 보내기] = 새 시트(83-3)
* · 줄 누름 = 칸 지정 모달(`AreaLink` · 그 줄 알약 키를 면적 칸에 잇기 · 풀기)
* · 시트 칸 값 · 연결이 바뀌면 `refresh` — 받은 기준에 바로 곱함 · 칸 주소도 넘김(서버 안 부름 · `Labor_View.setQty`)
* · 시트 칸 값 · 연결이 바뀌면 `refresh` — 받은 기준에 바로 곱함 · 칸 주소도 넘김(서버 안 부름 · `Labor_View.setQty`) ·
* 도면 패널의 연결 표 값도 저장 전에 바로 따라 바뀜(112-1 · `AreaDrawing.sync`)
* ========================================================================== */
import { showToast } from "@ui/ui_template_elements";
@@ -36,6 +37,8 @@ export interface AreaPanelOptions {
/** 알약 막대 항목 — 칸 지정 때 연결에 같이 적을 이름 · 단위 · 자재 */
pills: () => LinkItem[];
readOnly: boolean;
/** 면적 화면에서 [보내기 취소]한 연결(저장 전) — 도면 패널 실시간 갈기에서 뺌 */
cancelled?: () => ReadonlySet<string>;
}
export interface AreaPanel {
@@ -99,6 +102,7 @@ export function buildAreaPanel(opts: AreaPanelOptions): AreaPanel {
// 도면 → 면적 새 시트(83-3 · 한 번 · 연동 아님) — 고칠 수 없는 면적이면 보내기 단추 없음
const drawing = createAreaDrawing(opts.layer, opts.column, {
onTable: opts.readOnly ? undefined : (table) => void importDrawingTable(opts.sheet(), table),
cancelled: opts.cancelled,
});
const panels = createSidePanels({
prefKey: "m02-area-panels",
@@ -108,13 +112,16 @@ export function buildAreaPanel(opts: AreaPanelOptions): AreaPanel {
{ id: "labor", title: TEXT.labor, body: view.root },
{ id: "drawing", title: TEXT.drawing, body: drawing.root },
],
onChange: (open) => open === "drawing" && drawing.show(),
onChange: (open) => (open === "drawing" ? drawing.show() : drawing.hide()),
});
if (panels.current() === "drawing") drawing.show();
const root = panels.root;
// 처음 = 저장 안 한 시트 칸 값으로 셈(서버 calc 한 번)
const refresh = (): void => view.setQty(quantities(opts.sheet()), cellsOf(opts.sheet()));
const refresh = (): void => {
view.setQty(quantities(opts.sheet()), cellsOf(opts.sheet()));
drawing.sync(() => opts.sheet()?.getDoc()); // 저장 전 칸 값 → 도면 패널 표(112-1)
};
void view.show(opts.layer, opts.column, quantities(opts.sheet()));
refresh(); // 칸 주소는 지금 시트 것 — 보기가 저장본 대신 씀
return {