From cdca8a2cfdc6b477839a6304f8b48540e27e96d1 Mon Sep 17 00:00:00 2001 From: umsangdon Date: Tue, 6 Oct 2026 10:40:46 +0900 Subject: [PATCH] =?UTF-8?q?fix(structure):=20B06=20=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EA=B3=A0=EB=A5=B8=20=EC=A4=84=EC=9D=84=20?= =?UTF-8?q?=EB=8B=A4=EC=8B=9C=20=EB=88=8C=EB=9F=AC=20=ED=92=80=EB=A9=B4=20?= =?UTF-8?q?=ED=9A=A1=EB=8B=A8=20=EC=B9=B4=EB=93=9C=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=EB=8F=84=20=ED=95=A8=EA=BB=98=20=ED=92=82(54-8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 목록 재클릭 풂 전용 알림 onListRelease 추가 — 폼 리셋·종류 바꿈 등 다른 null 고름 길은 그대로 - B06 은 그 알림에 카드 선택 풂(focusStation(null)) 연결 - 53-2 list 단계에 풂 뒤 카드 선택 0 판정 추가 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_015KYZ2HWWdUwZWYnn3tQz7X --- A00_Common/design/design_shared.ts | 1 + A00_Common/design/design_view_cross.ts | 1 + B05_Profile/B05_Profile_UI_Structures_Panel.ts | 7 +++++-- B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts | 2 ++ B06_Section/B06_Section_UI_Page_Structures_Panel.ts | 3 +++ B06_Section/B06_Section_UI_Section_View.ts | 3 ++- B06_Section/B06_Section_UI_Section_View_Types.ts | 4 ++-- resources/tester/ui_checks/53-2_목록_강조.js | 10 ++++++++-- 8 files changed, 24 insertions(+), 7 deletions(-) diff --git a/A00_Common/design/design_shared.ts b/A00_Common/design/design_shared.ts index 622ceb954..36c04ff22 100644 --- a/A00_Common/design/design_shared.ts +++ b/A00_Common/design/design_shared.ts @@ -190,6 +190,7 @@ export function sharedStructures(shared: DesignPageShared): StructuresSection { onPipeUpdate: (from, to, attributes) => on().onPipeUpdate?.(from, to, attributes), onPipeRemove: (chainageM) => on().onPipeRemove?.(chainageM), onPipeSelect: (chainageM) => on().onPipeSelect?.(chainageM), + onListRelease: () => on().onListRelease?.(), onReveal: () => shared.revealLeft(), }, { includeDetail: () => shared.view() === "cross", projectId: shared.projectId }, diff --git a/A00_Common/design/design_view_cross.ts b/A00_Common/design/design_view_cross.ts index 49ec05934..ebb992578 100644 --- a/A00_Common/design/design_view_cross.ts +++ b/A00_Common/design/design_view_cross.ts @@ -179,6 +179,7 @@ export async function mountCrossView( focusChainage: (chainageM) => { if (!isWallSelecting()) focusStationAt(chainageM); }, + releaseCard: () => sectionView.focusStation(null), markStructure: (structureId) => sectionView.selectMark(structureId), applyPipeOptions: (chainageM, patch) => applyPipeOptionsToCache(pipeOptionsContext, chainageM, patch), diff --git a/B05_Profile/B05_Profile_UI_Structures_Panel.ts b/B05_Profile/B05_Profile_UI_Structures_Panel.ts index c09b500c0..150f47e9f 100644 --- a/B05_Profile/B05_Profile_UI_Structures_Panel.ts +++ b/B05_Profile/B05_Profile_UI_Structures_Panel.ts @@ -433,8 +433,10 @@ export function createStructuresSection( selectedPipeChainage, // 재선택 = 해제(2026-08-18 복구) — 해제는 리셋과 같은 전체 초기화다. onSelectStructure: (structure) => { - if (structure.structure_id !== null && structure.structure_id === editingId) resetForm(); - else loadForm(structure); + if (structure.structure_id !== null && structure.structure_id === editingId) { + resetForm(); + callbacks.onListRelease?.(); + } else loadForm(structure); }, onSelectPipe: (pipe) => { const isSame = @@ -442,6 +444,7 @@ export function createStructuresSection( Math.abs(selectedPipeChainage - pipe.chainage_m) < PIPE_MATCH_M; if (isSame) { resetForm(); + callbacks.onListRelease?.(); } else { loadPipeForm(pipe); callbacks.onPipeSelect(pipe.chainage_m); diff --git a/B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts b/B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts index 86e12199c..e667ce5ae 100644 --- a/B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts +++ b/B05_Profile/B05_Profile_UI_Structures_Panel_Types.ts @@ -164,6 +164,8 @@ export interface StructuresCallbacks { * 목록에서 직접 고른 경우엔 이미 펼쳐져 있어 아무 일도 안 한다. */ onReveal?: () => void; + /** 목록에서 고른 줄을 다시 눌러 풂 — 다른 화면의 고름(횡단 카드)도 함께 끔(54-8). */ + onListRelease?: () => void; } type OptionEntry = { key: string; read: () => string | number; isEmpty: () => boolean }; diff --git a/B06_Section/B06_Section_UI_Page_Structures_Panel.ts b/B06_Section/B06_Section_UI_Page_Structures_Panel.ts index 591e2c7ff..ad08fdb2e 100644 --- a/B06_Section/B06_Section_UI_Page_Structures_Panel.ts +++ b/B06_Section/B06_Section_UI_Page_Structures_Panel.ts @@ -87,6 +87,8 @@ export interface B06StructuresPanelDeps { stationInterval: () => number; /** 목록·폼에서 고른 시설의 측점 카드를 선택·스크롤한다. */ focusChainage: (chainageM: number) => void; + /** 목록에서 고른 줄을 다시 눌러 풂 — 횡단 카드 선택도 끔(54-8). */ + releaseCard?: () => void; /** 종단 알약 강조를 목록에서 고른 것에 맞춘다(null = 관 · 해제 — 측점선 짝을 따름). */ markStructure?: (structureId: string | null) => void; /** 목록이 바뀔 때마다 종단 알약 레인에 같은 목록을 넘긴다(2026-09-07 표시 통일). */ @@ -296,6 +298,7 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc // 알약 = 그 관 알약(같은 측점 구조물 말고 · 측점선 없는 물넘이포장도) — 카드 뒤에(53-2) deps.markStructure?.(chainageM === null ? null : `pipe-${chainageM.toFixed(2)}`); }, + onListRelease: () => deps.releaseCard?.(), }, }); diff --git a/B06_Section/B06_Section_UI_Section_View.ts b/B06_Section/B06_Section_UI_Section_View.ts index b03fa52ba..47097869c 100644 --- a/B06_Section/B06_Section_UI_Section_View.ts +++ b/B06_Section/B06_Section_UI_Section_View.ts @@ -445,7 +445,8 @@ export function createSectionView( refreshCard, refreshCards, focusStation(stationId) { - if (selectedStationId !== stationId) selectStation(stationId, true); + if (stationId === null) clearSelection(); + else if (selectedStationId !== stationId) selectStation(stationId, true); else { revealCard(stationId, "smooth"); // 같은 카드라도 알약 강조는 다시 맞춘다 — 목록에서 같은 측점 다른 항목을 고른 경우(52-15). diff --git a/B06_Section/B06_Section_UI_Section_View_Types.ts b/B06_Section/B06_Section_UI_Section_View_Types.ts index 811c93dad..24c05dbc1 100644 --- a/B06_Section/B06_Section_UI_Section_View_Types.ts +++ b/B06_Section/B06_Section_UI_Section_View_Types.ts @@ -38,8 +38,8 @@ export interface SectionViewController { /** 여러 측점을 한꺼번에 교체한다 — 상단 패널은 **마지막에 한 번만** 다시 그린다. */ refreshCards: (chainages: ReadonlyArray) => void; /** 좌측 구조물 목록에서 고른 측점 카드를 선택하고 화면에 드러낸다 — 재클릭 토글 없음 - * (2026-08-29 B05/B06 일원화: 목록 클릭 → 해당 카드 스크롤·강조). */ - focusStation: (stationId: string) => void; + * (2026-08-29 B05/B06 일원화: 목록 클릭 → 해당 카드 스크롤·강조). null = 카드 선택 풂(54-8). */ + focusStation: (stationId: string | null) => void; /** 종단 알약 강조를 그 구조물로(null = 풀기 — 카드 측점선 짝을 따름). */ selectMark: (structureId: string | null) => void; /** 카드(측점) 선택이 바뀔 때 알림 — 좌측 「구조물 배치」 폼이 그 측점 구조물을 diff --git a/resources/tester/ui_checks/53-2_목록_강조.js b/resources/tester/ui_checks/53-2_목록_강조.js index 76c58b674..9f89c8798 100644 --- a/resources/tester/ui_checks/53-2_목록_강조.js +++ b/resources/tester/ui_checks/53-2_목록_강조.js @@ -153,8 +153,14 @@ } items()[i].click(); // 다시 누름 = 풂 await w(900); - if (selRows().length || litPills().length || (!isB06 && lit3D().length)) - fail(`${r.text}: 풂 뒤 남음 ${selRows().length}/${litPills()}/${lit3D()}`); + // 풂 = 카드 선택도 풀림(54-8) + if ( + selRows().length || + litPills().length || + (!isB06 && lit3D().length) || + (isB06 && cardSel().length) + ) + fail(`${r.text}: 풂 뒤 남음 ${selRows().length}/${litPills()}/${lit3D()}/${cardSel()}`); } out.checked = rows.length; } else if (MODE === "pill") {