183 lines
8.7 KiB
TypeScript
183 lines
8.7 KiB
TypeScript
"use client"
|
|
import NewWindowPortal from '@/app/(with-layout)/map/components/newWindowPortal';
|
|
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
|
|
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
|
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
|
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
|
|
import { useGisContext } from "@common/business_components/ui/map/Gis";
|
|
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
|
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
import ResueFacility from './layerPopup/reuseFacility';
|
|
import { detainSttn, fetchHasuDetail, fetchpbnstDetail } from '../../../(popUp-layout)/util';
|
|
import HasuFacility from './layerPopup/hasuFacility';
|
|
import RainFacility from './layerPopup/rainFacility';
|
|
import RswtFacility from './layerPopup/rswtFacility';
|
|
import HtdflFacility from './layerPopup/htdflFacility';
|
|
import ReuseMngFacility from './layerPopup/reuseMngFacility';
|
|
|
|
interface NewWindowPopupProps {
|
|
featureData: any;
|
|
seletectedLayerNm?: string
|
|
onFeatureSelect: (data: any) => void;
|
|
onClose: () => void;
|
|
}
|
|
|
|
const NewWindowPopup22: React.FC<NewWindowPopupProps> = ({
|
|
featureData,
|
|
seletectedLayerNm,
|
|
onFeatureSelect,
|
|
onClose
|
|
}) => {
|
|
const { gisMap } = useGisContext() as unknown as { checkedLayerIds: React.MutableRefObject<number[]>; treeData: { lyrSn: number }[] | null; gisCore: any; gisMap: any; };
|
|
const [tabData, setTabData] = useState<{ id: string; name: string; data: any }[]>([]);
|
|
const [activeTab, setActiveTab] = useState<string>('0');
|
|
const [viewMode, setViewMode] = useState<'list' | 'detail' | 'nothing'>('list');
|
|
const [fcltPk, setFcltPk] = useState<string>('');
|
|
|
|
|
|
// onClose 함수를 useCallback으로 메모이제이션
|
|
const memoizedOnClose = useCallback(() => {
|
|
onClose();
|
|
}, [onClose]);
|
|
|
|
// 빗물재이용시설 변수
|
|
const [rainDetailModal, setRainDetailModal] = useState<{ isOpen: boolean, data: customRainBdst | undefined }>({ data: undefined, isOpen: false });
|
|
const [rainList, setRainList] = useState<customRainBdst[]>([]);
|
|
|
|
// 중수도시설 변수
|
|
const [rswtrDetailModal, setRswtrDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false });
|
|
const [rswtrList, setRswtrList] = useState<customRswtBdst[]>([]);
|
|
|
|
// 온배수시설 변수
|
|
const [htdflDetailModal, setHtdflDetailModal] = useState<{ isOpen: boolean, data: customHtdflBdst | undefined }>({ data: undefined, isOpen: false });
|
|
const [htdflList, setHtdflList] = useState<customHtdflBdst[]>([]);
|
|
|
|
// 하수처리시설 변수
|
|
const [hasuList, setHasuList] = useState<pubHasuType[]>([]);
|
|
const [isRuseReg, setIsRuseReg] = useState<{
|
|
data: any | undefined;
|
|
}>({ data: undefined });
|
|
|
|
// 수요처관리 변수
|
|
const [isDmdModal, setIsDmdModal] = useState<{
|
|
isMoal: boolean;
|
|
data: any | undefined;
|
|
}>({ isMoal: false, data: undefined });
|
|
const [mngList, setMngList] = useState<DemandCompType[]>([]);
|
|
|
|
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
|
|
const getSelectedLayers = () => {
|
|
console.trace('호출확인', 1)
|
|
let result = null;
|
|
const layers = gisMap ? gisMap.getLayers().getArray().filter((l: any) => l.getVisible()) : []; // gisMap이 null인지 확인 후 레이어 가져오기
|
|
let featureLayer: { get: (key: string) => any } = { get: () => null };
|
|
layers.forEach((layer: any) => {
|
|
const source = layer.getSource();
|
|
if (source && source.hasFeature && featureData
|
|
&& typeof featureData.getId === 'function' && source.hasFeature(featureData)) {
|
|
featureLayer = layer; // 피처가 속한 레이어 찾기)
|
|
}
|
|
});
|
|
result = featureLayer.get('lyrNm');
|
|
return result;
|
|
};
|
|
// 상세 목록 데이터 상태 처리
|
|
useEffect(() => {
|
|
if (hasuList.length > 0) setIsRuseReg({ data: [hasuList[0]] });
|
|
}, [hasuList])
|
|
useEffect(() => {
|
|
if (rainList.length > 0) setRainDetailModal({ isOpen: true, data: rainList[0] });
|
|
}, [rainList])
|
|
useEffect(() => {
|
|
if (rswtrList.length > 0) setRswtrDetailModal({ isOpen: true, data: rswtrList[0] });
|
|
}, [rswtrList])
|
|
useEffect(() => {
|
|
if (htdflList.length > 0) setHtdflDetailModal({ isOpen: true, data: htdflList[0] });
|
|
}, [htdflList])
|
|
useEffect(() => {
|
|
if (mngList.length > 0) setIsDmdModal({ isMoal: true, data: [mngList[0]] });
|
|
}, [mngList])
|
|
|
|
const lastCalledIdRef = useRef<string | null>(null);
|
|
const [layerId, setLayerId] = useState<string | null>();
|
|
|
|
useEffect(() => {
|
|
const layers = getSelectedLayers();
|
|
setLayerId(layers);
|
|
}, []); // 최초 렌더링 시 호출
|
|
|
|
// 피쳐 데이터가 변경될 때마다 호출
|
|
useEffect(() => {
|
|
if (!featureData || typeof featureData.getProperties !== "function" || featureData.getProperties() == '') return;
|
|
const selectedProps = featureData.getProperties();
|
|
const currentId = featureData.getId?.() || selectedProps?.id || selectedProps?.fid;
|
|
// 유효하지 않은 ID는 아예 무시
|
|
if (!currentId || typeof currentId !== 'string') return;
|
|
// 이전과 동일하면 무시
|
|
if (!currentId || currentId === lastCalledIdRef.current) return;
|
|
lastCalledIdRef.current = currentId // 새로운 피처일 때만 API 호출
|
|
const layerId = getSelectedLayers?.();
|
|
if (!layerId || typeof layerId !== 'string') return;
|
|
const featureCd =
|
|
layerId === '하수재이용시설' ? selectedProps?.swtrmt_fclt_cd :
|
|
['빗물이용시설', '중수도시설', '온배수시설', '수요처'].includes(layerId) ? selectedProps?.bdst_nm :
|
|
layerId === '하수처리시설' ? selectedProps?.swtrmt_fclt_nm :
|
|
null;
|
|
if (!featureCd || featureCd === fcltPk) return;
|
|
if (layerId === '하수재이용시설') {
|
|
fetchpbnstDetail(featureCd, setTabData);
|
|
} else if (layerId === '하수처리시설') {
|
|
fetchHasuDetail(featureCd, selectedProps?.swtrmt_fclt_cd).then((data) => { setHasuList(data) })
|
|
} else {
|
|
detainSttn(featureCd, layerId).then((res) => {
|
|
if (layerId === '빗물이용시설') setRainList(res);
|
|
else if (layerId === '중수도시설') setRswtrList(res);
|
|
else if (layerId === '온배수시설') { setHtdflList(res); setHtdflDetailModal({ isOpen: true, data: res[0] }); }
|
|
else if (layerId === '수요처') setMngList(res);
|
|
});
|
|
}
|
|
setFcltPk(featureCd);
|
|
setActiveTab(featureCd);
|
|
setViewMode("detail");
|
|
}, [featureData]);
|
|
///////////////////////////////////////////// 피쳐데이터 선택 시 각 시설별 데이터 처리 ///////////////////////////////////////////////
|
|
|
|
// 체크된 레이어에 따른 조건부 컴포넌트 렌더링 함수
|
|
const renderConditionalContent = () => {
|
|
const actTabData = tabData.find((tab) => tab.id === activeTab);
|
|
if (layerId === null || layerId === undefined) {
|
|
setLayerId(seletectedLayerNm || '');
|
|
}
|
|
switch (layerId) {
|
|
case '하수재이용시설':
|
|
return (<ResueFacility viewMode={viewMode} seletectedLayerNm={layerId} tabData={tabData} actTabData={actTabData} setFcltPk={setFcltPk} onFeatureSelect={onFeatureSelect} onClose={onClose} />)
|
|
case '하수처리시설':
|
|
return (<HasuFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} isRuseReg={isRuseReg} />)
|
|
case '빗물이용시설':
|
|
return (<RainFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} rainDetailModal={rainDetailModal} />)
|
|
case '중수도시설':
|
|
return (<RswtFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} rswtrDetailModal={rswtrDetailModal} />)
|
|
case '온배수시설':
|
|
return (<HtdflFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} htdflDetailModal={htdflDetailModal} />)
|
|
case '수요처':
|
|
return(<ReuseMngFacility seletectedLayerNm={layerId} viewMode={viewMode} onFeatureSelect={onFeatureSelect} onClose={onClose} isDmdModal={isDmdModal} />)
|
|
default:
|
|
break;
|
|
}
|
|
return null; // 조건에 맞는 콘텐츠가 없을 경우
|
|
};
|
|
return (
|
|
viewMode == 'nothing' ? <></> :
|
|
<NewWindowPortal
|
|
onClose={memoizedOnClose}
|
|
title="시설 상세 정보"
|
|
scrollbars='yes'
|
|
viewMode={viewMode}
|
|
resizable='no'>
|
|
{/* 체크된 레이어에 따른 조건부 렌더링 */}
|
|
{renderConditionalContent()}
|
|
</NewWindowPortal>
|
|
);
|
|
};
|
|
|
|
export default NewWindowPopup22; |