fix(B05,B06): 독립 기슭막이 단 수를 좌·우로 나누고 그 칸을 강조한다

- 단 수를 바깥 행에서 좌·우 칸 안으로 옮긴다. 저장 키도 좌·우 각각
  (inlet_revet_tiers·outlet_revet_tiers, 옛 tiers는 폴백·호환 기록).
  폼 값은 다단 채널(extra·bextra)로 가고, 폼은 그 채널 값을 되읽는다.
- 좌·우 칸에도 조정창 행 이식 자리를 두어, 벽을 고르면 배관 유입구·유출구와
  같이 그 칸이 강조되고 조정 항목이 옮겨 온다. 칸 이름표는 좌·우 그대로 둔다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-29 19:09:42 +09:00
co-authored by Claude Opus 5
parent 86a3266e0e
commit 091a30286e
5 changed files with 97 additions and 31 deletions
@@ -48,7 +48,9 @@ export interface B06StructuresPanelDeps {
/** 그 측점에서 유입·유출 벽이 각각 좌·우 어느 쪽인가(독립 기슭막이 칸 이름표). */
wallSideLabels?: (chainageM: number) => { inlet: "좌" | "우"; outlet: "좌" | "우" } | null;
/** 폼의 단 수를 다단 채널에 반영한다 — 조정창에서 세우던 것과 같은 자리. */
setTierCount?: (chainageM: number, tiers: number) => void;
setTierCount?: (chainageM: number, role: "inlet" | "outlet", tiers: number) => void;
/** 지금 선 단 수(기준벽 포함) — 폼이 도면과 같은 값을 보이게 한다. */
tierCount?: (chainageM: number, role: "inlet" | "outlet") => number | null;
/** 측점 간격(m) — 측점번호+잔여거리 환산용. */
stationInterval: () => number;
/** 목록·폼에서 고른 시설의 측점 카드를 선택·스크롤한다. */
@@ -110,6 +112,7 @@ function withSpecDefaults(
chainageM: number,
wallHeight?: (chainageM: number, role: "inlet" | "outlet") => number | null,
wallForm?: (chainageM: number, role: "inlet" | "outlet") => string | null,
tierCount?: (chainageM: number, role: "inlet" | "outlet") => number | null,
): Record<string, string | number> | undefined {
const owner = detail?.cross_sections.find(
(section) => Math.abs(section.chainage_m - chainageM) < PIPE_MATCH_M,
@@ -136,6 +139,9 @@ function withSpecDefaults(
const drawnHeight = wallHeight?.(chainageM, prefix);
if (drawnHeight != null) merged[`${prefix}_revet_height_m`] = Number(drawnHeight.toFixed(1));
else put(`${prefix}_revet_height_m`, side.revet_height_m);
// 단 수는 다단 채널이 정본이다 — 폼이 그 값을 그대로 보인다.
const tiers = tierCount?.(chainageM, prefix);
if (tiers != null) merged[`${prefix}_revet_tiers`] = tiers;
put(`${prefix}_revet_length_m`, side.revet_length_m);
put(`${prefix}_revet_before_m`, side.revet_before_m);
put(`${prefix}_revet_after_m`, side.revet_after_m);
@@ -199,8 +205,10 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc
}
// 단 수는 옵션이자 **조작 채널**이다 — 조정창에서 세우던 그 자리로 보내야
// 횡단도에 단이 선다(2026-08-30 사용자 지시 3: 배수관 측점과 동일하게).
const tiers = Number(patch.tiers);
if (Number.isFinite(tiers)) deps.setTierCount?.(fromChainageM, tiers);
for (const role of ["inlet", "outlet"] as const) {
const tiers = Number(patch[`${role}_revet_tiers`]);
if (Number.isFinite(tiers)) deps.setTierCount?.(fromChainageM, role, tiers);
}
// 옵션은 **옮기기 전 자리**로 예약한다 — 저장 시점의 관 목록이 그 자리 기준이다.
deps.queuePipeOptions(fromChainageM, patch as Record<string, number | string>);
deps.applyPipeOptions?.(fromChainageM, patch as Record<string, number | string>);
@@ -233,6 +241,8 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc
inlet: section.facility.inletSlot,
outlet: section.facility.outletSlot,
extra: section.facility.extraSlot,
revetInlet: section.facility.revetInletSlot,
revetOutlet: section.facility.revetOutletSlot,
});
async function load(): Promise<void> {
@@ -262,6 +272,7 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc
pipe.chainage_m,
deps.wallHeight,
deps.wallForm,
deps.tierCount,
),
design_flow_m3s: null,
}));
@@ -293,6 +304,7 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc
hit.chainage_m,
deps.wallHeight,
deps.wallForm,
deps.tierCount,
);
section.setPipeFacilities(pipeFacilities);
}