- 새 `Sangeun_Side` — 일위대가 상세와 같은 서랍(`createSidePanels`) + 원문 보기(`createSourceView` · M02 길 `/m02/logic-lib/source` · 원문 다운로드) · 바탕 · 둘째 기초(더한줄 로직)마다 탭 · 기초 하나 = 탭 없음 · 바탕 없음 = 「원문 연결 없음」 · 넓은 화면(1500 이상)만 처음 열림 · 열림 · 폭 기억 `m02-sangeun-side` - Sangeun_Detail — 옵션 `source`(단가산출 화면 View 만 켬 · 줄 모달 RowSk 는 안 켬) · 「시험 계산 · 텍스트 수식 = 바탕 기초 + …」 안내 글 걷음(750-2 로 네 보기가 같은 답이라 낡음 · 키 M02_SangeunBaseViews 지움) - 낡은 시험 고침 — test_721_find_pick(안내 걷음) · 새 지킴 test_750_2 에 752-1 대조 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
84 lines
3.3 KiB
TypeScript
84 lines
3.3 KiB
TypeScript
/* =============================================================================
|
|
* M02_MasterTemplete_Sangeun_Side.ts
|
|
* 단가산출(SK) 상세 오른쪽 원문 패널(PLAN 752-1 · 요구 588-3) — 일위대가 상세(47-4 · 85-4)와 같은 부품:
|
|
* 오른쪽 서랍(`createSidePanels`) + 원문 보기(`createSourceView` · M02 로그인 길 `/m02/logic-lib/source`)
|
|
* 기초마다 탭 — 바탕 로직 · 둘째 기초(더한줄 로직) 각각의 출처 · 기초가 하나면 탭 없음 · 없으면 안내
|
|
* 처음 = 넓은 화면만 열림(좁으면 세로 띠로 접힘) · 열림 · 폭 기억 = `m02-sangeun-side`
|
|
* 일위대가 줄 모달 안 상세는 안 만듦(부르는 쪽이 `source` 를 안 켬).
|
|
* ========================================================================== */
|
|
|
|
import { createSegment } from "@ui/ui_template_segment";
|
|
import { el } from "@ui/ui_template_elements";
|
|
import { t as L } from "@ui/ui_template_locale";
|
|
import { createSidePanels } from "@ui/ui_template_side_panels";
|
|
import { createText } from "@ui/ui_template_text";
|
|
import { createSourceView } from "../M01_MasterData/M01_MasterData_UI_LogicLab_Source";
|
|
import { tc } from "./M02_MasterTemplete_Labor_Text";
|
|
|
|
export interface SourceTab {
|
|
label: string;
|
|
src: string;
|
|
}
|
|
|
|
/** 기초 로직 → 원문 탭(「원문번호 이름」 · 출처 글) */
|
|
export const tabOf = (logic: {
|
|
키: string;
|
|
원문번호?: string;
|
|
이름: string;
|
|
출처?: string;
|
|
}): SourceTab => ({
|
|
label: `${logic.원문번호 || logic.키} ${logic.이름}`,
|
|
src: logic.출처 ?? "",
|
|
});
|
|
|
|
/** 이 폭 이상일 때만 처음부터 열림 — 상세 표 여섯 칸이 좁아지지 않게 */
|
|
const OPEN_FROM = 1500;
|
|
|
|
export function createSangeunSide(): {
|
|
wrap: (main: HTMLElement) => HTMLElement;
|
|
set: (tabs: SourceTab[]) => void;
|
|
} {
|
|
const view = createSourceView({
|
|
path: "/m02/logic-lib/source",
|
|
pdf: "/m02/logic-lib/source-pdf",
|
|
});
|
|
const host = el("div", { attrs: { "data-sangeun-source": "" } });
|
|
let tabs: SourceTab[] = [];
|
|
let at = 0;
|
|
const side = createSidePanels({
|
|
prefKey: "m02-sangeun-side",
|
|
follow: false, // 일위대가와 같음 — 상세 고정 높이 칸을 채움 · 본문과 따로 스크롤
|
|
defaultOpen: window.innerWidth >= OPEN_FROM ? "source" : null,
|
|
panels: [{ id: "source", title: tc("Labor_Source"), body: host }],
|
|
onChange: () => paint(),
|
|
});
|
|
function paint(): void {
|
|
if (side.current() !== "source") return; // 접힘 = 찾지 않음
|
|
if (!tabs.length)
|
|
return void host.replaceChildren(createText(L("M02_SangeunSourceNone"), "muted"));
|
|
at = Math.min(at, tabs.length - 1);
|
|
view.show(tabs[at].src);
|
|
const bar =
|
|
tabs.length > 1
|
|
? [
|
|
createSegment({
|
|
options: tabs.map((x, i) => ({ value: String(i), label: x.label })),
|
|
value: String(at),
|
|
size: 28,
|
|
ariaLabel: tc("Labor_Source"),
|
|
onChange: (v) => ((at = Number(v)), paint()),
|
|
}).root,
|
|
]
|
|
: [];
|
|
host.replaceChildren(...bar, view.root);
|
|
}
|
|
return {
|
|
wrap: (main) => el("div", { className: "ui-side-panels-row", children: [main, side.root] }),
|
|
set: (next) => {
|
|
if (JSON.stringify(next) === JSON.stringify(tabs)) return;
|
|
tabs = next;
|
|
paint();
|
|
},
|
|
};
|
|
}
|