[1529] 시공법 버튼 constTp 매핑 — WORK_LV_ID_-2(標準施工Ⅱ) 신규 항목 대응 + 인덱스 밀림 방지

Co-Authored-By: Claude Opus 4 <noreply@anthropic.com>
This commit is contained in:
ysCha 2026-06-05 15:51:46 +09:00
parent b9fb769e74
commit 02062ee4d1
3 changed files with 50 additions and 57 deletions

View File

@ -1,6 +1,5 @@
import { useState, useEffect } from 'react' import { useState, useEffect } from 'react'
import { useMessage } from '@/hooks/useMessage' import { useMessage } from '@/hooks/useMessage'
import { isObjectNotEmpty } from '@/util/common-utils'
import QSelectBox from '@/components/common/select/QSelectBox' import QSelectBox from '@/components/common/select/QSelectBox'
import { useModuleTabContents } from '@/hooks/module/useModuleTabContents' import { useModuleTabContents } from '@/hooks/module/useModuleTabContents'
import { useRecoilValue } from 'recoil' import { useRecoilValue } from 'recoil'
@ -170,41 +169,32 @@ export default function ModuleTabContents({ tabIndex, addRoof, setAddedRoofs, ro
</div> </div>
<div className="module-flex-item non-flex"> <div className="module-flex-item non-flex">
<div className="flex-item-btn-wrap"> <div className="flex-item-btn-wrap">
<button {/* 2026-06-05 공법 버튼을 배열 인덱스 대신 constTp로 매핑 — API 응답 항목 추가/순서변경(예: 標準施工(Ⅱ) WORK_LV_ID_-2) 시 인덱스 밀림 방지. 운영(구 API)엔 -2가 없어 optional 은 데이터 있을 때만 렌더 */}
className={`btn-frame roof ${isObjectNotEmpty(constructionList[0]) && constructionList[0].constPossYn === 'Y' ? 'white' : ''}`} {[
ref={(el) => (constructionRef.current[0] = el)} { constTp: 'WORK_LV_ID_-1', label: '標準施工()' },
onClick={() => (isObjectNotEmpty(constructionList[0]) && constructionList[0].constPossYn === 'Y' ? handleConstruction(0) : null)} { constTp: 'WORK_LV_ID_-2', label: '標準施工(Ⅱ)', optional: true },
> { constTp: 'WORK_LV_ID_1', label: '標準施工' },
標準施工() { constTp: 'WORK_LV_ID_3', label: '強化施工' },
</button> { constTp: 'WORK_LV_ID_4', label: '多設施工' },
<button { constTp: 'WORK_LV_ID_5', label: '多設施工II' },
className={`btn-frame roof ${isObjectNotEmpty(constructionList[3]) && constructionList[3].constPossYn === 'Y' ? 'white' : ''}`} ].map(({ constTp, label, optional }) => {
ref={(el) => (constructionRef.current[3] = el)} const index = constructionList.findIndex((c) => c.constTp === constTp)
onClick={() => (isObjectNotEmpty(constructionList[3]) && constructionList[3].constPossYn === 'Y' ? handleConstruction(3) : null)} const item = index > -1 ? constructionList[index] : null
> if (optional && !item) return null
多設施工 const enabled = item && item.constPossYn === 'Y'
</button> return (
<button <button
className={`btn-frame roof ${isObjectNotEmpty(constructionList[1]) && constructionList[1].constPossYn === 'Y' ? 'white' : ''}`} key={constTp}
ref={(el) => (constructionRef.current[1] = el)} className={`btn-frame roof ${enabled ? 'white' : ''}`}
onClick={() => (isObjectNotEmpty(constructionList[1]) && constructionList[1].constPossYn === 'Y' ? handleConstruction(1) : null)} ref={(el) => {
> if (index > -1) constructionRef.current[index] = el
標準施工 }}
</button> onClick={() => (enabled ? handleConstruction(index) : null)}
<button >
className={`btn-frame roof ${isObjectNotEmpty(constructionList[4]) && constructionList[4].constPossYn === 'Y' ? 'white' : ''}`} {label}
ref={(el) => (constructionRef.current[4] = el)} </button>
onClick={() => (isObjectNotEmpty(constructionList[4]) && constructionList[4].constPossYn === 'Y' ? handleConstruction(4) : null)} )
> })}
多設施工II
</button>
<button
className={`btn-frame roof ${isObjectNotEmpty(constructionList[2]) && constructionList[2].constPossYn === 'Y' ? 'white' : ''}`}
ref={(el) => (constructionRef.current[2] = el)}
onClick={() => (isObjectNotEmpty(constructionList[2]) && constructionList[2].constPossYn === 'Y' ? handleConstruction(2) : null)}
>
強化施工
</button>
</div> </div>
<div className="grid-check-form-block"> <div className="grid-check-form-block">
<div className="d-check-box pop"> <div className="d-check-box pop">

View File

@ -217,7 +217,7 @@ const Trestle = forwardRef((props, ref) => {
}, [constructionList, autoSelectStep]) }, [constructionList, autoSelectStep])
const getConstructionState = (index) => { const getConstructionState = (index) => {
if (constructionList && constructionList.length > 0) { if (index > -1 && constructionList && constructionList.length > 0 && constructionList[index]) {
if (constructionList[index].constPossYn === 'Y') { if (constructionList[index].constPossYn === 'Y') {
if (trestleState && trestleState.constTp === constructionList[index].constTp) { if (trestleState && trestleState.constTp === constructionList[index].constTp) {
return 'blue' return 'blue'
@ -865,21 +865,23 @@ const Trestle = forwardRef((props, ref) => {
</div> </div>
<div className="module-flex-item non-flex"> <div className="module-flex-item non-flex">
<div className="flex-item-btn-wrap"> <div className="flex-item-btn-wrap">
<button className={`btn-frame roof ${getConstructionState(0)}`} onClick={() => handleConstruction(0)}> {/* 2026-06-05 공법 버튼을 배열 인덱스 대신 constTp로 매핑 — API 응답 항목 추가/순서변경(예: 標準施工(II) WORK_LV_ID_-2) 시 인덱스 밀림 방지. 운영(구 API)엔 -2가 없어 optional 은 데이터 있을 때만 렌더 */}
{getMessage('modal.module.basic.setting.module.standard.construction')}(I) {[
</button> { constTp: 'WORK_LV_ID_-1', label: `${getMessage('modal.module.basic.setting.module.standard.construction')}(I)` },
<button className={`btn-frame roof ${getConstructionState(3)}`} onClick={() => handleConstruction(3)}> { constTp: 'WORK_LV_ID_-2', label: `${getMessage('modal.module.basic.setting.module.standard.construction')}(II)`, optional: true },
{getMessage('modal.module.basic.setting.module.multiple.construction')} { constTp: 'WORK_LV_ID_1', label: getMessage('modal.module.basic.setting.module.standard.construction') },
</button> { constTp: 'WORK_LV_ID_3', label: getMessage('modal.module.basic.setting.module.enforce.construction') },
<button className={`btn-frame roof ${getConstructionState(1)}`} onClick={() => handleConstruction(1)}> { constTp: 'WORK_LV_ID_4', label: getMessage('modal.module.basic.setting.module.multiple.construction') },
{getMessage('modal.module.basic.setting.module.standard.construction')} { constTp: 'WORK_LV_ID_5', label: `${getMessage('modal.module.basic.setting.module.multiple.construction')}(II)` },
</button> ].map(({ constTp, label, optional }) => {
<button className={`btn-frame roof ${getConstructionState(4)}`} onClick={() => handleConstruction(4)}> const index = constructionList.findIndex((c) => c.constTp === constTp)
{getMessage('modal.module.basic.setting.module.multiple.construction')}(II) if (optional && index === -1) return null
</button> return (
<button className={`btn-frame roof ${getConstructionState(2)}`} onClick={() => handleConstruction(2)}> <button key={constTp} className={`btn-frame roof ${getConstructionState(index)}`} onClick={() => handleConstruction(index)}>
{getMessage('modal.module.basic.setting.module.enforce.construction')} {label}
</button> </button>
)
})}
</div> </div>
<div className="grid-check-form-flex"> <div className="grid-check-form-flex">
<div className="d-check-box pop"> <div className="d-check-box pop">

View File

@ -175,9 +175,10 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
isObjectNotEmpty(moduleConstructionSelectionData?.construction) && isObjectNotEmpty(moduleConstructionSelectionData?.construction) &&
moduleConstructionSelectionData?.construction.hasOwnProperty('constPossYn') ///키가 있으면 moduleConstructionSelectionData?.construction.hasOwnProperty('constPossYn') ///키가 있으면
) { ) {
const selectedIndex = moduleConstructionSelectionData.construction.selectedIndex // 2026-06-05 저장값 복원도 constTp 기준 — 항목 추가/순서변경으로 selectedIndex 가 어긋나는 문제 방지
const construction = constructionList[selectedIndex] const selectedIndex = constructionList.findIndex((c) => c.constTp === moduleConstructionSelectionData.construction.constTp)
if (construction.constPossYn === 'Y') { const construction = selectedIndex > -1 ? constructionList[selectedIndex] : null
if (construction && construction.constPossYn === 'Y') {
handleConstruction(selectedIndex) handleConstruction(selectedIndex)
} }
} }
@ -268,7 +269,7 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
const handleConstruction = (index) => { const handleConstruction = (index) => {
if (index > -1) { if (index > -1) {
const isPossibleIndex = constructionRef.current const isPossibleIndex = constructionRef.current
.map((el, i) => (el.classList.contains('white') || el.classList.contains('blue') ? i : -1)) .map((el, i) => (el && (el.classList.contains('white') || el.classList.contains('blue')) ? i : -1))
.filter((index) => index !== -1) .filter((index) => index !== -1)
isPossibleIndex.forEach((index) => { isPossibleIndex.forEach((index) => {
@ -341,7 +342,7 @@ export function useModuleTabContents({ tabIndex, addRoof, setAddedRoofs, roofTab
setSelectedConstruction(selectedConstruction) setSelectedConstruction(selectedConstruction)
} else { } else {
constructionRef.current.forEach((ref) => { constructionRef.current.forEach((ref) => {
ref.classList.remove('blue') if (ref) ref.classList.remove('blue')
}) })
} }
} }