- 좌측 판(Hopyo_Side): 일위대가 사전조합 아래 · 구조물 조합 층 · 쓰기 권한 없으면 [엑셀 올리기] 꺼짐 · 숨은 file 입력 .xls,.xlsx · 파일 줄 → 본 화면
- 본 화면(Hopyo_View): 파일 · 시트 · 호표 수 · 검산 · 맞춤 n/m · 호표 표 + 찾기 · [지우기] / 호표 줄 표(갈래 · 품명 · 규격 · 수량 · 단위 · 엑셀 단가 · 맞춤 · 대상 · 입력값 · 환산) · [고르기](후보 5 + 다른 로직 · 자재 찾기 → 미리 채움) · [확정] · [빼기] · [되살림] · [같음 모두 확정] · 빠진 줄 · [사전조합 만들기] → 값 비교 · 다시 씀이면 [새로 만들기](확인 뒤 덮음)
- [로직 추가](Hopyo_Pick · Labor_Pick 늦은 덧줄 `more` · 종류 고르기): 문서 층 · 위 층 호표 줄(맞춤 n/m) → 고르면 서버가 문서 층 사전조합을 만들고 참조 줄(별칭 = 호표 품명) · 빠진 줄 알림 · 프로젝트 층 없음
- Labor_Detail: 제자리 넷 줄(가져오기 · pick 별칭 받음 · withHopyo) · 693 줄 그대로
- 서버: GET /layers/{층}/hopyo-picks(이 층 · 위 층 · 이 층 기억)
- 색 = 공용 토큰(밝음 · 어두움) · 시험 test_m02_hopyo_screen 4 + hopyo-picks 1 · typecheck 0
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ji4nuyLVHcxrXWHTdb5nRD
59 lines
3.0 KiB
TypeScript
59 lines
3.0 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_Hopyo_Pick.ts
|
|
* [로직 추가] 창의 「실무 호표」 줄(PLAN 324-4) — 일위대가 문서 층 · 위 층 실무자료의 호표마다 한 줄(맞춤 n/m) ·
|
|
* 고르면 서버가 그 호표를 문서 층 사전조합으로 만들고(`/hopyo-build` · 있던 것은 다시 씀) `lib.pick` 으로
|
|
* 참조 줄(별칭 = 호표 품명) · 빠진 줄이 있으면 알림. 프로젝트 층엔 없음.
|
|
* ========================================================================== */
|
|
|
|
import { showToast } from "@ui/ui_template_elements";
|
|
import { buildHopyo, listHopyoPicks, type HopyoPickRow } from "./M02_MasterTemplete_Hopyo_Api";
|
|
import type { LibraryPick, PickExtra } from "./M02_MasterTemplete_Labor_Pick";
|
|
import { tc } from "./M02_MasterTemplete_Labor_Text";
|
|
|
|
export const HOPYO_KIND = "hopyo";
|
|
const LAYER_TEXT: Record<string, string> = { system: "마스터", company: "회사", personal: "개인" };
|
|
const ALIAS_MAX = 40; // 별칭 상한(44-6 · 서버 `ALIAS_MAX`)
|
|
|
|
/** 서고 고르기에 「실무 호표」 덧줄 · 종류 고르기(단가산출 · 사전조합 · 실무 호표)를 붙임 */
|
|
export function withHopyo(lib: LibraryPick): LibraryPick {
|
|
if (lib.layer === "project") return lib;
|
|
const scope = { layer: lib.layer, owner: lib.owner };
|
|
return {
|
|
...lib,
|
|
kindFilter: lib.kindFilter ?? [
|
|
{ value: "logic", text: tc("Kind_Logic") },
|
|
{ value: "precombo", text: tc("Kind_Combo") },
|
|
{ value: HOPYO_KIND, text: "실무 호표" },
|
|
],
|
|
more: async () => (await listHopyoPicks(scope)).map((row) => hopyoExtra(row, lib)),
|
|
};
|
|
}
|
|
|
|
/** 실무 호표 한 줄 */
|
|
export function hopyoExtra(row: HopyoPickRow, lib: LibraryPick): PickExtra {
|
|
return {
|
|
kind: HOPYO_KIND,
|
|
key: `${row.층}|${row.주인 ?? ""}|${row.키}|${row.번}`,
|
|
tag: "실무 호표",
|
|
name: [row.이름, row.규격].filter(Boolean).join(" "),
|
|
sub: `${row.파일} · 제${row.번}호표 · ${LAYER_TEXT[row.층] ?? row.층}`,
|
|
unit: `${row.단위} · 맞춤 ${row.맞춤[0]}/${row.맞춤[1]}`,
|
|
onPick: () => void pickHopyo(row, lib),
|
|
};
|
|
}
|
|
|
|
/** 고름 — 서버가 사전조합을 만들고(다시 씀) 참조 줄을 더함 */
|
|
export async function pickHopyo(row: HopyoPickRow, lib: LibraryPick): Promise<void> {
|
|
try {
|
|
const from = { 층: row.층, 주인: row.주인, 키: row.키, 번: row.번 };
|
|
const got = await buildHopyo({ layer: lib.layer, owner: lib.owner }, from);
|
|
const miss = got.빠진줄.length;
|
|
const head = `「${row.이름}」 → 사전조합 ${got.참조.키}${got.다시씀 ? "(있던 것)" : ""}`;
|
|
if (miss) showToast(`${head} · 빠진 줄 ${miss} — 실무자료 화면에서 맞춤`, "warning", 6000);
|
|
else showToast(head, "success");
|
|
lib.pick(got.참조, got.이름, row.이름.slice(0, ALIAS_MAX).trim() || null);
|
|
} catch (error) {
|
|
showToast(error instanceof Error ? error.message : String(error), "error");
|
|
}
|
|
}
|