feat(716-4): 서고 나무 폴더 — 종류 인자 · 안에 든 것째 지움 · 쓰는 곳 409 · 여럿 · 복사 붙여넣기

- 서버 `M02_Precombo_Folders` — 종류 인자(precombo · sangeun · 자리 파일 `{종류}_폴더.json`) · 폴더 지우기 = 안의 문서 파일째(모두 검사 뒤 한 번에 · 바깥에서 쓰면 409 + 그 이름 · 지우는 것끼리 참조는 됨) · 문서 지우기 · `대상` 여럿 옮기기 · 지우기 · 붙여넣기(새 키 · 본뜬 = 원본 · 같은 폴더 이름 「(1)」)
- 길 `M02_Labor_Router` — `/layers/{층}/{종류}-tree` GET · POST · `/paste`(옛 precombo-tree 주소 그대로)
- 화면 새 `UI_Side_Library.ts` — 일위대가 · 단가산출 두 칸이 같이 쓰는 서고 칸(Ctrl · Shift 고름 · 오른쪽 클릭 · Ctrl+C · Ctrl+V · Delete · 지우기 확인 창 · 끌어 옮기기 여럿) · `UI_Side_Precombo.ts` = 일위대가 몫만 넘김
- `Api_Fetch` — 나무 부르기 종류 인자 · `pasteLibraryTree` · `newLibrary` 종류 sangeun
- 시험 — 새 `test_716_4_library_folders.py`(임시 storage) · 낡은 것 고침: `test_m02_precombo_folders`(빈 폴더만 지움 → 안에 든 것째 · 「없는 사전조합」 → 「없는 문서」 · FILE → file_of) · `test_m02_precombo_scope` + helper(나무 짜기 · 서고 길 글이 Library.ts 로 옮김)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-01 15:35:23 +09:00
co-authored by Claude Opus 5.5
parent d27dba4f23
commit ceec2a99da
9 changed files with 842 additions and 362 deletions
@@ -150,7 +150,7 @@ export type LibraryBody =
{ 문서: Record<string, unknown> } | { 본뜬: { 층: Layer; 주인: string | null; 키: string } };
export const newLibrary = (
layer: Layer,
kind: "precombo",
kind: LibraryKind,
body: LibraryBody,
owner?: string | null,
): Promise<TemplateInfo> =>
@@ -159,25 +159,49 @@ export const newLibrary = (
body: JSON.stringify(body),
});
/** 사전조합 나무 자유 폴더(158-1) — 자리 없는 문서 = 뿌리 · 판이 다르면 409(`StaleError`) */
/** 서고 나무 자유 폴더(158-1 · 716-4) — 일위대가(precombo) · 단가산출(sangeun) 따로 ·
* 자리 없는 문서 = 뿌리 · 판이 다르면 409(`StaleError`) · 지우기 = 안에 든 문서째(쓰는 곳 있으면 409) */
export type LibraryKind = "precombo" | "sangeun";
export interface PrecomboTree {
판: string;
폴더: string[][];
자리: Record<string, string[]>;
알림?: { op: string; 지운문서?: string[]; 만든문서?: string[]; 바뀐이름?: string[] };
}
export const fetchPrecomboTree = (layer: Layer, owner: string | null): Promise<PrecomboTree> =>
call(owned(layer, `/layers/${layer}/precombo-tree`, owner));
const libTree = (kind: LibraryKind, layer: Layer, owner: string | null, tail = ""): string =>
owned(layer, `/layers/${layer}/${kind}-tree${tail}`, owner);
export const fetchPrecomboTree = (
layer: Layer,
owner: string | null,
kind: LibraryKind = "precombo",
): Promise<PrecomboTree> => call(libTree(kind, layer, owner));
export const editPrecomboTree = (
layer: Layer,
edit: Pick<TreeEdit, "경로" | "이름" | "새경로" | "키"> & {
op: "add-folder" | "rename" | "move" | "delete";
대상?: TreeRef[];
},
판: string,
owner: string | null,
kind: LibraryKind = "precombo",
): Promise<PrecomboTree> =>
call(owned(layer, `/layers/${layer}/precombo-tree`, owner), {
call(libTree(kind, layer, owner), { method: "POST", body: JSON.stringify({ ...edit, 판 }) });
/** 복사해 둔 문서 · 폴더 → 이 층 `dest` 아래 새 키(폴더는 안의 것까지 · 같은 폴더 이름 「(1)」) */
export const pasteLibraryTree = (
kind: LibraryKind,
layer: Layer,
owner: string | null,
clip: TreeClip,
dest: string[],
): Promise<PrecomboTree> =>
call(libTree(kind, layer, owner, "/paste"), {
method: "POST",
body: JSON.stringify({ ...edit, 판 }),
body: JSON.stringify({
from_layer: clip.from.layer,
from_owner: clip.from.owner,
대상: clip.refs,
경로: dest,
}),
});
/* --- 구조물 도면(종류 structure · 이름 = 구조물집계표 열 id) ---