Merge remote-tracking branch 'origin/sub_laptop_8' into main_laptop_1
This commit is contained in:
@@ -289,18 +289,18 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra
|
||||
const pipeColor = (chainage: number): string => pipeMarkerColor(basins, chainage);
|
||||
|
||||
/** 마커 선택 ↔ 유역 강조 동기화 + 삭제 버튼 갱신(편집 폼은 사이드 소관). */
|
||||
function syncPipeSelection(): void {
|
||||
function syncPipeSelection(notify = true): void {
|
||||
const index = pipeEditor.selected();
|
||||
deleteButton.disabled = index === null;
|
||||
const picked = index === null ? null : pipeEditor.pipes()[index];
|
||||
selectBasin(basinIndexOfPipe(basins, picked ?? null));
|
||||
selectBasin(basinIndexOfPipe(basins, picked ?? null), notify);
|
||||
// 유역 유무와 무관하게 선택 자체를 알린다 — 그래프·3D·리스트 동기화(재진입은
|
||||
// Page의 selectionSyncing 가드가 끊는다). 값이 안 바뀌면 조용히 — 재계산(apply)
|
||||
// 뒤의 재호출이 다른 화면 선택을 풀어 버리지 않게.
|
||||
const pickedChainage = picked ? picked.chainage_m : null;
|
||||
if (pickedChainage !== lastNotifiedPipeChainage) {
|
||||
lastNotifiedPipeChainage = pickedChainage;
|
||||
callbacks.onPipeSelected?.(pickedChainage);
|
||||
if (notify) callbacks.onPipeSelected?.(pickedChainage);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,7 +647,7 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra
|
||||
pipeEditor.select(index);
|
||||
pipeEditor.deleteSelected();
|
||||
},
|
||||
selectPipeAtChainage(chainageM) {
|
||||
selectPipeAtChainage(chainageM, notify = true) {
|
||||
const index =
|
||||
chainageM === null
|
||||
? null
|
||||
@@ -658,7 +658,7 @@ export function createDrainagePanel(callbacks: DrainagePanelCallbacks = {}): Dra
|
||||
if (pipeEditor.selected() === next) return;
|
||||
// select()는 onChange를 울리지 않는다 — 폼·유역·재그리기를 직접 맞춘다.
|
||||
pipeEditor.select(next);
|
||||
syncPipeSelection();
|
||||
syncPipeSelection(notify);
|
||||
scheduleDraw();
|
||||
},
|
||||
async savePipes() {
|
||||
|
||||
@@ -45,7 +45,8 @@ export interface DrainagePanel {
|
||||
selectBasinByChainage: (chainageM: number | null) => void;
|
||||
/** 밖(리스트·그래프·3D)에서 관을 고른다 — 마커 선택·유역 강조를 맞춘다.
|
||||
* 이미 같으면 무시(2026-08-17 전역 선택 동기화). */
|
||||
selectPipeAtChainage: (chainageM: number | null) => void;
|
||||
/** notify 거짓 = 고름 한 칸에서 파생해 칠하기만(밖으로 안 알림 · 재계산 뒤 다시 얹음 · 233-3). */
|
||||
selectPipeAtChainage: (chainageM: number | null, notify?: boolean) => void;
|
||||
/** 측점 선택 마킹 — 계획선 위 해당 누가거리에 표식을 그린다(null이면 지움). */
|
||||
markStation: (chainageM: number | null) => void;
|
||||
/** 구간형 구조물이 놓인 자리 — 계획선 위에 띠로 얹는다(계획서 3-6).
|
||||
|
||||
@@ -494,7 +494,8 @@ export function createRouteMarkers(
|
||||
if (center) selectionPin.position.copy(center);
|
||||
}
|
||||
|
||||
function selectStation(stationId: string | null): void {
|
||||
/** notify 거짓 = 고름 한 칸에서 파생해 칠하기만(알림 없음 · 233-2). */
|
||||
function selectStation(stationId: string | null, notify = true): void {
|
||||
selectedStationId = stationId;
|
||||
stationGroup.children.forEach((object) => {
|
||||
// 측점 띠(stationId 보유 Mesh)만 색을 바꾼다.
|
||||
@@ -503,7 +504,7 @@ export function createRouteMarkers(
|
||||
(object.material as THREE.MeshBasicMaterial).color.set(selected ? 0xef4444 : 0xfacc15);
|
||||
});
|
||||
syncSelectionPin();
|
||||
stationSelectionListener?.(selectedStationId);
|
||||
if (notify) stationSelectionListener?.(selectedStationId);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -69,6 +69,8 @@ interface PanelCallbacks {
|
||||
onPipeFacilityRemove: (chainageM: number) => void;
|
||||
/** null = 사이드 목록 재클릭 해제 — 전 화면 선택도 함께 푼다(2026-08-18). */
|
||||
onPipeFacilitySelect: (chainageM: number | null) => void;
|
||||
/** 목록 다시 누름 · 새로 놓기 = 풀기 한 길(233-3). */
|
||||
onListRelease?: () => void;
|
||||
/** 이어 공사 시작 기준(시작 측점·누가거리 시작)이 바뀔 때. */
|
||||
onStationDisplayChange: (offset: { station: number; cumulative: number }) => void;
|
||||
}
|
||||
@@ -104,6 +106,7 @@ export function createRoutePanel(callbacks: PanelCallbacks, shared: DesignPageSh
|
||||
onPipeUpdate: callbacks.onPipeFacilityUpdate,
|
||||
onPipeRemove: callbacks.onPipeFacilityRemove,
|
||||
onPipeSelect: callbacks.onPipeFacilitySelect,
|
||||
onListRelease: callbacks.onListRelease,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
type SummaryItem,
|
||||
} from "../common_util/common_util_summary_item";
|
||||
import { STRUCTURE_SPECS } from "../A00_Common/design/design_structure_pipe";
|
||||
import { PIPE_MATCH_M } from "../A00_Common/design/design_selection";
|
||||
import { pipeExtraCount } from "../A00_Common/design/design_structure_pipe_calc";
|
||||
import {
|
||||
containerTitle,
|
||||
@@ -229,7 +230,8 @@ export function renderStructureList(params: StructureListParams): void {
|
||||
} else {
|
||||
const { pipe } = row;
|
||||
const picked =
|
||||
selectedPipeChainage !== null && Math.abs(selectedPipeChainage - pipe.chainage_m) < 0.05;
|
||||
selectedPipeChainage !== null &&
|
||||
Math.abs(selectedPipeChainage - pipe.chainage_m) < PIPE_MATCH_M; // 고름 찾는 거리 한 값(233-3)
|
||||
item.classList.toggle("is-selected", picked);
|
||||
station.textContent = formatStation(pipe.chainage_m, intervalM);
|
||||
item.addEventListener("click", () => params.onSelectPipe(pipe));
|
||||
|
||||
@@ -566,10 +566,10 @@ export function createStructuresSection(
|
||||
// 이 배열을 참조로 받아 두므로, 새 배열로 바꾸면 그쪽이 옛 배열을 고쳐
|
||||
// 목록에 반영되지 않는다(2026-09-04 실측: 저장 전 항목 [삭제]가 안 먹던 원인).
|
||||
structures.splice(0, structures.length, ...next.map((entry) => ({ ...entry })));
|
||||
// 실시간 반영으로 되돌아온 목록이면 폼을 닫지 않는다 — 고치던 칸이 사라진다.
|
||||
// [저장] 뒤 같은 id 가 남으면 그대로 고름 — 다시 열기와 같게(53-2).
|
||||
// 실시간 반영 목록이면 폼 안 닫음(고치던 칸) · [저장] 뒤 같은 id · 관 폼은 그대로(53-2 · 233-3)
|
||||
const kept = structures.find((entry) => entry.structure_id === editingId) ?? null;
|
||||
if (!applyingLive) loadForm(editingId === null ? null : kept);
|
||||
if (!applyingLive && selectedPipeChainage === null)
|
||||
loadForm(editingId === null ? null : kept);
|
||||
renderList();
|
||||
},
|
||||
getStructures: () => [...structures],
|
||||
@@ -593,12 +593,12 @@ export function createStructuresSection(
|
||||
syncButtons();
|
||||
}
|
||||
}
|
||||
if (
|
||||
selectedPipeChainage !== null &&
|
||||
!pipeFacilities.some(
|
||||
(pipe) => Math.abs(pipe.chainage_m - selectedPipeChainage!) < PIPE_MATCH_M,
|
||||
)
|
||||
) {
|
||||
const kept = pipeFacilities.find(
|
||||
(pipe) => Math.abs(pipe.chainage_m - (selectedPipeChainage ?? NaN)) < PIPE_MATCH_M,
|
||||
);
|
||||
if (kept)
|
||||
selectedPipeChainage = kept.chainage_m; // 조금 옮겨진 관도 고름 따라감(233-3)
|
||||
else if (selectedPipeChainage !== null) {
|
||||
// 고르고 있던 관이 사라졌다(삭제·재계산 이동) — 폼도 함께 닫는다.
|
||||
selectedPipeChainage = null;
|
||||
facilityOptions.setFacility(null);
|
||||
|
||||
Reference in New Issue
Block a user