refactor(M02): 재료산출 시트 지움 — 종류 material · 재료번 SM · 좌측 줄 · 집계표 「재료산출」 줄 · 카드 · 전체 편집 · 복사 길 · 프로젝트 복사본 「재료」 · 고르기 모달 · 시스템 층 · fixture · 시험
- 새 프로젝트 씨앗(KINDS)에서도 빠짐 · 새 열은 구조물 도면 · 면적산출만 만듦 - storage 층(회사 · 개인 · 프로젝트) material/ 파일은 지우지 않음(읽기만 끊음) - 장부 재료번 칸은 다음 집계표 [저장] 때 빠짐 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NPJGtfXo6GMbcpiboQC4uK
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
/* =============================================================================
|
||||
* ui_template_sheet.ts
|
||||
* 엑셀처럼 도는 표 부품 — `createSheet(칸, 문서, {mode, onChange, drawingLabel, areaLabel, materialLabel, onSelect, onPick})`
|
||||
* 엑셀처럼 도는 표 부품 — `createSheet(칸, 문서, {mode, onChange, drawingLabel, areaLabel, onSelect, onPick})`
|
||||
* → `{getDoc, setDoc, recalc, selectColumn, destroy}`.
|
||||
*
|
||||
* master = 시스템 관리자 양식 고치기 — 머리 · 층 이름 · 단위 · 일위대가 ·
|
||||
* 층마다 열 더하기(「분류1 더하기」 … 층 이름 + 더하기) · 열 지우기.
|
||||
* 도면 · 면적산출 · 재료산출 줄 = `drawingLabel` · `areaLabel` · `materialLabel` 글 ·
|
||||
* 칸을 고르면 `onSelect` · `onPick` 을 주면 일위대가 · 도면 · 면적산출 · 재료산출 칸은
|
||||
* 도면 · 면적산출 줄 = `drawingLabel` · `areaLabel` 글 ·
|
||||
* 칸을 고르면 `onSelect` · `onPick` 을 주면 일위대가 · 도면 · 면적산출 칸은
|
||||
* 치지 않고 조회 후 선택.
|
||||
* `readOnly` = 볼 수만 있음 — 단추 줄 · 안내 글 숨김 · 칸 고치기 · 머리 고치기 · 열 너비 끌기 막음 ·
|
||||
* 열이 하나도 없으면 [열 더하기] 가 켜져 첫 열을 만듦(머리 글 바로 고치기).
|
||||
@@ -56,12 +56,11 @@ export interface SheetOptions {
|
||||
onChange?: (doc: SheetDoc) => void;
|
||||
/** 도면 줄 칸 글(마스터 첫 쪽 · 열 id) — 없거나 빈 글이면 「없음」 · 글이 바뀌면 `recalc()` 로 다시 그림. */
|
||||
drawingLabel?: (colId: string) => string;
|
||||
/** 면적산출 · 재료산출 줄 칸 글(번호) — `drawingLabel` 과 같음. */
|
||||
/** 면적산출 줄 칸 글(번호) — `drawingLabel` 과 같음. */
|
||||
areaLabel?: (colId: string) => string;
|
||||
materialLabel?: (colId: string) => string;
|
||||
/** 칸을 고름 — 누르기 · 방향키 · Tab. */
|
||||
onSelect?: (sel: SheetSelection) => void;
|
||||
/** 조회 후 선택 — master 일위대가 · 도면 · 면적산출 · 재료산출 칸을 두 번 누르기 · Enter · F2 로 부름.
|
||||
/** 조회 후 선택 — master 일위대가 · 도면 · 면적산출 칸을 두 번 누르기 · Enter · F2 로 부름.
|
||||
* 글을 돌려주면 일위대가 칸에 넣음 · 번호 글 줄은 부른 쪽이 가져온 뒤 `recalc()`.
|
||||
* 없으면 일위대가는 글로 고침 · 번호 글 줄은 읽기만. */
|
||||
onPick?: (sel: SheetSelection) => Promise<string | null | undefined> | void;
|
||||
@@ -90,7 +89,6 @@ export function createSheet(host: HTMLElement, input: SheetDoc, opts: SheetOptio
|
||||
sel: null,
|
||||
drawingLabel: opts.drawingLabel,
|
||||
areaLabel: opts.areaLabel,
|
||||
materialLabel: opts.materialLabel,
|
||||
pick: !!opts.onPick,
|
||||
headLocked: !!opts.lockHead,
|
||||
combo: !!opts.combo,
|
||||
|
||||
@@ -22,16 +22,15 @@ export const KEY_UNIT = "s:unit";
|
||||
export const KEY_PRICE = "s:price";
|
||||
export const KEY_DRAWING = "s:drawing";
|
||||
export const KEY_AREA = "s:area";
|
||||
export const KEY_MATERIAL = "s:material";
|
||||
/** 마스터 전용 줄(첫 쪽 단위 줄 아래 차례) — 도면 · 면적산출 · 재료산출 줄은 손으로 못 침(번호 글). */
|
||||
export const MASTER_ROWS = [KEY_PRICE, KEY_DRAWING, KEY_AREA, KEY_MATERIAL] as const;
|
||||
/** 마스터 전용 줄(첫 쪽 단위 줄 아래 차례) — 도면 · 면적산출 줄은 손으로 못 침(번호 글). */
|
||||
export const MASTER_ROWS = [KEY_PRICE, KEY_DRAWING, KEY_AREA] as const;
|
||||
export type MasterRowKey = (typeof MASTER_ROWS)[number];
|
||||
/** 번호 글 줄 — 부른 쪽이 준 글(`refLabel`)만 보임. */
|
||||
export const REF_ROWS: readonly string[] = [KEY_DRAWING, KEY_AREA, KEY_MATERIAL];
|
||||
export const REF_ROWS: readonly string[] = [KEY_DRAWING, KEY_AREA];
|
||||
/** 조회 후 선택 줄 — `onPick` 을 주면 이 줄 칸은 치지 않고 고름. */
|
||||
export const PICK_ROWS: readonly string[] = MASTER_ROWS;
|
||||
|
||||
/** 글 열(NO · 측점 · 비고 같은 꼴=글)의 일위대가 · 도면 · 면적산출 · 재료산출 칸 — 빈칸 · 잠김. */
|
||||
/** 글 열(NO · 측점 · 비고 같은 꼴=글)의 일위대가 · 도면 · 면적산출 칸 — 빈칸 · 잠김. */
|
||||
export const isBlankPick = (key: string, col: SheetColumn): boolean =>
|
||||
PICK_ROWS.includes(key) && col.꼴 === "글";
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
* 표 그리기 — 문서 + 풀이 결과 → 쪽마다 `<table>`(머리 층 · 단위 줄 · 본문 · 합계 줄).
|
||||
*
|
||||
* 칸마다 `data-r`(줄 열쇠) · `data-c`(열 id) — 고치기 · 키보드는 격자(`ui_template_sheet.ts`)가 위임으로 받음.
|
||||
* 줄 열쇠 — 본문 `d:<줄id>` · 합계 `t:<합계id>` · 마스터 줄 `s:unit|price|drawing|area|material`.
|
||||
* master = 본문 위에 열마다 일위대가 · 도면 · 면적산출 · 재료산출 줄 · project = 쪽줄마다 쪽을 나눔(쪽마다 머리 · 합계는 마지막 쪽).
|
||||
* 줄 열쇠 — 본문 `d:<줄id>` · 합계 `t:<합계id>` · 마스터 줄 `s:unit|price|drawing|area`.
|
||||
* master = 본문 위에 열마다 일위대가 · 도면 · 면적산출 줄 · project = 쪽줄마다 쪽을 나눔(쪽마다 머리 · 합계는 마지막 쪽).
|
||||
* 머리 층 줄 머리 칸은 `data-layer`(층 차례) — master 에서 층 이름을 고침.
|
||||
* ========================================================================== */
|
||||
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
isBlankPick,
|
||||
isCalcColumn,
|
||||
KEY_AREA,
|
||||
KEY_MATERIAL,
|
||||
KEY_UNIT,
|
||||
MASTER_ROWS,
|
||||
type MasterRowKey,
|
||||
@@ -39,10 +38,9 @@ export interface RenderState {
|
||||
mode: SheetMode;
|
||||
result: SheetResult;
|
||||
sel: { r: string; c: string } | null;
|
||||
/** 도면 · 면적산출 · 재료산출 줄 칸 글(열 id) — 없거나 빈 글이면 「없음」. */
|
||||
/** 도면 · 면적산출 줄 칸 글(열 id) — 없거나 빈 글이면 「없음」. */
|
||||
drawingLabel?: (colId: string) => string;
|
||||
areaLabel?: (colId: string) => string;
|
||||
materialLabel?: (colId: string) => string;
|
||||
/** 조회 후 선택 줄(`PICK_ROWS`)을 고름으로 받나 — 칸 겉모양만. */
|
||||
pick?: boolean;
|
||||
/** 머리 · 층 이름을 못 고침(`lockHead`) — 칸 겉모양만. */
|
||||
@@ -53,13 +51,9 @@ export interface RenderState {
|
||||
headEditable?: boolean;
|
||||
}
|
||||
|
||||
/** 도면 · 면적산출 · 재료산출 줄 칸 글. */
|
||||
/** 도면 · 면적산출 줄 칸 글. */
|
||||
export const refText = (state: RenderState, key: string, colId: string): string =>
|
||||
(key === KEY_AREA
|
||||
? state.areaLabel
|
||||
: key === KEY_MATERIAL
|
||||
? state.materialLabel
|
||||
: state.drawingLabel)?.(colId)?.trim() || st("Drawing_None");
|
||||
(key === KEY_AREA ? state.areaLabel : state.drawingLabel)?.(colId)?.trim() || st("Drawing_None");
|
||||
|
||||
/** 열 폭 — 저장 폭(없으면 기본) · 머리 글이 안 잘리는 최소 폭보다 좁지 않게. */
|
||||
const columnWidth = (doc: SheetDoc, col: SheetColumn, mins: Map<string, number>): number =>
|
||||
@@ -68,7 +62,7 @@ const columnWidth = (doc: SheetDoc, col: SheetColumn, mins: Map<string, number>)
|
||||
mins.get(col.id) ?? 0,
|
||||
);
|
||||
|
||||
/** 구조물 조합 — 일위대가 · 도면 · 면적산출 · 재료산출 줄 글(키 · 번호)이 줄바꿈 없이 들게 최소 폭을 넓힘
|
||||
/** 구조물 조합 — 일위대가 · 도면 · 면적산출 줄 글(키 · 번호)이 줄바꿈 없이 들게 최소 폭을 넓힘
|
||||
* (`.ui-sheet__meta td` 글꼴과 같게 잼). */
|
||||
function fitMeta(state: RenderState, cols: SheetColumn[], mins: Map<string, number>): void {
|
||||
const rem = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
|
||||
@@ -115,7 +109,7 @@ export function renderSheet(state: RenderState): HTMLElement {
|
||||
const mins = headMinWidths(cols, depth, font);
|
||||
if (state.combo) fitMeta(state, cols, mins);
|
||||
const widthDoc = state.combo ? { ...doc, 보기: { ...doc.보기, 열너비: {} } } : doc;
|
||||
// 줄 머리 칸 폭 — 층 이름 · 단위 · 일위대가 · 도면 · 면적산출 · 재료산출 · 합계 이름이 안 잘리게
|
||||
// 줄 머리 칸 폭 — 층 이름 · 단위 · 일위대가 · 도면 · 면적산출 · 합계 이름이 안 잘리게
|
||||
const GUTTER = Math.min(
|
||||
GUTTER_MAX,
|
||||
Math.max(
|
||||
@@ -126,7 +120,6 @@ export function renderSheet(state: RenderState): HTMLElement {
|
||||
st("Row_Unit_Price"),
|
||||
st("Row_Drawing"),
|
||||
st("Row_Area"),
|
||||
st("Row_Material"),
|
||||
...(doc.합계줄 ?? []).map((t) => t.이름),
|
||||
].map((label) => Math.ceil(textWidth(label, font)) + 16),
|
||||
),
|
||||
@@ -193,7 +186,6 @@ export function renderSheet(state: RenderState): HTMLElement {
|
||||
"s:price": "Row_Unit_Price",
|
||||
"s:drawing": "Row_Drawing",
|
||||
"s:area": "Row_Area",
|
||||
"s:material": "Row_Material",
|
||||
} as const
|
||||
)[key];
|
||||
const tr = el("tr", { className: "ui-sheet__meta", children: [gutter("th", st(label))] });
|
||||
|
||||
@@ -13,7 +13,6 @@ const TEXT = {
|
||||
Row_Unit_Price: ["일위대가", "Unit price"],
|
||||
Row_Drawing: ["도면", "Drawing"],
|
||||
Row_Area: ["면적산출", "Area"],
|
||||
Row_Material: ["재료산출", "Material"],
|
||||
Add_Suffix: [" 추가", " +"],
|
||||
New_Prefix: ["새 ", "New "],
|
||||
Drawing_None: ["없음", "None"],
|
||||
|
||||
@@ -80,7 +80,7 @@ export interface SheetDoc {
|
||||
보기?: SheetView;
|
||||
}
|
||||
|
||||
/** 고른 칸 — `row` = 줄 열쇠(`d:<줄id>` · `t:<합계id>` · `s:unit|price|drawing|area|material`) ·
|
||||
/** 고른 칸 — `row` = 줄 열쇠(`d:<줄id>` · `t:<합계id>` · `s:unit|price|drawing|area`) ·
|
||||
* `col` = 열 차례(0부터 · 없으면 -1) · `colId` = 열 id(없으면 null). */
|
||||
export interface SheetSelection {
|
||||
row: string;
|
||||
|
||||
Reference in New Issue
Block a user