Files
Aislo/A00_Common/design/design_profile_overlays.ts
T

70 lines
3.7 KiB
TypeScript

/* =============================================================================
* design_profile_overlays.ts
* 종단도 바닥 오버레이 서브패널 — 유토곡선 · 테이블 · 유토 총괄 배지(213-3 · 700줄 한계로 뗌).
* 만들어 `bodyWrap` 에 붙이고 종단 스크롤과 잇는 데까지 — 그리기 · 높이는 종단도 몫.
* ========================================================================== */
import { attachMassHaulBadgeDrag, createMassHaulBadge } from "@util/common_util_mass_haul_badge";
import { readStateRaw, writeStateRaw } from "../b_page_state";
import { createHaulPlanPrefetch } from "../../B05_Profile/B05_Profile_Api_HaulPlan";
import { createProfileTableOverlay } from "../../B05_Profile/B05_Profile_UI_Profile_TableOverlay";
import {
createRouteMassHaulPanel,
type MassHaulSummaryValues,
} from "../../B05_Profile/B05_Profile_UI_Profile_MassHaul";
export interface ProfileOverlaysDeps {
projectId: string;
routeId: () => number | null;
/** 종단 열(요약 줄 · 본문 · 서클을 담은 칸) — 오버레이가 그 위를 덮는다. */
bodyWrap: HTMLElement;
/** 종단 스크롤러 — 오버레이 가로 스크롤을 이것과 맞춘다. */
body: HTMLElement;
/** 서브패널이 바뀜(펼침 · 범례 · 리사이저 · 유토 배분 도착). */
onChange: () => void;
}
export function createProfileOverlays(deps: ProfileOverlaysDeps) {
const { bodyWrap, body, onChange } = deps;
/** 유토곡선 총괄값 — **그래프 좌측 상단 배지**가 보인다(2026-09-06 사용자 지시).
* 유토곡선을 접어도 이 값은 남아야 한다. */
const massBadge = createMassHaulBadge();
// 그래프 위 도구줄 · 측점 ▲ 줄(바닥 47px) 아래로 내려 겹치지 않게 한다(289).
massBadge.root.style.setProperty("--mass-haul-badge-top", "52px");
bodyWrap.append(massBadge.root);
// 그래프 안 끌어 옮김(309-2) — 자리는 화면 설정 한 칸(B05 · B06 같은 값)
attachMassHaulBadgeDrag(massBadge.root, body, {
read: () => readStateRaw("mass-haul-badge-pos"),
write: (value) => writeStateRaw("mass-haul-badge-pos", value),
});
let massHaulSummary: MassHaulSummaryValues | null = null;
// 유토 배분은 **서버가 만든다**(2026-09-06) — 편집이 멈추면 뒤에서 받아 두고, 도착하면
// 곡선을 다시 그린다. 그 산식이 브라우저 번들에 안 실리는 것이 이 구조의 목적이다.
const haulPrefetch = createHaulPlanPrefetch(
deps.projectId,
() => deps.routeId() ?? undefined,
onChange,
);
const massHaul = createRouteMassHaulPanel(
onChange,
(summary) => {
const before = massHaulSummary;
massHaulSummary = summary;
if (before?.finalM3 !== summary?.finalM3) massBadge.set(summary);
},
haulPrefetch,
);
bodyWrap.append(massHaul.overlay, massHaul.handle);
// 오버레이의 가로 스크롤을 종단 스크롤러와 양방향 동기화 — 측점 세로선 정렬 유지.
massHaul.attachScrollSync(body);
// 테이블도 유토곡선과 같은 오버레이 서브패널 — 유토곡선 위에 쌓인다(2026-08-05 사용자 지시).
const tableOverlay = createProfileTableOverlay(onChange);
bodyWrap.append(tableOverlay.overlay, tableOverlay.handle);
tableOverlay.attachScrollSync(body);
// 유토곡선·테이블 영역에서 브라우저 기본 우클릭 메뉴를 막는다(2026-08-05 사용자 지시).
// 종단 그래프의 구조물 메뉴는 chartWrap에서 이미 preventDefault 후 자체 메뉴를 띄운다.
body.addEventListener("contextmenu", (event) => event.preventDefault());
massHaul.overlay.addEventListener("contextmenu", (event) => event.preventDefault());
return { massHaul, tableOverlay };
}