From c8bd95b1aacff593e8e72fd155905613f17845ea Mon Sep 17 00:00:00 2001 From: umsangdon Date: Tue, 6 Oct 2026 13:27:54 +0900 Subject: [PATCH] =?UTF-8?q?fix(B06):=2054-29=20=ED=9A=A1=EB=8B=A8=20=C2=B7?= =?UTF-8?q?=20=EB=AA=A9=EB=A1=9D=20=EA=B3=A0=EB=A5=B4=EA=B8=B0=20=EC=A2=8C?= =?UTF-8?q?=EC=B8=A1=20=ED=8C=A8=EB=84=90=20=EA=B0=99=EC=9D=80=20=EA=B8=80?= =?UTF-8?q?=20=E2=80=94=20=EC=B0=A8=EC=9D=B4=EB=8A=94=20=EA=B0=95=EC=A1=B0?= =?UTF-8?q?=20=EC=83=81=EC=9E=90=EB=BF=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 배관 유입 · 유출 칸에 횡단 전용 줄(옵션 · 경사 · 읽기) 안 옮김 · 이름표 꼬리 「(기슭막이(유출))」 뺌 - 배관 유입 벽 「추가 기슭막이(단) 0단」 줄 숨김(선 단이 있을 때만) · 집수정 내공 줄만 남김 - 폼을 다시 그린 뒤(유입 형식 되싣기 · 단 수 · 벽 조작) 고른 상자 강조 다시 — 흙막이 상자 강조 빠짐 고침 - 시험 test_54_29_pick_same_panel · test_54_27 단 줄 단언 새 형태로 화면 확인(sub5_검증 12+18 단 1): 유출 · 흙막이 1 · 유입 목록 대 횡단 innerText · 칸 67 · 값 같음 · 강조 상자 하나만 · B05 넘김 같음 · 유출 5칸 → 관 길이 15 → 20 · 되돌림 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01BVPp2o6Mh2FZJr72yW3ofZ --- B06_Section/B06_Section_UI_Adjust_Dock.ts | 29 +++++++----- .../B06_Section_UI_Cross_Structure_Panel.ts | 5 +- .../B06_Section_UI_Page_Structures_Panel.ts | 7 ++- .../tester/test_54_27_soil_tier_field.py | 3 +- .../tester/test_54_29_pick_same_panel.py | 46 +++++++++++++++++++ 5 files changed, 75 insertions(+), 15 deletions(-) create mode 100644 resources/tester/test_54_29_pick_same_panel.py diff --git a/B06_Section/B06_Section_UI_Adjust_Dock.ts b/B06_Section/B06_Section_UI_Adjust_Dock.ts index b4b863758..91c2b61df 100644 --- a/B06_Section/B06_Section_UI_Adjust_Dock.ts +++ b/B06_Section/B06_Section_UI_Adjust_Dock.ts @@ -57,11 +57,19 @@ const SIDE_ROWS = [ ".b06-structure-panel__struct--wall-height", ].join(", "); -/** 배관 유출 칸 — 읽기 줄(54-1) · 단 수 줄(폼 「추가 흙막이(단)」 칸이 맡음 · 54-27)은 안 받음. */ -const PIPE_OUTLET_ROWS = SIDE_ROWS.replace(".b06-structure-panel__struct--readout, ", "").replace( - ".b06-structure-panel__struct--tier, ", - "", -); +/** 배관 칸 = 폼에 자리 없는 집수정 내공 · 유입 단 수만 — 목록에서 골라도 같은 글(54-29). + * 유출 단 수는 폼 「추가 흙막이(단)」 칸(54-27) · 읽기 · 옵션 줄은 안 받음. */ +const PIPE_INLET_ROWS = [ + ".b06-structure-panel__struct--tier", + ".b06-structure-panel__struct--basin-size", +].join(", "); +const PIPE_OUTLET_ROWS = ".b06-structure-panel__struct--basin-size"; + +/** 받을 칸에 맞는 줄 — 배관 유입 · 유출 칸이 아니면 옛 줄 그대로. */ +function rowsFor(slot: HTMLElement): string { + if (slot === sideSlots?.outlet) return PIPE_OUTLET_ROWS; + return slot === sideSlots?.inlet ? PIPE_INLET_ROWS : SIDE_ROWS; +} /** 이식 자리가 지금 화면에 서 있는지 — 그 위 어느 줄이든 숨었으면(다른 시설 명세 폼 등) 옮기지 않는다. */ function slotUsable(target: HTMLElement | undefined): target is HTMLElement { @@ -174,13 +182,10 @@ function relocateSideRows(panelRoot: HTMLElement): void { moveRows(panelRoot, EXTRA_ROWS, target); // 단 수·옵션은 그 단이 딸린 부모 벽의 값이라 부모 칸에 그대로 세운다 — 다단을 // 고를 때 그 두 행이 사라지던 것을 막는다(2026-08-30 사용자). - if (slotUsable(ownerSlot)) - moveRows(panelRoot, ownerSlot === sideSlots.outlet ? PIPE_OUTLET_ROWS : SIDE_ROWS, ownerSlot); + if (slotUsable(ownerSlot)) moveRows(panelRoot, rowsFor(ownerSlot), ownerSlot); } else { if (!slotUsable(target)) return; - // 배관 유출 칸은 읽기 줄(관 길이 · 좌우 · 상하 안내) · 단 수 줄을 안 받음(54-1 · 54-27) - const rows = target === sideSlots.outlet ? PIPE_OUTLET_ROWS : SIDE_ROWS; - moveRows(panelRoot, rows, target); + moveRows(panelRoot, rowsFor(target), target); } // 고른 구조물이 어느 쪽인지 그룹 테두리로 알린다(2026-08-29 사용자 지시 3). const group = target.closest("fieldset"); @@ -188,7 +193,9 @@ function relocateSideRows(panelRoot: HTMLElement): void { group.classList.add("is-active"); // 이름표에 지금 만지는 구조물을 적는다 — "유입구 (기슭막이)", "유출구 (기슭막이(독립))". // 추가 기슭막이 칸은 이름 자체가 그 단이라 괄호 안에 단 번호가 온다(2026-08-30 지시 1). - setGroupLabel(group, panelRoot.dataset.panelTitle ?? ""); + // 배관 칸은 이름표를 안 바꿈 — 목록에서 고른 글과 같게 · 강조만(54-29). + const pipe = target === sideSlots.inlet || target === sideSlots.outlet; + setGroupLabel(group, pipe ? "" : (panelRoot.dataset.panelTitle ?? "")); // 고른 칸이 화면 밖일 수 있다 — 그 자리로 스크롤한다(지시 2 · 유입 · 유출도 53-1). group.scrollIntoView({ block: "nearest" }); } diff --git a/B06_Section/B06_Section_UI_Cross_Structure_Panel.ts b/B06_Section/B06_Section_UI_Cross_Structure_Panel.ts index bdaabfaa6..e0d10169c 100644 --- a/B06_Section/B06_Section_UI_Cross_Structure_Panel.ts +++ b/B06_Section/B06_Section_UI_Cross_Structure_Panel.ts @@ -595,9 +595,12 @@ export function buildStructurePanel( // 집수정 유입은 계류측 단이 설 자리가 있을 때만 — 벽이 아니라 구체다. // 다단 벽도 포함한다 — 행은 부모 칸에 서 있고, 그 값(부모 단 수·옵션)을 그대로 쓴다. const revetWall = ((key === "inlet" || key === "outlet") && !isBasin) || isExtra; + // 배관 유입 벽 = 다단 없음 — 이미 선 단이 있을 때만(목록에서 고른 글과 같게 · 54-29) + const pipeInlet = key === "inlet" && !isBasin && !deps.hiddenPipe(); extraRow.classList.toggle( "is-hidden", - !revetWall && !(isBasin && tierChannel === "basin" && (tiers.canAdd || tiers.count > 0)), + (!revetWall || (pipeInlet && tiers.count === 0)) && + !(isBasin && tierChannel === "basin" && (tiers.canAdd || tiers.count > 0)), ); currentCount = tiers.count; countValue.textContent = `${tiers.count}단`; diff --git a/B06_Section/B06_Section_UI_Page_Structures_Panel.ts b/B06_Section/B06_Section_UI_Page_Structures_Panel.ts index 44559bad5..db4d5a2c8 100644 --- a/B06_Section/B06_Section_UI_Page_Structures_Panel.ts +++ b/B06_Section/B06_Section_UI_Page_Structures_Panel.ts @@ -496,7 +496,8 @@ export function createB06StructuresPanel(deps: B06StructuresPanelDeps): B06Struc facility: { setInletStructure: (value) => section.facility.setInletStructure(value), onInletStructureChange: (handler) => section.facility.onInletStructureChange(handler), - recount: () => section.facility.recount(), + // 다시 그린 상자에 강조를 다시 얹음(흙막이 상자 · 54-29) + recount: () => (section.facility.recount(), refreshAdjustSlots()), }, overrideOptions: (chainageM, patch) => { const hit = pipeFacilities.find( @@ -587,7 +588,9 @@ export function wireStructureSelection( const syncInletStructure = (): void => { const chainageM = panel.currentChainage(); const target = chainageM === null ? undefined : sectionAt(chainageM); - if (target) panel.facility.setInletStructure(stationControls.inletStructure.valueFor(target)); + if (!target) return; + panel.facility.setInletStructure(stationControls.inletStructure.valueFor(target)); + refreshAdjustSlots(); // 폼을 다시 그림 — 고른 상자 강조를 다시 얹음(54-29) }; const origRevet = stationControls.revetOffset.select; diff --git a/resources/tester/test_54_27_soil_tier_field.py b/resources/tester/test_54_27_soil_tier_field.py index b6fe0df3e..6ee475570 100644 --- a/resources/tester/test_54_27_soil_tier_field.py +++ b/resources/tester/test_54_27_soil_tier_field.py @@ -75,4 +75,5 @@ def test_자동_자리_읽기_글이_없음() -> None: def test_배관_유출_칸은_옛_단_수_줄을_안_받음() -> None: dock = _src("B06_Section/B06_Section_UI_Adjust_Dock.ts") - assert '".b06-structure-panel__struct--tier, ",\n "",' in dock + # 54-29 — 배관 유출 칸 = 집수정 내공 줄만(단 수 · 읽기 · 옵션 줄 안 받음) + assert 'const PIPE_OUTLET_ROWS = ".b06-structure-panel__struct--basin-size";' in dock diff --git a/resources/tester/test_54_29_pick_same_panel.py b/resources/tester/test_54_29_pick_same_panel.py new file mode 100644 index 000000000..5d6cd6073 --- /dev/null +++ b/resources/tester/test_54_29_pick_same_panel.py @@ -0,0 +1,46 @@ +"""횡단에서 고르기 · 목록에서 고르기 좌측 패널 같은 글 (PLAN 54-29). + +짝: `B06_Section/B06_Section_UI_Adjust_Dock.ts`(배관 칸 = 이름표 그대로 · 옵션 · 읽기 · 유출 단 수 줄 안 받음) · +`B06_Section/B06_Section_UI_Cross_Structure_Panel.ts`(배관 유입 벽 단 수 줄 = 선 단이 있을 때만) · +`B06_Section/B06_Section_UI_Page_Structures_Panel.ts`(폼을 다시 그린 뒤 강조 다시). +화면 확인은 ORCA(목록 · 횡단 innerText · 칸 수 · 값 같음 · 강조 상자 하나만 다름). +""" + +from __future__ import annotations + +import os +import re + +HERE = os.path.dirname(__file__) + + +def _src(rel: str) -> str: + with open(os.path.join(HERE, "..", "..", rel), encoding="utf-8") as f: + return f.read() + + +def test_배관_칸은_옵션_읽기_줄을_안_받음() -> None: + dock = _src("B06_Section/B06_Section_UI_Adjust_Dock.ts") + inlet = re.search(r"const PIPE_INLET_ROWS = \[(.*?)\]", dock, re.S) + assert inlet + assert "struct--options" not in inlet.group(1) + assert "struct--readout" not in inlet.group(1) + assert 'const PIPE_OUTLET_ROWS = ".b06-structure-panel__struct--basin-size";' in dock + + +def test_배관_칸_이름표는_그대로() -> None: + dock = _src("B06_Section/B06_Section_UI_Adjust_Dock.ts") + assert 'setGroupLabel(group, pipe ? "" : (panelRoot.dataset.panelTitle ?? ""));' in dock + + +def test_배관_유입_단_수_줄은_선_단이_있을_때만() -> None: + panel = _src("B06_Section/B06_Section_UI_Cross_Structure_Panel.ts") + assert "!isBasin && !deps.hiddenPipe()" in panel + assert "(pipeInlet && tiers.count === 0)" in panel + + +def test_폼을_다시_그리면_강조_다시() -> None: + page = _src("B06_Section/B06_Section_UI_Page_Structures_Panel.ts") + assert "recount: () => (section.facility.recount(), refreshAdjustSlots())" in page + sync = page[page.index("const syncInletStructure") :] + assert sync.index("refreshAdjustSlots()") < sync.index("};")