fix(495-2 M02 파일 업로드): 도면 상세 · 도면 양식 [파일 업로드] 지움 — DWG = CAD [삽입 → DWG 불러오기] 한 길
- M02_MasterTemplete_Drawing.ts — importDrawingFile · noImport · [파일 업로드] 덩이 지움 - DrawingCard · AreaDrawing — noImport 곁값 지움 · CardHelp 글 = CAD [삽입] DWG 불러오기 - 서버 /api/m02/drawing-import = 부르는 곳 0 · 남김 - 시험 test_m02_card_shell 두 개 고쳐 씀 · ui_checks 47-1 기대 detailImport = 0 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -160,7 +160,6 @@ export function createAreaDrawing(
|
||||
originMarker: true,
|
||||
noArea: true,
|
||||
frame: true,
|
||||
noImport: true,
|
||||
pickTabs: true,
|
||||
});
|
||||
frame = stage.querySelector("iframe");
|
||||
|
||||
@@ -40,7 +40,7 @@ export const CARD_HELP: Record<"structure" | "labor" | "area", CardHelp> = {
|
||||
features: [
|
||||
SAVE,
|
||||
take("도면"),
|
||||
["수정", "도면 상세(전체 편집 화면)를 엶 — 파일 업로드(DXF · DWG)는 여기"],
|
||||
["수정", "도면 상세(전체 편집 화면)를 엶 — DWG 불러오기(CAD [삽입])는 여기"],
|
||||
clear("도면"),
|
||||
FOLD,
|
||||
],
|
||||
@@ -98,7 +98,7 @@ export const CARD_HELP: Record<"structure" | "labor" | "area", CardHelp> = {
|
||||
|
||||
/** 상세에만 있는 단추 줄(49-7) — 카드 도움말 글 한 벌 뒤에 더함 */
|
||||
const DETAIL_ONLY: Record<keyof typeof CARD_HELP, [string, string][]> = {
|
||||
structure: [["파일 업로드", "DXF · DWG 파일을 도면으로 불러옴(상세 머리 [파일 업로드])"]],
|
||||
structure: [["DWG 불러오기", "DWG · DXF 파일을 지금 도면에 더함(CAD 리본 [삽입])"]],
|
||||
labor: [],
|
||||
area: [["도면으로 보내기", "고른 범위를 도면 표로 보냄(상세 머리)"]],
|
||||
};
|
||||
|
||||
@@ -67,13 +67,6 @@
|
||||
gap: var(--spacing-8);
|
||||
}
|
||||
|
||||
.m02-drawing__actions {
|
||||
display: flex;
|
||||
gap: var(--spacing-8);
|
||||
margin-left: auto;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.m02-pop {
|
||||
display: block;
|
||||
background-color: transparent; /* 단추 아래 뜨는 작은 창 — 뒤를 가리지 않음 */
|
||||
|
||||
@@ -39,7 +39,7 @@ export interface DrawingTemplateOptions {
|
||||
projectId?: string | null;
|
||||
/** 저장 안 한 고침이 생기면 true — CAD 편집 · 작도 영역 값 바꿈. */
|
||||
onChanged?: (dirty: boolean) => void;
|
||||
/** 페이지 제목 줄 안의 빈 칸 — 있으면 작도 영역 칸 · [파일 업로드]를 거기 한 줄로 놓는다. */
|
||||
/** 페이지 제목 줄 안의 빈 칸 — 있으면 작도 영역 칸을 거기 한 줄로 놓는다. */
|
||||
headerSlot?: HTMLElement;
|
||||
/** CAD 좌측 패널(특성 · 도면층)을 접힌 채로 연다 — 누르면 펼침(구조물 도면 미리보기). */
|
||||
panelsCollapsed?: boolean;
|
||||
@@ -51,8 +51,6 @@ export interface DrawingTemplateOptions {
|
||||
noArea?: boolean;
|
||||
/** B07 도각을 외곽 좌하단 (0,0) 에 얹음 — 잠금 층 · 보여주기만(돌려줄 때 뺌 · 저장 안 됨). */
|
||||
frame?: boolean;
|
||||
/** [파일 업로드] 단추를 안 둠 — 집계표 카드 미리보기(불러오기는 도면 상세에서만). */
|
||||
noImport?: boolean;
|
||||
/** 장id(82-1) — 자동백업 칸을 장마다 나눔(1장 = 빈 값 · 옛 칸 그대로) */
|
||||
sheet?: string;
|
||||
/** 장 도번(82-2) — 얹은 도각 `{{도면번호}}` 자리 */
|
||||
@@ -142,25 +140,6 @@ function withoutFrame(drawing: DrawingTemplateDoc): DrawingTemplateDoc {
|
||||
};
|
||||
}
|
||||
|
||||
async function importDrawingFile(
|
||||
file: File,
|
||||
): Promise<{ drawing: DrawingTemplateDoc; entity_count: number }> {
|
||||
const form = new FormData();
|
||||
form.append("file", file);
|
||||
const response = await fetch(`${API_BASE_URL}/m02/drawing-import`, {
|
||||
method: "POST",
|
||||
credentials: "include",
|
||||
body: form,
|
||||
});
|
||||
const payload = (await response.json()) as {
|
||||
drawing: DrawingTemplateDoc;
|
||||
entity_count: number;
|
||||
message?: string;
|
||||
};
|
||||
if (!response.ok) throw new Error(payload.message ?? `HTTP ${response.status}`);
|
||||
return payload;
|
||||
}
|
||||
|
||||
export function mountDrawingTemplate(
|
||||
container: HTMLElement,
|
||||
doc: DrawingTemplateDoc,
|
||||
@@ -292,45 +271,6 @@ export function mountDrawingTemplate(
|
||||
after?.();
|
||||
};
|
||||
|
||||
const actions = document.createElement("div");
|
||||
actions.className = "m02-drawing__actions";
|
||||
const canImport = !readOnly && options.noImport !== true;
|
||||
if (canImport) {
|
||||
const fileInput = document.createElement("input");
|
||||
fileInput.type = "file";
|
||||
fileInput.accept = ".dxf,.dwg";
|
||||
fileInput.hidden = true;
|
||||
fileInput.addEventListener("change", () => {
|
||||
const file = fileInput.files?.[0];
|
||||
fileInput.value = "";
|
||||
if (!file) return;
|
||||
importButton.disabled = true;
|
||||
importDrawingFile(file)
|
||||
.then((response) => {
|
||||
// 불러온 도각은 아직 저장하지 않는다 — 자리표를 놓고 [저장]을 눌러야 양식이 된다.
|
||||
void load(response.drawing);
|
||||
options.onChanged?.(true); // 불러온 것은 아직 저장 전 — 떠날 때 묻게 함
|
||||
showToast(`도형 ${response.entity_count}개를 불러왔습니다.`, "success");
|
||||
})
|
||||
.catch((error) =>
|
||||
showToast(
|
||||
error instanceof Error ? error.message : "도각 파일을 불러오지 못했습니다.",
|
||||
"error",
|
||||
),
|
||||
)
|
||||
.finally(() => (importButton.disabled = false));
|
||||
});
|
||||
const importButton = createButton({
|
||||
label: "파일 업로드",
|
||||
variant: "filled",
|
||||
onClick: () => fileInput.click(),
|
||||
});
|
||||
// 구조물 조합 층 단추([마스터])와 같은 꼴 — 실무자료 [파일 업로드]와 같은 종류(362-2)
|
||||
importButton.classList.add("m02-layers__btn");
|
||||
importButton.title = importButton.ariaLabel = "파일 업로드 (DXF · DWG)";
|
||||
actions.append(importButton, fileInput);
|
||||
}
|
||||
|
||||
const getDoc = async (): Promise<DrawingTemplateDoc> => {
|
||||
const { drawing: saved } = await cad.requestSave();
|
||||
const drawing = options.frame ? withoutFrame(saved) : saved;
|
||||
@@ -345,13 +285,14 @@ export function mountDrawingTemplate(
|
||||
};
|
||||
|
||||
// 한 줄 — 페이지가 머리 칸(headerSlot)을 주면 거기, 아니면 그림 칸 위에 작게.
|
||||
toolbar.append(...(noArea ? [] : [areaButton]), actions);
|
||||
// DWG · DXF 불러오기 = CAD 리본 [삽입 → DWG 불러오기] · 끌어다 놓기 한 길(495-2)
|
||||
toolbar.append(...(noArea ? [] : [areaButton]));
|
||||
const tabs = options.tabs ? [options.tabs] : [];
|
||||
if (options.headerSlot) {
|
||||
toolbar.classList.add("m02-drawing__toolbar--slot");
|
||||
options.headerSlot.append(toolbar);
|
||||
root.append(...tabs, cad.element);
|
||||
} else root.append(...(noArea && !canImport ? [] : [toolbar]), ...tabs, cad.element);
|
||||
} else root.append(...(noArea ? [] : [toolbar]), ...tabs, cad.element);
|
||||
container.append(root);
|
||||
void load(doc);
|
||||
|
||||
|
||||
@@ -85,7 +85,6 @@ function mountStructure(
|
||||
originMarker: true, // 좌표 0,0 기준점 십자
|
||||
noArea: true, // 작도 영역 칸 없음
|
||||
frame: true, // 도각 = 보여주기만 · 외곽 좌하단 (0,0)(56장)
|
||||
noImport: true, // 파일 업로드는 도면 상세에서만(47-2)
|
||||
pickTabs: true,
|
||||
...hooks,
|
||||
});
|
||||
|
||||
@@ -117,10 +117,12 @@ def test_도움말_제목_옆_네_절():
|
||||
|
||||
|
||||
def test_미리보기_파일_불러오기_없음():
|
||||
"""47-2 — 도면 카드 미리보기엔 [파일 업로드] 없음 · 도면 상세(전체 편집)는 그대로."""
|
||||
"""47-2 · 495-2 — M02 [파일 업로드] 없음(카드 · 상세 모두) · DWG = CAD [삽입 → DWG 불러오기] 한 길."""
|
||||
drawing = _text("M02_MasterTemplete_Drawing.ts")
|
||||
assert "const canImport = !readOnly && options.noImport !== true;" in drawing
|
||||
assert "noImport: true," in _text("M02_MasterTemplete_DrawingCard.ts")
|
||||
for gone in ("noImport", "canImport", "importDrawingFile", "/m02/drawing-import"):
|
||||
assert gone not in drawing
|
||||
for name in ("M02_MasterTemplete_DrawingCard.ts", "M02_MasterTemplete_AreaDrawing.ts"):
|
||||
assert "noImport" not in _text(name)
|
||||
|
||||
|
||||
def test_일위대가_줄_고름과_옵션_단추():
|
||||
@@ -181,10 +183,10 @@ def test_옵션_줄_구분_이름_별칭_병합():
|
||||
|
||||
|
||||
def test_도면_상세_머리_파일_업로드_단추():
|
||||
"""362-2 — 도면 상세 머리 📂 → 글 단추 [파일 업로드](구조물 조합 층 단추 꼴 · 실무자료와 같은 종류)."""
|
||||
"""362-2 → 495-2 — 도면 상세 머리 [파일 업로드] 지움 · 도움말 = CAD [삽입] DWG 불러오기."""
|
||||
drawing = _text("M02_MasterTemplete_Drawing.ts")
|
||||
assert 'label: "파일 업로드",' in drawing and 'variant: "filled",' in drawing
|
||||
assert 'importButton.classList.add("m02-layers__btn");' in drawing
|
||||
assert '"파일 업로드 (DXF · DWG)"' in drawing
|
||||
assert "파일 업로드" not in drawing and "importButton" not in drawing
|
||||
assert "📂" not in drawing and "파일 불러오기 (DXF" not in drawing
|
||||
help_ = _text("M02_MasterTemplete_CardHelp.ts")
|
||||
assert "파일 업로드" not in help_ and '["DWG 불러오기",' in help_
|
||||
assert "📂" not in _text("M02_MasterTemplete_CardHelp.ts")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* 47-1 · 47-2 — 구조물 조합 카드 셋 [?] = 제목 바로 옆 · 도움말 네 절 · 도면 미리보기 [파일 업로드] 없음 · 도면 상세 [파일 업로드] 있음
|
||||
/* 47-1 · 47-2 — 구조물 조합 카드 셋 [?] = 제목 바로 옆 · 도움말 네 절 · 도면 미리보기 · 도면 상세 [파일 업로드] 없음(495-2 · DWG = CAD [삽입])
|
||||
* 시작 화면: M02 마스터 템플릿 · 마스터 층(#/m02-master-template?open=구조물조합&root=master) · 시스템 관리자 ·
|
||||
* 나무에 item1(구조물 조합)이 있음
|
||||
* 부르는 법: orca eval --expression "$(cat 이 파일)" (async 식 · JSON 글을 돌려줌 · 20초 안)
|
||||
@@ -6,7 +6,7 @@
|
||||
* 기대 수치:
|
||||
* - cards = 3(도면 정보 · 일위대가 · 면적산출) · 카드마다 nextToTitle = true(? 가 제목 글 바로 다음) ·
|
||||
* inTools = false · parts = ["about","keys","features","steps"] · opened = true · closed = true
|
||||
* - previewImport = 0(카드 미리보기 [파일 업로드]) · detailImport = 1(도면 상세 [파일 업로드]) · back = true(카드 화면으로 돌아옴)
|
||||
* - previewImport = 0(카드 미리보기 [파일 업로드]) · detailImport = 0(도면 상세 [파일 업로드] · 495-2 지움) · back = true(카드 화면으로 돌아옴)
|
||||
*/
|
||||
(async () => {
|
||||
const w = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
@@ -57,10 +57,14 @@
|
||||
if (!edit) return JSON.stringify({ ...out, error: "도면 [수정] 없음" });
|
||||
const hash = location.hash;
|
||||
edit.click();
|
||||
out.detailImport = (await until(() => imports(), 8000)) || 0;
|
||||
[...document.querySelectorAll("button")]
|
||||
.find((b) => vis(b) && b.innerText.trim() === "돌아가기")
|
||||
?.click();
|
||||
const back = () =>
|
||||
[...document.querySelectorAll("button")].find(
|
||||
(b) => vis(b) && b.innerText.trim() === "돌아가기",
|
||||
);
|
||||
await until(back, 8000);
|
||||
await w(2500);
|
||||
out.detailImport = imports();
|
||||
back()?.click();
|
||||
out.back = !!(await until(
|
||||
() => location.hash === hash && document.querySelector(".m02-struct__card"),
|
||||
));
|
||||
|
||||
Reference in New Issue
Block a user