Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015KYZ2HWWdUwZWYnn3tQz7X
127 lines
5.0 KiB
TypeScript
127 lines
5.0 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_AreaDrawing.ts
|
|
* 면적산출 상세 오른쪽 「도면」 패널 몸(PLAN 47-6) — 그 열 구조물 도면을 보기 · 고르기(고치기 없음).
|
|
* 처음 펼 때 읽고 그림 — 접힌 채 iframe 을 띄우지 않음.
|
|
* 83-3 — 머리 [면적산출로 보내기] = CAD 에 고른 범위 요청(`aislo:b08:export-table-request`) → 받은 표 자료
|
|
* (`aislo:b08:export-table` · CAD `integration/aislo-table-export.ts`)를 `onTable` 로(새 시트 만들기는 부른 쪽).
|
|
* CAD 명령 TOAREA 로 보낸 것도 같은 길. 고칠 수 없는 면적(읽기 층)이면 단추 없음.
|
|
* ========================================================================== */
|
|
|
|
import { createButton, el } from "@ui/ui_template_elements";
|
|
import { readTemplate, type Layer, type StructureDoc } from "./M02_MasterTemplete_Api_Fetch";
|
|
import { mountDrawingTemplate, type DrawingTemplateDoc } from "./M02_MasterTemplete_Drawing";
|
|
import type { DrawingTable } from "./M02_MasterTemplete_AreaFromDrawing";
|
|
|
|
const TEXT = {
|
|
loading: "도면 불러오는 중…",
|
|
none: "이 열은 구조물 도면이 없음",
|
|
send: "면적산출로 보내기",
|
|
sendTip:
|
|
"도면에서 고른 범위(표 · 선으로 그린 표 · 글)를 면적산출 새 시트로 한 번 옮김 — 연동 아님 · 누름 · 끌기로 고름",
|
|
};
|
|
|
|
export const EXPORT_TABLE_REQUEST = "aislo:b08:export-table-request";
|
|
export const EXPORT_TABLE = "aislo:b08:export-table";
|
|
|
|
/** 고르기만 — 제목줄 · 리본 · 패널 · 상태줄 숨김(카드 고치기 갈래와 같은 숨김 · 명령 안내 줄은 남김) */
|
|
const HIDE =
|
|
".cad-titlebar, .cad-ribbon, .cad-inspector, .cad-statusbar, .cad-quick-access" +
|
|
" { display: none !important; }";
|
|
|
|
function hideChrome(frame: HTMLIFrameElement): void {
|
|
const apply = (): void => {
|
|
const inner = frame.contentDocument;
|
|
if (!inner?.head || inner.getElementById("m02-area-hide")) return;
|
|
const style = inner.createElement("style");
|
|
style.id = "m02-area-hide";
|
|
style.textContent = HIDE;
|
|
inner.head.append(style);
|
|
};
|
|
frame.addEventListener("load", apply);
|
|
apply();
|
|
}
|
|
|
|
export interface AreaDrawingOptions {
|
|
/** 받은 표 자료 — 없으면(읽기 층) 보내기 단추 없음 */
|
|
onTable?: (table: DrawingTable) => void;
|
|
}
|
|
|
|
export interface AreaDrawing {
|
|
root: HTMLElement;
|
|
/** 패널이 펼쳐짐 — 처음 한 번만 읽고 그림 */
|
|
show: () => void;
|
|
destroy: () => void;
|
|
}
|
|
|
|
export function createAreaDrawing(
|
|
layer: Layer,
|
|
column: string,
|
|
opts: AreaDrawingOptions = {},
|
|
): AreaDrawing {
|
|
const root = el("div", { className: "m02-apanel__drawing" });
|
|
const stage = el("div", { className: "m02-apanel__drawstage" });
|
|
let view: { destroy: () => void } | null = null;
|
|
let frame: HTMLIFrameElement | null = null;
|
|
let started = false;
|
|
let dead = false;
|
|
const note = (text: string): void =>
|
|
stage.replaceChildren(el("p", { className: "m02-apanel__note", text }));
|
|
|
|
const send = createButton({ label: TEXT.send, size: "sm", variant: "ghost" });
|
|
send.title = TEXT.sendTip;
|
|
send.dataset.areaFromDrawing = "";
|
|
send.disabled = true; // 도면이 서면 켬
|
|
send.addEventListener("click", () =>
|
|
frame?.contentWindow?.postMessage({ type: EXPORT_TABLE_REQUEST }, window.location.origin),
|
|
);
|
|
if (opts.onTable) root.append(el("div", { className: "m02-apanel__drawbar", children: [send] }));
|
|
root.append(stage);
|
|
|
|
const onMessage = (event: MessageEvent): void => {
|
|
if (!frame || event.source !== frame.contentWindow) return;
|
|
if (event.origin !== window.location.origin) return;
|
|
const data = event.data as { type?: string; table?: DrawingTable } | null;
|
|
if (data?.type === EXPORT_TABLE && data.table && opts.onTable) opts.onTable(data.table);
|
|
};
|
|
window.addEventListener("message", onMessage);
|
|
|
|
const show = (): void => {
|
|
if (started) return;
|
|
started = true;
|
|
note(TEXT.loading);
|
|
readTemplate(layer, "structure", column, null)
|
|
.then((got) => {
|
|
if (dead) return;
|
|
const doc = got.문서 as StructureDoc | null;
|
|
if (!doc?.도면) return note(TEXT.none);
|
|
stage.replaceChildren();
|
|
// 보기 전용 + 고르기(누름 · 끌기) — 미리보기(끌기 = 화면 옮기기)는 고르기가 꺼져 있어 안 씀
|
|
view = mountDrawingTemplate(stage, doc.도면 as unknown as DrawingTemplateDoc, {
|
|
readOnly: true,
|
|
name: `preview:${column}`,
|
|
layer,
|
|
panelsCollapsed: true,
|
|
originMarker: true,
|
|
noArea: true,
|
|
frame: true,
|
|
noImport: true,
|
|
});
|
|
frame = stage.querySelector("iframe");
|
|
if (frame) hideChrome(frame);
|
|
send.disabled = !frame;
|
|
})
|
|
.catch(() => !dead && note(TEXT.none));
|
|
};
|
|
|
|
return {
|
|
root,
|
|
show,
|
|
destroy: () => {
|
|
dead = true;
|
|
window.removeEventListener("message", onMessage);
|
|
view?.destroy();
|
|
root.remove();
|
|
},
|
|
};
|
|
}
|