fix(M02): 보낸 표 놓기 전 탭을 바꾸면 그 장에 다시 놓기 · 저장 뒤 지금 장 미저장 표시 지움(82-3)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
This commit is contained in:
@@ -92,7 +92,12 @@ export interface DrawingTemplateHandle {
|
||||
placeTable: (entity: Record<string, unknown>, link: string) => void;
|
||||
updateTable: (link: string, cells: unknown[][]) => Promise<number>;
|
||||
/** 다른 장을 같은 CAD 에 실음(82-1) — 백업 칸 · 도각 도번도 그 장 것으로 */
|
||||
loadSheet: (drawing: DrawingTemplateDoc, sheet: string, frameNumber?: string) => void;
|
||||
loadSheet: (
|
||||
drawing: DrawingTemplateDoc,
|
||||
sheet: string,
|
||||
frameNumber?: string,
|
||||
after?: () => void,
|
||||
) => Promise<void>;
|
||||
destroy: () => void;
|
||||
}
|
||||
|
||||
@@ -249,7 +254,8 @@ export function mountDrawingTemplate(
|
||||
onHostSave: hostSave,
|
||||
});
|
||||
let loadSeq = 0;
|
||||
const load = async (drawing: DrawingTemplateDoc): Promise<void> => {
|
||||
/** `after` = 싣기를 보낸 바로 뒤(이 싣기가 마지막일 때만) — 표 놓기를 「열린 뒤」로 미룰 때 */
|
||||
const load = async (drawing: DrawingTemplateDoc, after?: () => void): Promise<void> => {
|
||||
const mine = ++loadSeq;
|
||||
cad.beginLoading();
|
||||
const frame = options.frame ? await fetchFrame(frameNumber) : null;
|
||||
@@ -279,6 +285,7 @@ export function mountDrawingTemplate(
|
||||
originMarker: options.originMarker === true,
|
||||
},
|
||||
);
|
||||
after?.();
|
||||
};
|
||||
|
||||
const actions = document.createElement("div");
|
||||
@@ -346,11 +353,11 @@ export function mountDrawingTemplate(
|
||||
getDoc,
|
||||
placeTable: cad.placeTable,
|
||||
updateTable: cad.updateTable,
|
||||
loadSheet: (drawing, sheet, number) => {
|
||||
loadSheet: (drawing, sheet, number, after) => {
|
||||
recoveryScope = recoveryScopeOf(options, sheet);
|
||||
frameNumber = number ?? "";
|
||||
base = drawing;
|
||||
void load(drawing);
|
||||
return load(drawing, after);
|
||||
},
|
||||
destroy: () => {
|
||||
areaModal?.close();
|
||||
@@ -417,6 +424,13 @@ export function mountStructureSheets(
|
||||
const more = doc.더한장 ?? [];
|
||||
let cadDirty = false;
|
||||
let listDirty = false;
|
||||
/** 아직 안 놓은 보낸 표(82-3) — 놓기 전에 탭을 바꾸면 그 장에 다시 걺(놓을 장 = 지금 탭) */
|
||||
let placing: { entity: Record<string, unknown>; link: string } | null = null;
|
||||
const placed = (got: DrawingTemplateDoc, link: string): boolean =>
|
||||
got.entities.some((e) => {
|
||||
const style = (e as { shapeData?: { style?: Record<string, unknown> } }).shapeData?.style;
|
||||
return e.type === "Table" && style?.연결 === link;
|
||||
});
|
||||
const report = (): void => options.onChanged?.(cadDirty || listDirty || tabs.anyDirty());
|
||||
const numberOf = (id: string): string =>
|
||||
sheetNumber(
|
||||
@@ -426,13 +440,19 @@ export function mountStructureSheets(
|
||||
|
||||
const tabs: CadTabs<DrawingTemplateDoc> = createCadTabs<DrawingTemplateDoc>({
|
||||
features: readOnly ? {} : { add: true, rename: true, remove: true, reorder: true },
|
||||
capture: async () => ({ drawing: await drawing.getDoc(), dirty: cadDirty }),
|
||||
show: (tab) => {
|
||||
capture: async () => {
|
||||
const got = await drawing.getDoc();
|
||||
if (placing && placed(got, placing.link)) placing = null;
|
||||
return { drawing: got, dirty: cadDirty };
|
||||
},
|
||||
show: async (tab) => {
|
||||
cadDirty = false;
|
||||
drawing.loadSheet(
|
||||
// 놓기는 싣기를 보낸 바로 뒤 — cad_host 가 「열린 뒤」로 미룸(먼저 보내면 싣기가 도구를 끔)
|
||||
await drawing.loadSheet(
|
||||
tab.drawing ?? { entities: [], layers: [BLANK_LAYER] },
|
||||
tab.id === FIRST_TAB ? "" : tab.id,
|
||||
numberOf(tab.id),
|
||||
() => placing && drawing.placeTable(placing.entity, placing.link),
|
||||
);
|
||||
report();
|
||||
},
|
||||
@@ -491,6 +511,7 @@ export function mountStructureSheets(
|
||||
도면: tab.drawing ?? { format: 6, entities: [], layers: [{ ...BLANK_LAYER }] },
|
||||
}));
|
||||
listDirty = false;
|
||||
cadDirty = false; // 받기(requestSave)가 CAD 미저장도 내림 — 다음 고침이 다시 알림
|
||||
tabs.markClean(undefined, true);
|
||||
return {
|
||||
도면: first?.drawing ?? doc.도면,
|
||||
@@ -501,7 +522,10 @@ export function mountStructureSheets(
|
||||
const id = tabs.active()?.id ?? FIRST_TAB;
|
||||
return id === FIRST_TAB ? "" : id;
|
||||
},
|
||||
placeTable: drawing.placeTable,
|
||||
placeTable: (entity, link) => {
|
||||
placing = { entity, link };
|
||||
drawing.placeTable(entity, link);
|
||||
},
|
||||
// 실린 장은 CAD · 안 실린 장은 받아 둔 편집본에서(82-3)
|
||||
updateTable: async (link, cells) => {
|
||||
const now = tabs.active();
|
||||
|
||||
@@ -103,13 +103,14 @@ const tabsMod = load("ui_template/cad_host/cad_host_tabs.ts", { "@ui/ui_template
|
||||
|
||||
// ⑤ M02 여러 장 — 가짜 CAD(requestSave = 지금 실린 도면 + 편집)
|
||||
const cadLoads = [];
|
||||
const ev = [];
|
||||
let inCad = null;
|
||||
const fakeCad = {
|
||||
element: node("div"),
|
||||
beginLoading() {},
|
||||
load: (drawing, meta, frameEdit, fields, extra) => (cadLoads.push(extra.recoveryScope), (inCad = drawing)),
|
||||
load: (drawing, meta, frameEdit, fields, extra) => (ev.push("load"), cadLoads.push(extra.recoveryScope), (inCad = drawing)),
|
||||
requestSave: async () => ({ drawing: inCad, quantityTable: null }),
|
||||
placeTable() {},
|
||||
placeTable: (entity, link) => ev.push("place " + link),
|
||||
updateTable: async () => 1,
|
||||
destroy() {},
|
||||
};
|
||||
@@ -142,6 +143,18 @@ const tabsMod = load("ui_template/cad_host/cad_host_tabs.ts", { "@ui/ui_template
|
||||
const third = bar.kids.find((k) => k.dataset.tabId && k.dataset.active === "true").dataset.tabId;
|
||||
await bar.kids.find((k) => k.dataset.tabId === "#1").on.click();
|
||||
await new Promise((r) => setTimeout(r, 5));
|
||||
// 보낸 표를 놓기 전에 탭을 바꾸면 그 장에서 다시 놓기(싣기 뒤) · 놓은 뒤에는 안 걺
|
||||
const tabNodes = () => bar.kids.filter((k) => k.dataset.tabId);
|
||||
ev.length = 0;
|
||||
sheets.placeTable(table("T9"), "T9");
|
||||
await tabNodes()[1].on.click();
|
||||
await new Promise((r) => setTimeout(r, 5));
|
||||
out.replace = ev.slice();
|
||||
inCad = { ...inCad, entities: [...inCad.entities, table("T9")] }; // 놓음
|
||||
ev.length = 0;
|
||||
await tabNodes()[0].on.click();
|
||||
await new Promise((r) => setTimeout(r, 5));
|
||||
out.placedOnce = ev.slice();
|
||||
out.updated = await sheets.updateTable("T2", [[{ text: "새" }]]);
|
||||
const got = await sheets.getDoc();
|
||||
out.m02 = {
|
||||
@@ -210,15 +223,21 @@ def test_B07_목록에서_연_도면이_탭_미저장_편집_지킴():
|
||||
def test_여러_장_문서_장_도번_백업_칸(got):
|
||||
m02 = got["m02"]
|
||||
assert m02["first"] == 2
|
||||
assert m02["more"] == [["단면", 1], ["3장", 1]]
|
||||
assert m02["more"] == [["단면", 2], ["3장", 1]] # 단면에 T9 표를 놓음
|
||||
assert m02["newId"] is True and m02["active"] == ""
|
||||
assert m02["scopes"][0] == "m02:system:rv" and m02["scopes"][1].startswith("m02:system:rv#s")
|
||||
assert m02["number"] == "SD-1-3"
|
||||
q = "/api/m02/structure-frame?number="
|
||||
assert m02["frames"] == [q + "SD-1", q + "SD-1-3"] # 장 도번마다 한 번(1장은 다시 안 받음)
|
||||
# 장 도번마다 한 번(같은 도번은 다시 안 받음)
|
||||
assert m02["frames"] == [q + "SD-1", q + "SD-1-3", q + "SD-1-2"]
|
||||
assert m02["dirty"] is True # 장 더함 = 저장 안 한 고침
|
||||
|
||||
|
||||
def test_놓기_전_탭을_바꾸면_그_장에_다시_놓기(got):
|
||||
assert got["replace"] == ["place T9", "load", "place T9"] # 싣기 뒤에 다시
|
||||
assert got["placedOnce"] == ["load"]
|
||||
|
||||
|
||||
def test_안_실린_장_표도_갈음(got):
|
||||
assert got["updated"] == 2 # 받아 둔 둘째 장 1 + 실린 장(가짜 CAD) 1
|
||||
assert got["m02"]["t2"] == "새"
|
||||
|
||||
Reference in New Issue
Block a user