From 9bc9c9da86d2a4d9a04a7faa28de5c3f8f2ef448 Mon Sep 17 00:00:00 2001 From: ysCha Date: Tue, 7 Jul 2026 17:01:47 +0900 Subject: [PATCH] =?UTF-8?q?[2321]=20=EB=AA=A8=EB=93=88=EB=B0=B0=EC=B9=98?= =?UTF-8?q?=20=E5=8D=83=E9=B3=A5=E9=85=8D=E7=BD=AE(=EC=A7=80=EA=B7=B8?= =?UTF-8?q?=EC=9E=AC=EA=B7=B8=20=EB=B0=B0=EC=B9=98)=20=EA=B0=80=EB=B6=80?= =?UTF-8?q?=20=ED=8C=90=EC=A0=95=20=E2=80=94=20=EC=84=A0=ED=83=9D=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=EB=A9=B4(=EC=A7=80=EB=B6=95=EC=9E=AC)?= =?UTF-8?q?=EB=B3=84=20=EC=9E=AC=EA=B3=84=EC=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존: 마운트 1회 .some()으로 전체 지붕재 일괄 판정 (지붕재1 기준으로 고정되는 버그) - 변경: moduleSetupSurface 선택 변화마다 해당 지붕재만 재판정, 미선택/전체선택 시 전체 기준 - 不可 지붕재 선택 시 켜져 있던 千鳥 자동 해제 + 수동배치(手動配置) 3상태 초기화 - roofIndex 문자열/숫자 타입 불일치 방지: Number() 정규화 + null 필터 Co-Authored-By: Claude Opus 4 --- .../floor-plan/modal/basic/step/Placement.jsx | 36 ++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/components/floor-plan/modal/basic/step/Placement.jsx b/src/components/floor-plan/modal/basic/step/Placement.jsx index 2dced068..95f6fb3e 100644 --- a/src/components/floor-plan/modal/basic/step/Placement.jsx +++ b/src/components/floor-plan/modal/basic/step/Placement.jsx @@ -7,6 +7,7 @@ import { isManualModuleSetupState, moduleRowColArrayState, moduleSetupOptionState, + moduleSetupSurfaceState, toggleManualSetupModeState, } from '@/store/canvasAtom' import { useRecoilState, useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil' @@ -42,14 +43,39 @@ const Placement = forwardRef((props, refs) => { const [colspan, setColspan] = useState(1) const moduleRowColArray = useRecoilValue(moduleRowColArrayState) + const moduleSetupSurface = useRecoilValue(moduleSetupSurfaceState) //선택된 배치면 + + // 千鳥可否 는 지붕재별로 다르므로 선택된 배치면 기준으로 재판정한다. + // 일부 지붕재만 선택하면 그 지붕재 기준, 미선택이거나 모든 지붕재가 선택되면 전체 기준으로 + // 하나라도 不可(plvrYn==='N')면 千鳥 불가. + useEffect(() => { + const roofConstructions = moduleSelectionData?.roofConstructions + if (!roofConstructions?.length) return + + const plvrOf = (roofIndex) => roofConstructions.find((c) => Number(c.roofIndex) === Number(roofIndex))?.construction?.plvrYn + const allRoofIndexes = roofConstructions.map((c) => Number(c.roofIndex)) + const selectedRoofIndexes = [...new Set((moduleSetupSurface ?? []).filter((s) => s.roofMaterial?.index != null).map((s) => Number(s.roofMaterial.index)))] + + // 미선택 또는 모든 지붕재가 선택된 경우 = 전체 기준 + const useAll = selectedRoofIndexes.length === 0 || allRoofIndexes.every((roofIndex) => selectedRoofIndexes.includes(roofIndex)) + const targetRoofIndexes = useAll ? allRoofIndexes : selectedRoofIndexes + + const notAble = targetRoofIndexes.some((roofIndex) => plvrOf(roofIndex) === 'N') + setIsChidoriNotAble(notAble) + + // 不可 지붕재가 선택되면 켜져 있던 千鳥 를 자동 해제하고, 진행 중이던 수동배치도 초기화한다. + // (千鳥 오프셋이 바뀌면 기존/신규 모듈 배치가 섞이므로, 千鳥 수동 변경과 동일하게 수동 모드를 끈다) + if (notAble) { + setModuleSetupOption((prev) => (prev.isChidori ? { ...prev, isChidori: false } : prev)) + setIsManualModuleSetup(false) + setIsManualModuleLayoutSetup(false) + setManualSetupMode('off') + } + }, [moduleSetupSurface, moduleSelectionData]) + //모듈 배치면 생성 useEffect(() => { if (moduleSelectionData) { - //1개라도 치도리 불가가 있으면 치도리 불가 - const isChidroriValue = moduleSelectionData.roofConstructions.some((item) => item.construction.plvrYn === 'N') - if (isChidroriValue) { - setIsChidoriNotAble(true) - } makeModuleInitArea(moduleSelectionData) }