Merge remote-tracking branch 'origin/sub_laptop_2' into sub_laptop_1
충돌 셋(UI_Side · UI_Style · locale_m2)은 양쪽을 모두 살려 풂 — 옵션 보이기 · 항목 고르기 문구 · 층 화면 문구를 한 벌로, 도면 양식 줄은 시스템 층에서만.
This commit is contained in:
@@ -53,6 +53,15 @@ function reason(detail: unknown, status: number): string {
|
||||
return lines.filter(Boolean).join(" · ") || `HTTP ${status}`;
|
||||
}
|
||||
|
||||
/** 지금 화면의 층 — 시스템 = 옛 길 그대로 · 회사 · 개인 = `/layers/{층}` 아래(구조물집계표 · 조합 길 모두) */
|
||||
let activeLayer: Layer = "system";
|
||||
export const setActiveLayer = (layer: Layer): void => {
|
||||
activeLayer = layer;
|
||||
};
|
||||
export const getActiveLayer = (): Layer => activeLayer;
|
||||
const scoped = <T>(path: string, init: RequestInit = {}): Promise<T> =>
|
||||
call<T>(`${activeLayer === "system" ? "" : `/layers/${activeLayer}`}${path}`, init);
|
||||
|
||||
const enc = encodeURIComponent;
|
||||
const q = (projectId: string | null): string => (projectId ? `?project_id=${enc(projectId)}` : "");
|
||||
const head = (layer: Layer): string =>
|
||||
@@ -122,7 +131,7 @@ export const listStructures = async (): Promise<TemplateInfo[]> =>
|
||||
|
||||
/** 새로 — 도번 자동 · 빈 도면 (+ 없으면 빈 면적산출 · 재료산출 통합문서) · 이미 있으면 StaleError */
|
||||
export const createStructure = (column: string): Promise<TemplateDoc> =>
|
||||
call(`/structures/${enc(column)}`, { method: "POST" });
|
||||
scoped(`/structures/${enc(column)}`, { method: "POST" });
|
||||
|
||||
/** 한 열의 번호 — 도번 `SD` · 면적번 `SA` · 재료번 `SM` + 같은 8자리
|
||||
* [종류][분류1][분류2][분류3](없는 쪽은 빈 글) */
|
||||
@@ -134,7 +143,7 @@ export interface StructureNumbers {
|
||||
|
||||
/** `{열 id: {도번, 면적번, 재료번}}` — 구조물 열만(글 열 · 없는 열은 키 없음 = 「없음」) */
|
||||
export const fetchStructureNumbers = (): Promise<Record<string, StructureNumbers>> =>
|
||||
call("/structures/numbers");
|
||||
scoped("/structures/numbers");
|
||||
|
||||
/** 구조물집계표조합 한 줄 — 구조물 열 하나(키 `SS` + 6자리 · 한 번 준 키는 안 바뀜) */
|
||||
export interface StructureCombo extends StructureNumbers {
|
||||
@@ -161,7 +170,7 @@ export interface StructureCombos {
|
||||
}
|
||||
|
||||
/** 조합 표 — 서버가 집계표 [저장] 때 맞춤(읽기만) */
|
||||
export const fetchStructureCombos = (): Promise<StructureCombos> => call("/structure-combos");
|
||||
export const fetchStructureCombos = (): Promise<StructureCombos> => scoped("/structure-combos");
|
||||
|
||||
/** 조합 갈라 내기 결과 — `새로만듦` false = 같은 담은 로직의 조합이 이미 있어 그 키를 가리킴 */
|
||||
export interface BranchedCombo {
|
||||
@@ -182,14 +191,14 @@ export const branchCombo = (
|
||||
판?: string;
|
||||
},
|
||||
): Promise<BranchedCombo> =>
|
||||
call(`/structures/${enc(column)}/combo`, { method: "POST", body: JSON.stringify(body) });
|
||||
scoped(`/structures/${enc(column)}/combo`, { method: "POST", body: JSON.stringify(body) });
|
||||
|
||||
/** 있는 조합을 이 열에 씀 — 집계표 그 열 일위대가 · 자재조합 키만 바꿈(조합은 그대로 · `새로만듦` false) */
|
||||
export const setColumnCombo = (
|
||||
column: string,
|
||||
body: { 종류: "일위대가" | "자재조합"; 키: string; 판?: string },
|
||||
): Promise<BranchedCombo> =>
|
||||
call(`/structures/${enc(column)}/use-combo`, { method: "POST", body: JSON.stringify(body) });
|
||||
scoped(`/structures/${enc(column)}/use-combo`, { method: "POST", body: JSON.stringify(body) });
|
||||
|
||||
/** 자재 조합(키 `UM`) 담은 자재 한 줄 */
|
||||
export interface MaterialItem {
|
||||
@@ -210,7 +219,7 @@ export interface MaterialCombo {
|
||||
}
|
||||
|
||||
export const fetchMaterialCombo = (key: string): Promise<MaterialCombo> =>
|
||||
call(`/material-combos/${enc(key)}`);
|
||||
scoped(`/material-combos/${enc(key)}`);
|
||||
|
||||
/** 이 열의 자재 조합을 고친 담은 자재로 갈라 냄 — 규칙은 `branchCombo` 와 같음 ·
|
||||
* `본뜬키` 빈 글 = 이 열의 첫 자재 조합 */
|
||||
@@ -218,7 +227,7 @@ export const branchMaterialCombo = (
|
||||
column: string,
|
||||
body: { 본뜬키?: string; 담은자재: MaterialItem[]; 이름: string; 판?: string },
|
||||
): Promise<BranchedCombo> =>
|
||||
call(`/structures/${enc(column)}/material-combo`, {
|
||||
scoped(`/structures/${enc(column)}/material-combo`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
@@ -229,14 +238,14 @@ export const listMaterialCombos = (): Promise<{
|
||||
판: string;
|
||||
줄: MaterialCombo[];
|
||||
쓰는곳: Record<string, string[]>;
|
||||
}> => call("/material-combos");
|
||||
}> => scoped("/material-combos");
|
||||
|
||||
/** 새로 · 본떠 만들기(`본뜬키`) — 키는 서버가 표 「다음」 번호로 줌 */
|
||||
export const createMaterialCombo = (
|
||||
판: string,
|
||||
줄: Omit<MaterialCombo, "키">,
|
||||
): Promise<{ 키: string; 판: string; 줄: MaterialCombo }> =>
|
||||
call("/material-combos", { method: "POST", body: JSON.stringify({ 판, 줄 }) });
|
||||
scoped("/material-combos", { method: "POST", body: JSON.stringify({ 판, 줄 }) });
|
||||
|
||||
/** 고치기 — 이름 · 비고 · 담은자재(본뜬키 · 소유는 서버가 있던 것으로) */
|
||||
export const editMaterialCombo = (
|
||||
@@ -244,11 +253,11 @@ export const editMaterialCombo = (
|
||||
판: string,
|
||||
줄: MaterialCombo,
|
||||
): Promise<{ 키: string; 판: string; 줄: MaterialCombo }> =>
|
||||
call(`/material-combos/${enc(키)}`, { method: "PUT", body: JSON.stringify({ 판, 줄 }) });
|
||||
scoped(`/material-combos/${enc(키)}`, { method: "PUT", body: JSON.stringify({ 판, 줄 }) });
|
||||
|
||||
/** 지우기 — 구조물 열이 쓰면 서버가 막고 그 열 이름들을 까닭으로 줌 */
|
||||
export const deleteMaterialCombo = (키: string, 판: string): Promise<unknown> =>
|
||||
call(`/material-combos/${enc(키)}?판=${enc(판)}`, { method: "DELETE" });
|
||||
scoped(`/material-combos/${enc(키)}?판=${enc(판)}`, { method: "DELETE" });
|
||||
|
||||
/* --- 구조물 옵션 보이기(마스터 템플릿 `구조물옵션표시.json`) — 좌측 「구조물 옵션 보이기」 줄 --- */
|
||||
export interface OptionKind {
|
||||
@@ -275,19 +284,31 @@ export const saveStructureOptions = (판: string, 표시: OptionsDoc["표시"]):
|
||||
|
||||
/** 다른 열(`from`) 구조물 도면 내용을 받는 열(`column`)로 가져옴 — 도번 · 열은 받는 쪽 그대로 */
|
||||
export const copyStructure = async (column: string, from: string): Promise<void> => {
|
||||
await call(`/structures/${enc(column)}/copy?from=${enc(from)}`, { method: "POST" });
|
||||
await scoped(`/structures/${enc(column)}/copy?from=${enc(from)}`, { method: "POST" });
|
||||
};
|
||||
|
||||
/** 다른 열(`from`) 면적산출 내용(알약 연결 포함)을 받는 열(`column`)로 가져옴 — 면적번 · 열은 그대로 */
|
||||
export const copyArea = async (column: string, from: string): Promise<void> => {
|
||||
await call(`/area/${enc(column)}/copy?from=${enc(from)}`, { method: "POST" });
|
||||
await scoped(`/area/${enc(column)}/copy?from=${enc(from)}`, { method: "POST" });
|
||||
};
|
||||
|
||||
/** 다른 열(`from`) 재료산출 내용(알약 연결 포함)을 받는 열(`column`)로 가져옴 — 재료번 · 열은 그대로 */
|
||||
export const copyMaterial = async (column: string, from: string): Promise<void> => {
|
||||
await call(`/material/${enc(column)}/copy?from=${enc(from)}`, { method: "POST" });
|
||||
await scoped(`/material/${enc(column)}/copy?from=${enc(from)}`, { method: "POST" });
|
||||
};
|
||||
|
||||
/** 회사 · 개인 층의 집계표 항목(열 하나 + 도면 · 면적 · 재료 파일 + 자재조합 줄)을 내 개인 층으로 복사 —
|
||||
* 새 SS 키로 만들고 `본뜬` 표시 · `fromOwner` = 회사 층 회사 · 개인 층 「회사/사용자」 */
|
||||
export const copyItemToPersonal = (body: {
|
||||
fromLayer: Layer;
|
||||
fromOwner: string | null;
|
||||
key: string;
|
||||
}): Promise<{ key: string }> =>
|
||||
call("/layers/personal/items/copy", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ from_layer: body.fromLayer, from_owner: body.fromOwner, key: body.key }),
|
||||
});
|
||||
|
||||
/* --- 프로젝트 층 단추 다섯 --- */
|
||||
const project = (id: string, tail: string): string => `/projects/${enc(id)}/templates/${tail}`;
|
||||
const post = (path: string, body: object = {}): Promise<unknown> =>
|
||||
|
||||
Reference in New Issue
Block a user