feat(717-2a): M02 왼쪽 맨 위 「단가산출」 칸 — 층 단추 따로(기본 개인) · 폴더 나무 · 목록표 · 상세 자리 · 대시보드 줄
- 새 UI_Side_Sangeun.ts — 서고 칸(716-4) kind sangeun · 목록표 고름 sangeunList - 새 Sangeun_View.ts — 이름 · 단위 · 바탕 · 덮개 · 더한 줄 · 뺀 줄 · 열린 입력 요약 + 상세 자리표(717-2b 가 갈음) - UI_Main 종류 sangeun 갈래 · 목록표 조건에 sangeun · Library_List 열 표(단가산출 = 바탕 · 고친 줄 · 쓰는 곳) · sangeunBlank(단위 식 · 바탕 없음) - UI_Page 단가산출 층 상태 sk · UI_Side 맨 위 칸 · reveal 「단가산출」 · Layer open 「단가산출」 · Api Kind sangeun - m_settings_nav 대시보드 마스터 템플릿 묶음 「단가산출」 줄(?open=단가산출) · locale_m2 키 - 낡은 글 대조 시험 넷 고침(197_1 · b01_settings_cards · m02_layer_screen · m02_precombo_scope) — 대시보드 줄 하나 늘고 OPENS · reveal · 목록 열 표 · 칸 차례가 바뀜 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
/* =============================================================================
|
||||
* M02_MasterTemplete_Library_List.ts
|
||||
* 일위대가 사전조합 서고 목록표(51-4) — 좌측 사전조합 층 단추를 누르면 상세 칸에 뜸.
|
||||
* 표 = 고름 · 키 · 구분 · 상세구분(51-12) · 이름 · 단위 · 기준 금액(서버 1 단위 계) · 고친 날 · 줄 누름 = 그 문서 상세.
|
||||
* 서고 목록표(51-4 · 717-2a) — 좌측 일위대가 · 단가산출 층 단추를 누르면 상세 칸에 뜸.
|
||||
* 표 = 고름 · 키 · 구분 · 상세구분(51-12) · 이름 · 단위 · 기준 금액(서버 1 단위 계) · 고친 날 · 줄 누름 = 그 문서 상세 ·
|
||||
* 단가산출 = 구분 둘 대신 바탕(M01 로직 · 없으면 「바탕 없음」) · 고친 줄 수 · 쓰는 곳 수(서버 `summary`).
|
||||
* 머리 [생성] · [복사](고른 줄) · [삭제](고른 줄 · 쓰는 곳 있으면 서버 409 까닭 그대로).
|
||||
* 꼴 = M01 단가산출 로직 목록 — 찾기 줄(`buildHeadFilters`) · 쪽(`buildPager`) · 표(`m01-master__grid`) 를 M01 에서 import.
|
||||
* ========================================================================== */
|
||||
@@ -28,10 +29,10 @@ import {
|
||||
saveTemplate,
|
||||
type Layer,
|
||||
type LibraryBody,
|
||||
type LibraryKind,
|
||||
type TemplateInfo,
|
||||
} from "./M02_MasterTemplete_Api_Fetch";
|
||||
import { tc } from "./M02_MasterTemplete_Labor_Text";
|
||||
import type { PrecomboKind } from "./M02_MasterTemplete_UI_Side_Precombo";
|
||||
|
||||
/** 목록 줄 — 서버가 문서 `이름`(제목) · 단위 · 1 단위 기준 계를 실어 보냄 */
|
||||
type Row = TemplateInfo & {
|
||||
@@ -40,13 +41,16 @@ type Row = TemplateInfo & {
|
||||
기준금액?: number | null;
|
||||
구분?: string | null;
|
||||
상세구분?: string | null;
|
||||
바탕?: string | null;
|
||||
고친줄수?: number;
|
||||
쓰는곳수?: number;
|
||||
};
|
||||
|
||||
export interface LibraryListOptions {
|
||||
layer: Layer;
|
||||
/** 그 층 주인(134-3 · 사전조합 층 · null = 자기 층) */
|
||||
owner: string | null;
|
||||
kind: PrecomboKind;
|
||||
kind: LibraryKind;
|
||||
canEdit: boolean;
|
||||
/** 줄 누름 · 생성 · 복사 뒤 — 그 문서 상세 */
|
||||
open: (key: string, label: string) => void;
|
||||
@@ -60,6 +64,36 @@ const money = (v: number | null | undefined): string =>
|
||||
v == null ? "" : v.toLocaleString("ko-KR", { maximumFractionDigits: 2 });
|
||||
export const libraryLabel = (row: Row): string => (row.제목 ? `${row.이름} ${row.제목}` : row.이름);
|
||||
|
||||
/** 새 단가산출 몸(717-2a) — 바탕 없음 · 빈 더한줄 · 단위 「식」(서버 필수 · 상세에서 고침 · 717-2b) */
|
||||
export const sangeunBlank = (name: string): Record<string, unknown> => ({
|
||||
이름: name,
|
||||
단위: "식",
|
||||
바탕: null,
|
||||
더한줄: [],
|
||||
});
|
||||
/** 표 열 — 머리 글 · 줄 값(일위대가 = 구분 둘 · 단가산출 = 바탕 · 고친 줄 · 쓰는 곳) */
|
||||
const COLUMNS: Record<LibraryKind, () => [string, (row: Row) => string][]> = {
|
||||
precombo: () => [
|
||||
[tc("Lib_Key"), (r) => r.이름],
|
||||
[tc("Sub"), (r) => r.구분 || tc("Lib_Unsorted")], // 빈 구분 = 미분류(149-2 · 나무와 같은 말)
|
||||
[tc("Detail"), (r) => r.상세구분 ?? ""],
|
||||
[tc("Lib_Name"), (r) => r.제목 ?? ""],
|
||||
[tc("Lib_Unit"), (r) => r.단위 ?? ""],
|
||||
[tc("Lib_Base"), (r) => money(r.기준금액)],
|
||||
[tc("Lib_Date"), (r) => r.수정일],
|
||||
],
|
||||
sangeun: () => [
|
||||
[tc("Lib_Key"), (r) => r.이름],
|
||||
[tc("Lib_Name"), (r) => r.제목 ?? ""],
|
||||
[tc("Lib_Unit"), (r) => r.단위 ?? ""],
|
||||
[L("M02_SangeunBase"), (r) => r.바탕 || L("M02_SangeunNoBase")],
|
||||
[L("M02_SangeunEdited"), (r) => String(r.고친줄수 ?? 0)],
|
||||
[L("M02_SangeunUsers"), (r) => String(r.쓰는곳수 ?? 0)],
|
||||
[tc("Lib_Base"), (r) => money(r.기준금액)],
|
||||
[tc("Lib_Date"), (r) => r.수정일],
|
||||
],
|
||||
};
|
||||
|
||||
/** 이름 창(생성 · 복사 · 사전조합 나무 폴더 메뉴 149-1) — [생성] = `onOk` 성공하면 닫힘 */
|
||||
export const nameDialog = (
|
||||
title: string,
|
||||
@@ -101,6 +135,7 @@ export function mountLibraryList(
|
||||
tools: HTMLElement,
|
||||
opt: LibraryListOptions,
|
||||
): { getDoc: () => null; destroy: () => void } {
|
||||
const columns = COLUMNS[opt.kind]();
|
||||
let rows: Row[] = [];
|
||||
let picked: string | null = null;
|
||||
let page = 1;
|
||||
@@ -144,15 +179,9 @@ export function mountLibraryList(
|
||||
attrs: { "data-lib-key": row.이름 },
|
||||
children: [
|
||||
pick,
|
||||
...[
|
||||
row.이름,
|
||||
row.구분 || tc("Lib_Unsorted"), // 빈 구분 = 미분류(149-2 · 나무와 같은 말)
|
||||
row.상세구분 ?? "",
|
||||
row.제목 ?? "",
|
||||
row.단위 ?? "",
|
||||
money(row.기준금액),
|
||||
row.수정일,
|
||||
].map((v) => el("td", { text: v, attrs: { title: v } })),
|
||||
...columns
|
||||
.map(([, value]) => value(row))
|
||||
.map((v) => el("td", { text: v, attrs: { title: v } })),
|
||||
],
|
||||
});
|
||||
tr.addEventListener("click", () => opt.open(row.이름, libraryLabel(row)));
|
||||
@@ -160,7 +189,12 @@ export function mountLibraryList(
|
||||
})
|
||||
: [
|
||||
el("tr", {
|
||||
children: [el("td", { text: L("M02_NoTemplates"), attrs: { colspan: "8" } })],
|
||||
children: [
|
||||
el("td", {
|
||||
text: L("M02_NoTemplates"),
|
||||
attrs: { colspan: String(columns.length + 1) },
|
||||
}),
|
||||
],
|
||||
}),
|
||||
]),
|
||||
);
|
||||
@@ -191,7 +225,10 @@ export function mountLibraryList(
|
||||
/** 사전조합 = 이름 · 구분 · 상세구분 빈 값(미분류 · 134-5 · 상세에서 고름) · 빈 묶음 */
|
||||
btnNew.addEventListener("click", () => {
|
||||
nameDialog(L("M02_NewTitle"), "", async (name) => {
|
||||
const 문서 = { 이름: name, 구분: "", 상세구분: "", 단위: null, 담은로직: [] };
|
||||
const 문서 =
|
||||
opt.kind === "sangeun"
|
||||
? sangeunBlank(name)
|
||||
: { 이름: name, 구분: "", 상세구분: "", 단위: null, 담은로직: [] };
|
||||
await create({ 문서 }, name);
|
||||
});
|
||||
});
|
||||
@@ -244,16 +281,7 @@ export function mountLibraryList(
|
||||
page = 1;
|
||||
draw();
|
||||
});
|
||||
const heads = [
|
||||
"",
|
||||
"Lib_Key",
|
||||
"Sub",
|
||||
"Detail",
|
||||
"Lib_Name",
|
||||
"Lib_Unit",
|
||||
"Lib_Base",
|
||||
"Lib_Date",
|
||||
] as const;
|
||||
const heads = ["", ...columns.map(([head]) => head)];
|
||||
const gridBox = el("div", {
|
||||
className: "ui-table-wrap m01-master__grid-wrap",
|
||||
attrs: { "data-lib-list": opt.kind },
|
||||
@@ -262,9 +290,7 @@ export function mountLibraryList(
|
||||
className: "ui-table m01-master__grid",
|
||||
children: [
|
||||
el("thead", {
|
||||
children: [
|
||||
el("tr", { children: heads.map((h) => el("th", { text: h ? tc(h) : "" })) }),
|
||||
],
|
||||
children: [el("tr", { children: heads.map((h) => el("th", { text: h })) })],
|
||||
}),
|
||||
body,
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user