Merge remote-tracking branch 'origin/sub_laptop_7' into main_laptop_1

# Conflicts:
#	B06_Section/B06_Section_UI_Cross_View.ts
This commit is contained in:
2026-10-08 00:28:26 +09:00
37 changed files with 771 additions and 131 deletions
+2 -2
View File
@@ -15,7 +15,7 @@
* ========================================================================== */
import type { Instance, SpecContainer, SpecItem, StructureSpec } from "./design_structure_spec";
import { CHUTE_ADD, guardItems, revetKeys, SOIL_ADD } from "./design_structure_guard";
import { bodyGuardItems, CHUTE_ADD, SOIL_ADD } from "./design_structure_guard";
export const BOX_CUSTOM = "사용자 입력";
/** 사용자 입력에 가로 · 세로 둘 다 빈 채 저장했다는 표시(폭 · 높이 수가 없을 때만 적음). */
@@ -50,7 +50,7 @@ const guardContainer = (
{ value: "흙막이", label: "흙막이" },
],
},
...guardItems({ 흙막이: revetKeys(id) }, undefined, true),
...bodyGuardItems(id, "박스 높이(자동)"),
],
});
+2 -2
View File
@@ -12,7 +12,7 @@
* ========================================================================== */
import type { SpecContainer, SpecChoice, StructureSpec } from "./design_structure_spec";
import { CHUTE_ADD, guardItems, revetKeys, SOIL_ADD } from "./design_structure_guard";
import { bodyGuardItems, CHUTE_ADD, SOIL_ADD } from "./design_structure_guard";
/** 유입 · 유출 구조 — 날개벽만 옛 설치 칸이 「있음」. */
const guard = (side: "in" | "out"): SpecChoice[] => [
@@ -35,7 +35,7 @@ const guardContainer = (id: "inlet" | "outlet", title: string, link: string): Sp
key: `${id}_type`,
choices: guard(id === "inlet" ? "in" : "out"),
},
...guardItems({ 흙막이: revetKeys(id) }, undefined, true),
...bodyGuardItems(id, "본체 끝 높이(자동)"),
],
});
@@ -82,6 +82,23 @@ export const revetKeys = (side: "inlet" | "outlet"): Record<string, string> => (
after: `${side}_revet_after_m`,
});
/** 세월교 · 박스 유입 · 유출 흙막이 칸(79-7) — 높이 빈 칸 = 자동(`heightHint` · 횡단도가 셈) ·
* 절토부 앞 수평공간 칸(`{side}_revet_berm_m`)을 더함. */
export function bodyGuardItems(side: "inlet" | "outlet", heightHint: string): SpecItem[] {
const items = guardItems({ 흙막이: revetKeys(side) }, undefined, true).map((item) =>
item.id === "height" ? { ...item, default: undefined, hint: heightHint } : item,
);
const berm: SpecItem = {
id: "berm",
label: "수평공간 (m)",
kind: "number",
step: 0.1,
default: "1",
by: { item: "structure", map: { 흙막이: { key: `${side}_revet_berm_m` } } },
};
return [...items, berm];
}
/** 추가 흙막이(선택 · 여러 개) — 사면안정 흙막이(표 09 · 54-26)와 같은 칸 · 구조 고르기 없음(54-30). */
export const SOIL_ADD: SpecContainer = {
id: "soil_add",
+2 -2
View File
@@ -381,7 +381,7 @@ export async function mountCrossView(
(chainageM) => shared.bindings[shared.view()]?.structures?.onPipeSelect?.(chainageM),
);
// 횡단도(카드) 자체를 골라도 그 측점 구조물 정보를 폼에 올린다(2026-08-29 사용자).
// 연동으로 옆에서 넘어온 카드는 **소유 측점** 시설을 보여 준다.
// 연동으로 옆에서 넘어온 카드는 벽을 찍었을 때만 **소유 측점** 시설 · 카드만 고르면 일반 측점(79-6).
sectionView.setStationSelectListener((stationId) => {
const target = stationId
? sectionDetail?.cross_sections.find((section) => section.station_id === stationId)
@@ -391,7 +391,7 @@ export async function mountCrossView(
selectDesign(projectId, NO_SELECTION, { from: "b06" }); // 카드 해제 — 선택도 비운다.
return;
}
const owner = stationControls.structureSpan.ownerOf(target);
const owner = isWallSelecting() ? stationControls.structureSpan.ownerOf(target) : null;
const opened = structuresPanel.showAtChainage(owner?.chainage_m ?? target.chainage_m);
// 카드만 고른 것도 남긴다 — 종단 보기로 가면 그 시설이 그대로 열린다.
if (!isWallSelecting()) selectDesign(projectId, opened, { from: "b06" });