feat(M02): 구조물집계표 열마다 설계 컨테이너 · 도면 줄 도번
- 집계표(시스템 층) 도면 줄에 `구-0N` 도번 — `fetchStructureNumbers` 를 `drawingLabel` 로 - 칸 고르기(`onSelect`)마다 표 밖 형제 자리에 컨테이너 — 열 머리·도번 · 도면 미리보기(읽기만) · [도면 수정] - [도면 수정] = 고침 확인 뒤 없으면 `createStructure` · 같은 페이지에서 그 구조물 도면 CAD 편집 · 좌측 고름 표시 - 구조물 도면 저장은 `도면` 칸만 갈아 끼움 — 도번 · 산출근거는 그대로 - 컨테이너 아래 상세 산출근거 표(공종 · 규격 · 산출 내역 · 단위 · 수량(m당)) · 줄 더하기 · 저장 - 새 시험 `test_m02_structure_panel.py` — 집계표 이름 대조 · 창끼리 이름 계약 · `columnHead` Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TamXZKonwSwyGT74XwwCbC
This commit is contained in:
@@ -14,7 +14,14 @@ import {
|
||||
StaleError,
|
||||
type Kind,
|
||||
type Layer,
|
||||
type StructureDoc,
|
||||
} from "./M02_MasterTemplete_Api_Fetch";
|
||||
import {
|
||||
createStructurePanel,
|
||||
STRUCTURE_TABLE,
|
||||
type StructureColumn,
|
||||
type StructurePanelHandle,
|
||||
} from "./M02_MasterTemplete_Structure";
|
||||
|
||||
export interface Selection {
|
||||
layer: Layer;
|
||||
@@ -28,6 +35,12 @@ interface EditorHandle {
|
||||
destroy: () => void;
|
||||
}
|
||||
|
||||
/** 표 부품 손잡이 — 도면 줄 도번을 다시 그리려고 `recalc` 을 씀 */
|
||||
interface SheetEditorHandle extends EditorHandle {
|
||||
getDoc: () => { 열: StructureColumn[] };
|
||||
recalc: () => void;
|
||||
}
|
||||
|
||||
type Mods = Record<string, () => Promise<unknown>>;
|
||||
// 표 부품(sub3) · 도면 부품(sub2) — 파일 이름은 각 창이 정함 → 폴더를 훑어 내보낸 이름으로 찾음
|
||||
const SHEET_MODS: Mods = import.meta.glob("../ui_template/sheet/*.ts");
|
||||
@@ -65,12 +78,14 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
const slot = el("div", { className: "m02-main__slot" }); // 도면 양식의 작도 영역 칸이 들어옴
|
||||
const notice = el("div", { className: "m02-main__notice", attrs: { hidden: "" } });
|
||||
const host = el("div", { className: "m02-main__host" });
|
||||
const extra = el("div", { className: "m02-main__extra" }); // 표 밖 형제 자리 — 구조물 설계 컨테이너
|
||||
const root = el("div", {
|
||||
className: "m02-main",
|
||||
children: [
|
||||
el("div", { className: "m02-main__head", children: [title, slot, reload, save] }),
|
||||
notice,
|
||||
host,
|
||||
extra,
|
||||
],
|
||||
});
|
||||
|
||||
@@ -78,6 +93,8 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
let version = "";
|
||||
let loaded: unknown = null;
|
||||
let editor: EditorHandle | null = null;
|
||||
let sheet: SheetEditorHandle | null = null;
|
||||
let panel: StructurePanelHandle | null = null;
|
||||
let seq = 0;
|
||||
let dirty = false;
|
||||
|
||||
@@ -111,9 +128,31 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
const drop = (): void => {
|
||||
editor?.destroy();
|
||||
editor = null;
|
||||
sheet = null;
|
||||
panel?.destroy();
|
||||
panel = null;
|
||||
extra.replaceChildren();
|
||||
slot.replaceChildren();
|
||||
};
|
||||
|
||||
/** 구조물집계표 아래 설계 컨테이너 — 고른 열의 도면 미리보기 · [도면 수정] · 상세 산출근거 */
|
||||
function buildPanel(): StructurePanelHandle {
|
||||
const made = createStructurePanel({
|
||||
isAdmin,
|
||||
confirmLeave,
|
||||
// 같은 페이지에서 그 구조물 도면을 CAD 편집으로 엶 · 좌측 목록을 다시 받아
|
||||
// 고름 표시를 옮김(`sel` 은 `open` 이 기다리기 전에 이미 새 것 · 목록은 `getOpen` 을 봄)
|
||||
onEdit: (column) => {
|
||||
void open({ layer: "system", projectId: null, kind: "structure", name: column });
|
||||
onSaved?.();
|
||||
},
|
||||
// 새로 만든 뒤 — 집계표 도면 줄을 새 도번으로 다시 그림
|
||||
onCreated: () => sheet?.recalc(),
|
||||
});
|
||||
extra.replaceChildren(made.root);
|
||||
return made;
|
||||
}
|
||||
|
||||
async function mount(doc: unknown, at: Selection): Promise<void> {
|
||||
const readOnly = !canEdit(at.layer, isAdmin);
|
||||
host.replaceChildren();
|
||||
@@ -122,21 +161,33 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
SHEET_MODS,
|
||||
"createSheet",
|
||||
);
|
||||
if (create) {
|
||||
editor = create(host, doc, {
|
||||
mode: at.layer === "project" ? "project" : "master",
|
||||
onChange: () => (dirty = !readOnly),
|
||||
});
|
||||
return;
|
||||
}
|
||||
return empty(L("M02_NoSheet"));
|
||||
if (!create) return empty(L("M02_NoSheet"));
|
||||
// 구조물집계표(시스템 층)만 — 도면 줄에 도번 · 칸을 고르면 아래 컨테이너
|
||||
const struct = at.layer === "system" && at.name === STRUCTURE_TABLE ? buildPanel() : null;
|
||||
if (struct) await struct.reload();
|
||||
panel = struct;
|
||||
editor = create(host, doc, {
|
||||
mode: at.layer === "project" ? "project" : "master",
|
||||
onChange: () => (dirty = !readOnly),
|
||||
...(struct
|
||||
? {
|
||||
drawingLabel: (colId: string) => struct.numbers()[colId] ?? "",
|
||||
onSelect: (s: { colId: string | null }) =>
|
||||
struct.show(s.colId, sheet?.getDoc().열 ?? []),
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
if (struct) sheet = editor as SheetEditorHandle;
|
||||
return;
|
||||
}
|
||||
const mountDrawing = await findExport<(h: HTMLElement, d: unknown, o: object) => EditorHandle>(
|
||||
DRAWING_MODS,
|
||||
"mountDrawingTemplate",
|
||||
);
|
||||
if (mountDrawing) {
|
||||
editor = mountDrawing(host, doc, {
|
||||
// 구조물 도면은 CAD 문서가 `도면` 칸에 들어 있음 — 도번 · 산출근거는 안 건드림
|
||||
const cad = at.kind === "structure" ? (doc as StructureDoc).도면 : doc;
|
||||
editor = mountDrawing(host, cad, {
|
||||
onSave: () => void doSave(),
|
||||
readOnly,
|
||||
name: at.name,
|
||||
@@ -176,6 +227,11 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
)
|
||||
: got.문서;
|
||||
if (mine !== seq) return;
|
||||
// 구조물 도면은 열 id 로 열리니 머리에 도번을 함께 보임
|
||||
if (next.kind === "structure") {
|
||||
const number = (got.문서 as StructureDoc)?.도번;
|
||||
if (number) title.textContent = `${number} · ${next.name}`;
|
||||
}
|
||||
await mount(shown, next);
|
||||
} catch (error) {
|
||||
if (mine !== seq) return;
|
||||
@@ -189,7 +245,12 @@ export function createMain(isAdmin: boolean, onSaved?: () => void): MainHandle {
|
||||
if (!sel) return;
|
||||
const at = sel;
|
||||
try {
|
||||
const doc = editor ? await editor.getDoc() : loaded;
|
||||
const edited = editor ? await editor.getDoc() : loaded;
|
||||
// 구조물 도면 — CAD 는 `도면` 칸만 다룸 · 도번 · 산출근거는 읽은 그대로 둠
|
||||
const doc =
|
||||
at.kind === "structure" && loaded
|
||||
? { ...(loaded as StructureDoc), 도면: edited as StructureDoc["도면"] }
|
||||
: edited;
|
||||
const info = await saveTemplate(at.layer, at.kind, at.name, at.projectId, version, doc);
|
||||
version = info.판;
|
||||
loaded = doc;
|
||||
|
||||
Reference in New Issue
Block a user