- 줄 쌓기 기계 줄 이름 단추 = 기계 창(왼쪽 찾기 · 오른쪽 공통 기계 양식 읽기 전용 · 지금 줄 = 사본 값 · 새 값 표시) - [이 기계로 바꾸기] = repick 그대로(823-1 · 되돌리기) · M01 목록도 시간당(machine-rows) - [고쳐 쓰기](개인 층 SK) = 서버 확인(쓰기 없음) → 문서 칸 내기계초안 · 줄 입력 개인 EQP초안-N - [저장] 한 번에 서버가 초안 만들기 · 고침 → 키 바꿈 → 사본 박기 · 실패 = 만든 파일 지움 · 고친 줄 되돌림 - 미리 셈 = 초안을 그 요청 안만 셈 색인에 얹음 · 브라우저 = 셈 꼴 값을 캐시에 - 회사 · 마스터 층 · M01 기초 = 조회 · 바꾸기만(까닭 한 줄) · 옵션 가로 곁 [조회] - 걷음: 줄 옆 「복사해 내 기계로」(line_stack_mine.ts) · 찾기 창 [새 기계 만들기] · 개인관리 › 기계 만들기 · 고치기(보기 · 쓰는 곳 · 지우기만) - 내 기계 쓰는 곳 = 수식 길 사본도 셈 - 시험 test_827_1_machine_window(8) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
77 lines
3.4 KiB
TypeScript
77 lines
3.4 KiB
TypeScript
/* =============================================================================
|
|
* common_util_line_stack_draft.ts
|
|
* 줄 쌓기 기계 창 초안(PLAN 827-1) — 문서 칸 `내기계초안` 다루기(화면 · fetch 없음).
|
|
* 초안 하나 = {표지 「EQP초안-N」, 키?(고칠 내 기계), 본뜬?(바탕 키), 줄(내 기계 몸), 시간당?(목록 금액 · 식 키)}
|
|
* 줄 입력 기계='개인 EQP초안-N' 이 가리킴 · 단가산출 [저장] 때 서버가 만들기 · 고침 · 키 바꿈
|
|
* (짝 = `M02_MasterTemplete/M02_MyMachine_Draft.py` — 칸 이름 · 표지 꼴)
|
|
* ========================================================================== */
|
|
|
|
import { varId, type FormulaDoc } from "./common_util_formula_doc";
|
|
import { repick, type Picked } from "./common_util_line_stack_pick";
|
|
|
|
export const DRAFT_FIELD = "내기계초안";
|
|
const TAG = /EQP초안-\d+/g;
|
|
|
|
export interface DraftItem {
|
|
표지: string;
|
|
키?: string;
|
|
본뜬?: string;
|
|
줄: { 이름: string; 규격: string; 방식: string; 값?: Record<string, unknown>; 시간당?: object };
|
|
시간당?: { ok: boolean; 계?: number; 로직?: string | null };
|
|
}
|
|
|
|
type Holder = FormulaDoc & { [DRAFT_FIELD]?: DraftItem[] };
|
|
|
|
export const draftsOf = (doc: FormulaDoc | null | undefined): DraftItem[] =>
|
|
((doc as Holder | null | undefined)?.[DRAFT_FIELD] ?? []).filter(Boolean);
|
|
|
|
/** 기계 입력 글(따옴표 뗌)이 초안인지 */
|
|
export const isDraftNo = (no: string | null | undefined): boolean =>
|
|
/^개인 EQP초안-\d+$/.test(no ?? "");
|
|
|
|
let last = Date.now() % 1_000_000_000;
|
|
/** 새 표지 — 세션 안 겹치지 않게(캐시에 남은 옛 초안 값과 안 섞임) */
|
|
export const newTag = (): string => `EQP초안-${++last}`;
|
|
|
|
/** 문서가 안 쓰는 초안은 뺌 · 다 빠지면 칸 지움 */
|
|
export function pruneDrafts(doc: FormulaDoc): void {
|
|
const box = doc as Holder;
|
|
if (!box[DRAFT_FIELD]) return;
|
|
const { [DRAFT_FIELD]: list, ...rest } = box;
|
|
const used = new Set(JSON.stringify(rest).match(TAG) ?? []);
|
|
const keep = (list ?? []).filter((d) => used.has(d.표지));
|
|
if (keep.length) box[DRAFT_FIELD] = keep;
|
|
else delete box[DRAFT_FIELD];
|
|
}
|
|
|
|
/** 초안을 줄 `i`(단가 기호 `id`)에 끼움 — 내 기계 고침이면 이 문서에서 그 기계를 가리키던 줄 모두 초안으로 */
|
|
export function putDraft(doc: FormulaDoc, i: number, id: string, item: DraftItem, p: Picked): void {
|
|
const arg = p.입력?.기계 ?? "";
|
|
if (item.키) {
|
|
const was = `'개인 ${item.키}'`;
|
|
for (const v of doc.변수 ?? []) {
|
|
const l = v.연결;
|
|
if (l?.갈래 === "단가산출" && l.입력?.기계 === was) {
|
|
l.입력 = { ...l.입력, 기계: arg };
|
|
l.키 = p.키;
|
|
}
|
|
}
|
|
}
|
|
repick(doc, i, id, "기계", p);
|
|
const box = doc as Holder;
|
|
box[DRAFT_FIELD] = [...draftsOf(doc).filter((d) => d.표지 !== item.표지), item];
|
|
pruneDrafts(doc);
|
|
}
|
|
|
|
/** 기계 줄 연결 → 지금 기계 입력 글(따옴표 뗌) · 옵션 기호(`S_굴착기`)면 그 옵션 값 · 없음 = null */
|
|
export function machineNow(
|
|
doc: FormulaDoc,
|
|
link: { 갈래?: string; 입력?: Record<string, string> },
|
|
): string | null {
|
|
const arg = link.갈래 === "단가산출" ? String(link.입력?.기계 ?? "").trim() : "";
|
|
if (!arg) return null;
|
|
if (/^'.*'$/.test(arg)) return arg.slice(1, -1);
|
|
const val = (doc.변수 ?? []).find((x) => varId(x) === arg)?.연결?.값;
|
|
return val === undefined || val === null || String(val) === "" ? null : String(val);
|
|
}
|