- 수량 칸(요구 701-1) = 늘 식 글 칸(Q_특별인부) + 출처 꼬리표(표 = 표 고르기) · 눌러도 안 바뀜 · 표 값 기호에 수 = 그 값만(직접 입력) · 꼬리표 한 곳(sourceTag) - 글꼴(701-2) = 줄 쌓기 화면이 정함(14px · M02 가 부모 16px 을 받던 것) - M02 머리(701-3) = [초기화] 와 [되돌림] 뜻 다름 → [초기화] 이름 「M01 값으로」 · [단가 갱신][재생성] = 보기 고르기 옆 머리 칸(수식 보기만) - 일위대가 단가산출 줄 모달(701-5) = 페이지 머리와 같음(보기 고르기 · [단가 갱신] · [재생성] · [저장]) - 일위대가 로직 줄 모달(701-4 · 5) = 옛 [옵션] · [단가산출로도 저장] · [항목 추가] · [율 줄 추가] 걷음 · 보기 고르기 없이 상세만 + 안내(온 단가산출) · 줄 문서 키 SK-000000 이 수식 문서를 읽어 404 · 「못 읽음」 이던 것 고침 - 시험: test_804_7 낡은 소스 기대(꼬리표 조건 글) 고침 + 808-1 · test_806_1 808-1 모달 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
107 lines
4.4 KiB
TypeScript
107 lines
4.4 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_Sangeun_Tabs.ts
|
|
* M02 단가산출(SK) 상세 보기 고르기(PLAN 799-2 · 804-2 · 804-6 · 요구 686-1) — 수식(첫 탭 · 줄 쌓기) · 단가산출 상세.
|
|
* 수식 = 공용 줄 쌓기 화면(`A00_Common/line_stack_screen.ts` · M01 과 같은 꼴) — 길 앞머리만 M02 사본 길
|
|
* (`/m02/layers/{층}/sangeun/{키}/doc` · 802-4a) · 층 쓰기 권한 없으면 읽기만
|
|
* 저장(804-8 · `page` 있음 = 단가산출 화면) = 페이지 [저장] · [되돌림] 한 번에 — 탭 위 저장 단추 없음(M01 과 같음)
|
|
* 옛 수식 문서 탭(802-4b-2)은 804-6 에 걷음 · 단가산출 상세 = 상세가 쥔 `editor`(수식일 때 숨김)
|
|
* 저장 안 한 SK(일위대가 줄 모달 · 새 SK) = 「저장한 단가산출만」 글
|
|
* [단가 갱신] · [재생성](808-1 · 요구 701-3) = `tools` — 보기 고르기 옆 머리 줄(수식 보기일 때만)
|
|
* ========================================================================== */
|
|
|
|
import { createSegment } from "@ui/ui_template_segment";
|
|
import { createStackScreen } from "../A00_Common/line_stack_screen";
|
|
import { el } from "@ui/ui_template_elements";
|
|
import { tl } from "../M01_MasterData/M01_MasterData_UI_LogicLab_Text";
|
|
import type { Layer } from "./M02_MasterTemplete_Api_Fetch";
|
|
|
|
type View = "stack" | "ho";
|
|
|
|
export interface SkEquationOptions {
|
|
scope: { layer: Layer; owner: string | null };
|
|
edit: boolean;
|
|
/** 수식 저장 · [단가 갱신] · [재생성] 뒤 그 SK 새 판 */
|
|
onSaved: (version: string) => void;
|
|
/** 페이지가 저장 · 되돌림을 맡음(804-8) — 수식 고침 있음이 바뀔 때 부름 */
|
|
page?: () => void;
|
|
}
|
|
|
|
/** SK 수식 길 — 꼬리 물음(`/table?key=…`)에 주인 물음을 이어 붙임 */
|
|
export function skDocPath(scope: SkEquationOptions["scope"], key: string, path: string): string {
|
|
const [tail, query] = path.split("?");
|
|
const ask = [query, scope.owner ? `owner=${encodeURIComponent(scope.owner)}` : ""]
|
|
.filter(Boolean)
|
|
.join("&");
|
|
const at = `/m02/layers/${scope.layer}/sangeun/${encodeURIComponent(key)}/doc${tail}`;
|
|
return ask ? `${at}?${ask}` : at;
|
|
}
|
|
|
|
/** 보기 고르기 · 수식 그릇 — `editor` = 단가산출 상세 그릇(수식일 때 숨김) */
|
|
export function createSangeunTabs(
|
|
editor: HTMLElement,
|
|
opt: SkEquationOptions,
|
|
): {
|
|
picker: HTMLElement;
|
|
/** 수식 화면 단추([단가 갱신] · [재생성]) — 보기 고르기 옆(머리 줄) */
|
|
tools: HTMLElement;
|
|
host: HTMLElement;
|
|
/** 저장한 SK 키(빈 키 = 저장 전) */
|
|
draw: (key: string) => void;
|
|
canLeave: () => Promise<boolean>;
|
|
dirty: () => boolean;
|
|
save: () => Promise<boolean>;
|
|
discard: () => Promise<void>;
|
|
} {
|
|
const tools = el("span", { className: "m02-sk__tools", attrs: { "data-sk-tools": "" } }); // [단가 갱신] · [재생성](808-1)
|
|
const stack = createStackScreen({
|
|
base: "",
|
|
admin: opt.edit,
|
|
cache: "m02_sk_doc_drafts",
|
|
copy: { route: (k, p) => skDocPath(opt.scope, k, p), onSaved: opt.onSaved },
|
|
scope: opt.scope, // 804-4 다른 단가산출 · 일위대가 복사
|
|
page: opt.page,
|
|
tools,
|
|
});
|
|
let key = "";
|
|
let view: View = "stack";
|
|
const show = (v: View): void => {
|
|
view = v;
|
|
stack.root.hidden = tools.hidden = v !== "stack";
|
|
editor.hidden = v !== "ho";
|
|
if (!editor.hidden) editor.dataset.view = v;
|
|
};
|
|
const picker = createSegment({
|
|
options: [
|
|
{ value: "stack", label: tl("View_Equation") },
|
|
{ value: "ho", label: tl("Ho_Title") },
|
|
],
|
|
value: "stack",
|
|
size: 32,
|
|
ariaLabel: tl("View_Label"),
|
|
onChange: (v) => {
|
|
show(v as View);
|
|
if (v === "stack") stack.draw(key, true);
|
|
},
|
|
});
|
|
picker.root.dataset.skViews = "";
|
|
show("stack");
|
|
return {
|
|
picker: picker.root,
|
|
tools,
|
|
host: el("div", { className: "m02-sk__views", children: [stack.root] }),
|
|
draw: (k: string) => {
|
|
key = k;
|
|
// 문서 없는 줄(일위대가 로직 줄 모달 등 · 페이지 아님) = 단가산출 상세부터(808-1 · 수식은 문서가 있어야)
|
|
if (!k && !opt.page && view === "stack") {
|
|
picker.set("ho");
|
|
return show("ho");
|
|
}
|
|
if (view === "stack") stack.draw(k);
|
|
},
|
|
canLeave: () => stack.canLeave(),
|
|
dirty: () => stack.dirty(),
|
|
save: () => stack.save(),
|
|
discard: () => stack.discard(),
|
|
};
|
|
}
|