Files
Aislo/M02_MasterTemplete/M02_MasterTemplete_Hopyo_SheetSk.ts
T
eomsangdonandClaude Opus 5.5 8a5689c400 feat(780-2): 엑셀 보기 단가산출 탭 오른쪽 = 단가산출 목록 — 판 바꾸기 · 거르기 · 목록 ↔ 시트 · 두 벌 맞춤(요구 627)
- 새 Hopyo_SheetSk: 탭(역할) 따라 오른쪽 판 바꿈 · 일위대가표 = 호표 목록 그대로 · 단가산출표 · 상세 = 마법사 단가산출 칸 좁은 꼴 한 벌(처음 올 때 지음 · 다른 층 · 권한 없음 = 보기만) · 시트 칸 → 목록 강조 · 목록 줄 → 지금 탭 블록 자리
- WizardSk: 좁은 꼴 옵션 · 부름 칸(일위대가 n 곳 · 일위대가 밖) · 거르기(전체 · 안 · 밖 · 고를 줄 있음) · 같은 캐시 두 벌 맞춤 알림 · 옮김 뒤 HOPYO_BUILT(열린 엑셀 보기 칠 다시)
- SkPick: 줄 0 블록 = 「줄 없음」 확인 막음 · 거르기 · 끝내기 글 재료에 일위대가 밖 수
- SheetNav: role · blockAt · spotOf 내보냄 · SheetMap: 판정 없음 글 → 「일위대가 밖」
- Wizard [끝내기]: 막지 않음 · 물음창에 안 옮긴 단가산출 n(일위대가 밖 m)
- 시험: 새 test_627_sheet_sk(판 바꿈 · 목록 지음 · 줄 0 막음 · 캐시 공유) · test_778_5 끝내기 재료 꼴에 밖 칸 더함

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 18:01:06 +09:00

69 lines
3.2 KiB
TypeScript

/* =============================================================================
* M02_MasterTemplete_Hopyo_SheetSk.ts
* 엑셀 보기 창 오른쪽 판 바꾸기(PLAN 780-2 · 요구 627) — 탭 따라:
* · 일위대가표 = 호표 목록(`Hopyo_Sheet` 판 그대로) · 단가산출표 · 단가산출 상세 = 단가산출 목록
* (마법사 단가산출 칸 `sangeunStep` 좁은 꼴 한 벌 · 같은 캐시 · 같은 [확인] → [확인한 것 옮기기] · 마법사 체크와 상관없음)
* · 목록 블록 줄 누름 → 지금 탭의 그 블록 자리(단가산출표 = 목록 행 · 상세 = 블록 범위 · [◂ 뒤로] 쌓임)
* · 시트 칸 고름 → 그 행 블록을 목록에서 강조(`SheetNav.blockAt`)
* · 단가산출 칸은 처음 단가산출 탭에 올 때 지음(판정 셈이 무거움) · 만들 층 ≠ 파일 층 · 쓰기 권한 없음 = 보기만
* ========================================================================== */
import { el } from "@ui/ui_template_elements";
import type { HopyoScope } from "./M02_MasterTemplete_Hopyo_Api";
import type { SheetNav } from "./M02_MasterTemplete_Hopyo_SheetNav";
import { sangeunStep, type SkStep } from "./M02_MasterTemplete_Hopyo_WizardSk";
export interface SheetSkOptions {
scope: HopyoScope;
key: string;
파일: string;
target: HopyoScope;
canWrite: boolean;
nav: SheetNav;
/** 호표 목록 판 — 단가산출 탭이면 숨김 · 그 뒤에 단가산출 판을 붙임 */
side: HTMLElement;
}
const sameLayer = (a: HopyoScope, b: HopyoScope): boolean =>
a.layer === b.layer && (a.owner ?? null) === (b.owner ?? null);
export function createSheetSk(opt: SheetSkOptions) {
const root = el("div", { className: "m02-hopyo-sheet__side m02-hopyo-sheet__sk" });
root.setAttribute("data-hopyo-sk-side", "");
root.hidden = true;
opt.side.after(root);
let step: SkStep | null = null;
let sheet = "";
/** 블록 줄 누름 — 지금 탭에서 그 블록 자리 · 없으면 다른 단가산출 탭 */
function onRow(no: number): void {
const list = opt.nav.role(sheet) === "단가산출표";
const spot = list
? (opt.nav.spotOf(no, "단가산출표") ?? opt.nav.spotOf(no, "단가산출상세"))
: (opt.nav.spotOf(no, "단가산출상세") ?? opt.nav.spotOf(no, "단가산출표"));
if (spot) opt.nav.jumpTo(spot.시트, spot.행);
}
return {
root,
/** 시트 고름 · 탭 바꿈 — 판 바꾸기 · 강조 */
at(sel: { 시트: string; 칸: string }): void {
sheet = sel.시트;
const role = opt.nav.role(sel.시트);
const sk = role === "단가산출표" || role === "단가산출상세";
opt.side.hidden = sk;
root.hidden = !sk;
opt.side.parentElement?.classList.toggle("is-sk", sk);
if (!sk) return;
if (!step) {
const readOnly = !opt.canWrite || !sameLayer(opt.scope, opt.target);
step = sangeunStep(opt.scope, opt.key, opt.파일, undefined, { narrow: true, onRow, readOnly }); // prettier-ignore
root.append(step.root);
}
step.mark(opt.nav.blockAt(sel.시트, Number(/\d+/.exec(sel.칸)?.[0] ?? 0)));
},
};
}
export type SheetSk = ReturnType<typeof createSheetSk>;