feat(B05,B06): 구조물 배치 컨테이너를 B06에 장착하고 [횡단 조정] 사본을 세운다

B05/B06 인터페이스 일원화 1차 (2026-08-29 사용자 확정 계획):
- A00_Common/b_structures_section.ts: B05 구조물 배치 폼·목록 공용 진입점
  (재수출 + 스타일 동봉)
- B06 좌측 패널에 [구조물 배치] 섹션 + 하단 dock [목록][구분선][저장버튼]
  (B05 동일 템플릿). 구조물 조작은 세션 pending으로 쌓여 기존
  flushPendingStructures([임시저장]·[확정])로 정본 반영
- 선택 연동: 목록·폼 → 최근접 카드 focusStation, 횡단도 벽·세월교·BOX →
  좌측 폼에 소유 측점 시설 로드(wireStructureSelection)
- [횡단 조정] 하위 컨테이너(Adjust_Dock): 오버레이 조정창을 같은 deps로
  사본 인스턴스 생성해 세움 — 로직 이동 0, 카드 재렌더로 자동 동기.
  9키·십자 행은 사본에서 숨김(사용자 지시 7), 방향키 이중 입력 방지
- A군 시설 추가·이동·삭제는 B06에서 안내 토스트(배수유역 체인은 B05 몫)

검증: 공용 브라우저 — 구간값 길이 사본 + 10.0→11.0m 양측 동기,
오버레이 - 원복, ✕ 닫기 시 사본 해제. B05 회귀 없음. typecheck 통과.
This commit is contained in:
2026-08-29 14:20:49 +09:00
parent 11abd303e7
commit 2e28af6e86
11 changed files with 427 additions and 66 deletions
+41 -29
View File
@@ -42,6 +42,7 @@ import type {
StructureSpanControl,
} from "./B06_Section_UI_Cross_Culvert_Wire";
import { buildStructurePanel } from "./B06_Section_UI_Cross_Structure_Panel";
import { adoptAdjustPanel, releaseAdjustPanel } from "./B06_Section_UI_Adjust_Dock";
import { culvertCardState, structurePanelDeps } from "./B06_Section_UI_Cross_View_Structure";
import { attachZoomPan, buildZoomControls } from "./B06_Section_UI_Cross_View_Zoom";
import type { CrossWidthActions, ZoomPanState } from "./B06_Section_UI_Cross_View_Zoom";
@@ -685,36 +686,47 @@ export function createCrossSectionCard(
const source = isLinkedCulvert && culvertLink ? culvertLink.source : section;
return revetOffset?.adjustFor(source, key) ?? { x: 0, d: null, h: null, m: null };
};
const panel = buildStructurePanel(
structurePanelDeps({
section,
scrollKey: section.station_id,
adjustChainage: () => adjustTarget().chainage_m,
isLinked: isLinkedCulvert,
revetOffset,
inletStructure,
extraWalls,
structureSpan,
revetLink,
adjustOf,
outwardOf,
heightOfWall,
formOfWall,
appliedD: () => culvertAppliedD,
pipeLengthM: () => culvertPipeLengthM,
inletIsBasin: () => culvertInletIsBasin,
hiddenPipe: () => culvertHiddenPipe,
inletOptions: () => culvertInletOptions,
extraState: () => culvertExtraState,
basinExtraState: () => culvertBasinExtraState,
activeRevet: () => activeRevet,
setActiveRevet: (key) => {
activeRevet = key;
},
toggleRevet,
}),
const panelContext = {
section,
scrollKey: section.station_id,
adjustChainage: () => adjustTarget().chainage_m,
isLinked: isLinkedCulvert,
revetOffset,
inletStructure,
extraWalls,
structureSpan,
revetLink,
adjustOf,
outwardOf,
heightOfWall,
formOfWall,
appliedD: () => culvertAppliedD,
pipeLengthM: () => culvertPipeLengthM,
inletIsBasin: () => culvertInletIsBasin,
hiddenPipe: () => culvertHiddenPipe,
inletOptions: () => culvertInletOptions,
extraState: () => culvertExtraState,
basinExtraState: () => culvertBasinExtraState,
activeRevet: () => activeRevet,
setActiveRevet: (key: RevetKey | null) => {
activeRevet = key;
},
toggleRevet,
};
const panel = buildStructurePanel(structurePanelDeps(panelContext));
// 좌측 [횡단 조정] 사본 — 같은 deps라 어느 쪽 조작이든 카드 재렌더에서 두 창이
// 함께 새 값으로 그려진다(2026-08-29 일원화). 스크롤 기억 키만 분리한다.
const dockPanel = buildStructurePanel(
structurePanelDeps({ ...panelContext, scrollKey: `dock:${section.station_id}` }),
{ dock: true },
);
showRevetControl = (visible) => panel.show(visible ? activeRevet : null);
showRevetControl = (visible) => {
const key = visible ? activeRevet : null;
panel.show(key);
dockPanel.show(key);
if (key) adoptAdjustPanel(dockPanel.root);
else releaseAdjustPanel(dockPanel.root);
};
showRevetControl(activeRevet !== null);
// 세월교 조정창 — 배수관 창과 조작 축이 달라 따로 만든다(2026-08-25 사용자).
// 우측 상단 줌 버튼이 원배율에서 표시 반폭까지 다룬다(하단 ◀/▶/↺ 폐지, 2026-08-23).