feat: 지붕재적합성 메인 체크 시 하위 전체체크 처리 추가

This commit is contained in:
Daseul Kim 2025-05-23 10:45:14 +09:00
parent a25538319a
commit 36d5191311
3 changed files with 22 additions and 8 deletions

View File

@ -9,7 +9,7 @@ import { useSuitableStore } from '@/store/useSuitableStore'
import { SUITABLE_HEAD_CODE, type Suitable, type SuitableDetail } from '@/types/Suitable' import { SUITABLE_HEAD_CODE, type Suitable, type SuitableDetail } from '@/types/Suitable'
export default function SuitableList() { export default function SuitableList() {
const { toCodeName, toSuitableDetail, suitables, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = useSuitable() const { toCodeName, toSuitableDetail, toSuitableDetailIds, suitables, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = useSuitable()
const { selectedItems, addSelectedItem, removeSelectedItem } = useSuitableStore() const { selectedItems, addSelectedItem, removeSelectedItem } = useSuitableStore()
const [openItems, setOpenItems] = useState<Set<number>>(new Set()) const [openItems, setOpenItems] = useState<Set<number>>(new Set())
const observerTarget = useRef<HTMLDivElement>(null) const observerTarget = useRef<HTMLDivElement>(null)
@ -37,8 +37,8 @@ export default function SuitableList() {
// 아이템 클릭 // 아이템 클릭
const handleItemClick = useCallback( const handleItemClick = useCallback(
(mainId: number, detailId?: number): void => { (mainId: number, detailId?: number, detailIds?: Set<number>): void => {
isItemSelected(mainId, detailId) ? removeSelectedItem(mainId, detailId) : addSelectedItem(mainId, detailId) isItemSelected(mainId, detailId) ? removeSelectedItem(mainId, detailId) : addSelectedItem(mainId, detailId, detailIds)
}, },
[isItemSelected, addSelectedItem, removeSelectedItem], [isItemSelected, addSelectedItem, removeSelectedItem],
) )
@ -73,7 +73,12 @@ export default function SuitableList() {
<div className={`compliance-check-bx ${openItems.has(item.id) ? 'act' : ''}`} key={item.id}> <div className={`compliance-check-bx ${openItems.has(item.id) ? 'act' : ''}`} key={item.id}>
<div className="check-name-wrap"> <div className="check-name-wrap">
<div className={`check-form-box ${isMainIndeterminate(item.id, item.detailCnt) ? 'space' : ''}`}> <div className={`check-form-box ${isMainIndeterminate(item.id, item.detailCnt) ? 'space' : ''}`}>
<input type="checkbox" id={`ch${item.id}`} checked={isItemSelected(item.id)} onChange={() => handleItemClick(item.id)} /> <input
type="checkbox"
id={`ch${item.id}`}
checked={isItemSelected(item.id)}
onChange={() => handleItemClick(item.id, undefined, toSuitableDetailIds(item.detail))}
/>
<label htmlFor={`ch${item.id}`}>{item.productName}</label> <label htmlFor={`ch${item.id}`}>{item.productName}</label>
</div> </div>
<div className="check-name-btn"> <div className="check-name-btn">

View File

@ -9,7 +9,6 @@ export function useSuitable() {
const { axiosInstance } = useAxios() const { axiosInstance } = useAxios()
const { getCommCode } = useCommCode() const { getCommCode } = useCommCode()
const { itemPerPage, selectedCategory, searchValue, suitableCommCode, setSuitableCommCode, isSearch } = useSuitableStore() const { itemPerPage, selectedCategory, searchValue, suitableCommCode, setSuitableCommCode, isSearch } = useSuitableStore()
const getSuitables = async ({ const getSuitables = async ({
pageNumber, pageNumber,
@ -66,6 +65,15 @@ export function useSuitable() {
} }
} }
const toSuitableDetailIds = (suitableDetailString: string): Set<number> => {
try {
return new Set<number>(JSON.parse(suitableDetailString).map(({ id }: { id: number }) => id))
} catch (error) {
console.error('지붕재 데이터 파싱 실패:', error)
return new Set()
}
}
const { const {
data: suitables, data: suitables,
fetchNextPage, fetchNextPage,
@ -97,6 +105,7 @@ export function useSuitable() {
getSuitableCommCode, getSuitableCommCode,
toCodeName, toCodeName,
toSuitableDetail, toSuitableDetail,
toSuitableDetailIds,
suitables, suitables,
fetchNextPage, fetchNextPage,
hasNextPage, hasNextPage,

View File

@ -28,7 +28,7 @@ interface SuitableState {
/* 선택된 아이템 리스트 */ /* 선택된 아이템 리스트 */
selectedItems: Map<number, Set<number>> selectedItems: Map<number, Set<number>>
/* 선택된 아이템 추가 */ /* 선택된 아이템 추가 */
addSelectedItem: (mainId: number, detailId?: number) => void addSelectedItem: (mainId: number, detailId?: number, detailIds?: Set<number>) => void
/* 선택된 아이템 제거 */ /* 선택된 아이템 제거 */
removeSelectedItem: (mainId: number, detailId?: number) => void removeSelectedItem: (mainId: number, detailId?: number) => void
/* 선택된 아이템 모두 제거 */ /* 선택된 아이템 모두 제거 */
@ -59,7 +59,7 @@ export const useSuitableStore = create<SuitableState>((set) => ({
setSearchValue: (value: string) => set({ searchValue: value }), setSearchValue: (value: string) => set({ searchValue: value }),
/* 선택된 아이템 추가 */ /* 선택된 아이템 추가 */
addSelectedItem: (mainId: number, detailId?: number) => { addSelectedItem: (mainId: number, detailId?: number, detailIds?: Set<number>) => {
if (detailId) { if (detailId) {
// 디테일(하위) 아이템 추가 // 디테일(하위) 아이템 추가
set((state) => { set((state) => {
@ -71,7 +71,7 @@ export const useSuitableStore = create<SuitableState>((set) => ({
} else { } else {
// 메인(상위) 아이템 추가 // 메인(상위) 아이템 추가
set((state) => { set((state) => {
state.selectedItems.set(mainId, new Set()) state.selectedItems.set(mainId, detailIds || new Set())
return { selectedItems: state.selectedItems } return { selectedItems: state.selectedItems }
}) })
} }