지도 수정완료 하지만 팝업 크기 조정해야함
This commit is contained in:
@@ -1,150 +0,0 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { btnClass } from "@/app/store/common/code";
|
||||
import { pbnMapTableSize } from "@/app/store/map/pbnstMap";
|
||||
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import {
|
||||
ContentsDiv,
|
||||
SearchBaseForm,
|
||||
SearchInput,
|
||||
Title,
|
||||
UiTable,
|
||||
type ReturnType,
|
||||
} from "@common/business_components/ui";
|
||||
import { Label } from "@common/components/ui";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: "list" | "detail" | "nothing";
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
isRuseReg: { data: any | undefined };
|
||||
}
|
||||
const HasuFacility = ({
|
||||
seletectedLayerNm,
|
||||
viewMode,
|
||||
onClose,
|
||||
onFeatureSelect,
|
||||
isRuseReg,
|
||||
}: Props) => {
|
||||
const { code, pbnMap, pbnMapInit } = useWrStore((state) => state);
|
||||
const { pbnMapHeadList, pbnMapRes, pbnMapCount } = pbnMap;
|
||||
const [hasuTable, setHasuTable] = useState<pubHasuType[]>();
|
||||
const [isReset, setIsReset] = useState(false);
|
||||
const [pbnRuseNm, setPbnRuseNm] = useState<string>("");
|
||||
|
||||
const ref = useRef<ReturnType>({} as ReturnType);
|
||||
useEffect(() => {
|
||||
if (code.sggCd.length && pbnMapRes.length > 0) {
|
||||
setHasuTable(tableData(pbnMapRes, { code }));
|
||||
}
|
||||
}, [code, pbnMapRes]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== "하수처리시설" || viewMode != "list") return;
|
||||
if (!pbnMap.isInit) {
|
||||
|
||||
console.log('ref.current ', ref.current)
|
||||
pbnMapInit(1, pbnMapTableSize, ref.current);
|
||||
}
|
||||
}, [pbnMap.isInit, pbnMapInit]);
|
||||
|
||||
const hasuCellClick = (index: number | undefined) => {
|
||||
if (index !== undefined && pbnMapRes !== undefined) {
|
||||
onFeatureSelect(pbnMapRes[index]);
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
return viewMode == "list" ? (
|
||||
<ContentsDiv>
|
||||
<div className="grid grid-cols-2 gap-4 ">
|
||||
<div className="col-span-2">
|
||||
<Title title="하수처리시설 현황" />
|
||||
<SearchBaseForm
|
||||
selectSidoData={code.cityCd}
|
||||
selectSigunData={code.sggCd}
|
||||
selectRegionData={code.rvbsnCd}
|
||||
selectUnitWaterShedData={code.lgbsnCd}
|
||||
selectMiddleRegionData={code.mdmbsnCd}
|
||||
selectEnvPartData={code.lclgvrnmntCd}
|
||||
buttonOrder={["query", "init", "excel"]}
|
||||
rightClassName="ml-auto mr-6 flex items-center space-x-1"
|
||||
leftClassName="flex gap-5 w-9/12 m-4"
|
||||
leftSelectClassName="w-1/4"
|
||||
rightChildren={<></>}
|
||||
leftChildren={
|
||||
<div className="col-span-3 flex items-center">
|
||||
<Label className="w-full mt-2 ml-4 text-xl text-gray-600">
|
||||
{"하수처리시설명"}
|
||||
</Label>
|
||||
<SearchInput
|
||||
className={"text-2xl w-full"}
|
||||
label=""
|
||||
textValue={pbnRuseNm || ""}
|
||||
setText={(e) => {
|
||||
setPbnRuseNm(e || "");
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
queryClick={() => {
|
||||
setIsReset(true);
|
||||
}}
|
||||
initClick={function (): void {
|
||||
setPbnRuseNm("");
|
||||
}}
|
||||
btnClass={btnClass}
|
||||
ref={ref}
|
||||
isAdmin={false}
|
||||
excelClick={function (returnType: ReturnType): void {
|
||||
console.log("pbnstSttnSearch ", returnType);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-span-6">
|
||||
{/* 높이 조정 */}
|
||||
<UiTable
|
||||
tableData={hasuTable || []}
|
||||
headlist={pbnMapHeadList}
|
||||
pageSize={pbnMapTableSize}
|
||||
total={pbnMapCount || 0}
|
||||
headName={""}
|
||||
cellClick={hasuCellClick}
|
||||
onPageChange={(page) => {
|
||||
pbnMapInit(page, pbnMapTableSize, ref.current);
|
||||
setIsReset(false);
|
||||
}}
|
||||
resetPageNo={isReset}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</ContentsDiv>
|
||||
) : (
|
||||
<div style={{ overflowX: "hidden" }}>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title title="하수처리시설 상세정보" />
|
||||
</div>
|
||||
{/* 높이 조정 */}
|
||||
<UiTable
|
||||
tableData={isRuseReg?.data || []}
|
||||
headlist={pbnMapHeadList.slice(0, 4)}
|
||||
pageSize={1}
|
||||
total={0}
|
||||
headName={"위치정보"}
|
||||
cellClick={() => {}}
|
||||
onPageChange={() => {}}
|
||||
/>
|
||||
<UiTable
|
||||
tableData={isRuseReg?.data || []}
|
||||
headlist={pbnMapHeadList.slice(4)}
|
||||
pageSize={1}
|
||||
total={0}
|
||||
headName={"기본정보"}
|
||||
cellClick={() => {}}
|
||||
onPageChange={() => {}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
export default HasuFacility;
|
||||
@@ -1,83 +0,0 @@
|
||||
import { useWrStore } from '@/app/store';
|
||||
import type { customHtdflBdst } from '@/app/store/ruseFcltMng/fcltReg/htdflReg';
|
||||
import { tableData } from '@/components/lib/func/commom';
|
||||
import SttnDetailModal from '@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal';
|
||||
import { Title, UiTable } from '@common/business_components/ui';
|
||||
import { HeadMakeColSpan } from '@common/business_components/ui/table/HeadMakeColSpan';
|
||||
import React, { useEffect, useState } from 'react'
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
htdflDetailModal: { isOpen: boolean; data: customHtdflBdst | undefined };
|
||||
}
|
||||
const HtdflFacility = ({ seletectedLayerNm, viewMode, onFeatureSelect, onClose, htdflDetailModal }: Props) => {
|
||||
const { code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state);
|
||||
const { htdflSttnRes, htdflSttnResCount } = htdflSttn;
|
||||
const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>();
|
||||
const [htdflPage, setHtdflPage] = useState(1)
|
||||
// 온배수시설 cellClick 이벤트 (상세정보)
|
||||
const htdflCellClick = (index: number | undefined) => {
|
||||
if (index !== undefined && htdflTable !== undefined) {
|
||||
onFeatureSelect(htdflTable[index]);
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
|
||||
if (!htdflSttn.isInit) {
|
||||
initHtdfl(false, 1, "20", "0", '', code.cityCd, code.sggCd);
|
||||
}
|
||||
}, [code.cityCd, code.sggCd, htdflSttn.isInit, initHtdfl]);
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
|
||||
const data = tableData(htdflSttnRes, { code });
|
||||
const chData = data
|
||||
.map((item: any) => ({
|
||||
...item,
|
||||
...item.reuseBuilding[0],
|
||||
...item.reuseBuilding[0].htdflObj,
|
||||
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
|
||||
}))
|
||||
.filter((item: any) => item.htdflObj !== undefined);
|
||||
setHtdflTable(chData);
|
||||
}, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]);
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
|
||||
htdflSttnSearch(true, htdflPage, "20", '', '', code.cityCd, code.sggCd);
|
||||
}, [code.cityCd, code.sggCd, htdflPage, htdflSttnSearch]);
|
||||
return (
|
||||
viewMode == 'detail' ? (
|
||||
<SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst} />
|
||||
) : (
|
||||
<div style={{ overflowY: 'auto' }}>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="온배수시설 현황" />
|
||||
{/* <div className="flex gap-2 mt-8">
|
||||
<Button className={btnClass} color="primary" onClick={excelClick}>
|
||||
엑셀다운로드
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={htdflTable || []}
|
||||
headlist={htdflSttn.htdflSttHeadList}
|
||||
pageSize={20}
|
||||
total={htdflSttnResCount || 0}
|
||||
cellClick={(index: number | undefined) => {
|
||||
htdflCellClick(index ?? undefined);
|
||||
}}
|
||||
onPageChange={setHtdflPage}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
|
||||
</UiTable>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export default HtdflFacility
|
||||
@@ -1,105 +0,0 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
|
||||
import { Title, UiTable } from "@common/business_components/ui";
|
||||
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
|
||||
import { useEffect, useState } from "react";
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
rainDetailModal: { isOpen: boolean; data: customRainBdst | undefined };
|
||||
}
|
||||
const RainFacility = ({seletectedLayerNm,viewMode,onFeatureSelect,onClose,rainDetailModal}:Props) => {
|
||||
// 빗물재이용시설 변수
|
||||
const { code, rainSttn, rainSttnSearch, rainSttnInit } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
const { rainSttnRes, rainSttnResCount } = rainSttn;
|
||||
const [rainTable, setRainTable] = useState<customRainBdst[]>();
|
||||
const [rainPage, setRainPage] = useState(1)
|
||||
|
||||
// 빗물재이용시설 cellClick 이벤트 (상세정보)
|
||||
const rainCellClick = (index: number | undefined, headId: string) => {
|
||||
if (
|
||||
index !== undefined &&
|
||||
rainTable !== undefined &&
|
||||
headId !== 'chBuildingYn') {
|
||||
onFeatureSelect(rainTable[index]);
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '빗물이용시설' || viewMode != 'list') return;
|
||||
console.log('빗물이용시설 초기값 호출', viewMode)
|
||||
if (!rainSttn.isInit) {
|
||||
rainSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
|
||||
}
|
||||
}, [code.cityCd, code.sggCd, rainSttn.isInit, rainSttnInit]);
|
||||
|
||||
useEffect(() => {
|
||||
const data = tableData(rainSttnRes, { code });
|
||||
const chData = data
|
||||
.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
...item.reuseBuilding[0],
|
||||
...item.reuseBuilding[0].rainyObj,
|
||||
dtfcltCpct: item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
|
||||
instlCst: item.reuseBuilding[0].instlCst === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].instlCst,
|
||||
instlCstSprtAmt: item.reuseBuilding[0].instlCstSprtAmt === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].instlCstSprtAmt,
|
||||
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
|
||||
pntfColArea: item.reuseBuilding[0].rainyObj.pntfColArea === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].rainyObj.pntfColArea,
|
||||
filtrTrtmfctCpct: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
|
||||
archArea: Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
|
||||
};
|
||||
})
|
||||
.filter((item: any) => item.rainyObj !== undefined);
|
||||
setRainTable(chData);
|
||||
}, [code, rainSttnRes, rainSttn.rainSttHeadList]);
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '빗물이용시설' || viewMode != 'list') return;
|
||||
rainSttnSearch(false, rainPage, "20", '', '', code.cityCd, code.sggCd);
|
||||
}, [code.cityCd, code.sggCd, rainPage, rainSttnSearch]);
|
||||
return (viewMode == 'detail' ?
|
||||
(<SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} />)
|
||||
: (
|
||||
<>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="빗물이용시설 현황" />
|
||||
{/* <div className="flex gap-2 mt-8">
|
||||
<Button className={btnClass} color="primary" onClick={excelClick}>
|
||||
엑셀다운로드
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={rainTable || []}
|
||||
headlist={rainSttn.rainSttHeadList}
|
||||
pageSize={20}
|
||||
total={rainSttnResCount}
|
||||
cellClick={(index: number | undefined, headId: string) => {
|
||||
rainCellClick(index ?? undefined, headId);
|
||||
}}
|
||||
onPageChange={setRainPage}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
|
||||
</UiTable>
|
||||
</>
|
||||
))
|
||||
}
|
||||
export default RainFacility;
|
||||
@@ -1,146 +0,0 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
|
||||
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
|
||||
import { Title, UITab, UiTable } from "@common/business_components/ui";
|
||||
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
setFcltPk: (pk: string) => void;
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
actTabData: { id: string; name: string; data: any } | undefined;
|
||||
tabData: { id: string; name: string; data: any }[];
|
||||
}
|
||||
const ResueFacility = ({ viewMode, seletectedLayerNm, tabData, actTabData, setFcltPk, onFeatureSelect, onClose}: Props) => {
|
||||
const [activeTab, setActiveTab] = useState<string>(''); // 현재 활성화된 탭
|
||||
// 하수재이용시설 변수
|
||||
const {
|
||||
pbnstSttn,
|
||||
pbnstSttnSearch,
|
||||
pbnSttnInit,
|
||||
getFlcts
|
||||
} = useWrStore((state) => state);
|
||||
const { fclts, pbnstSttnResCount } = pbnstSttn
|
||||
const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>()
|
||||
// 재이용시설 cellClick 이벤트 (상세정보)
|
||||
const pbnstCellClick = (index: number | undefined) => {
|
||||
if (
|
||||
index !== undefined &&
|
||||
pbnstSttn.pbnstSttnRes &&
|
||||
pbnstSttn.pbnstSttnRes[index]
|
||||
) {
|
||||
setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltId);
|
||||
onFeatureSelect(pbnstSttn.pbnstSttnRes[index]);
|
||||
onClose()
|
||||
}
|
||||
};
|
||||
|
||||
// 재이용 현황 초기값
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
|
||||
if (!pbnstSttn.isInit) {
|
||||
getFlcts()
|
||||
}
|
||||
}, [seletectedLayerNm, pbnstSttn.isInit]);
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
|
||||
pbnSttnInit("1", "20", {
|
||||
partValue: "A",
|
||||
sidoValue: '0',
|
||||
sigunValue: "0",
|
||||
regionValue: "",
|
||||
unitWaterShedValue: "",
|
||||
middleRegionValue: "",
|
||||
envPartValue: "",
|
||||
sidoText: "",
|
||||
sigunText: ""
|
||||
}, String(new Date().getFullYear()), pbnstSttn.fclts);
|
||||
}, [fclts, pbnSttnInit, pbnstSttn.fclts, seletectedLayerNm])
|
||||
useEffect(() => {
|
||||
setBdstTable(pbnstSttn.pbnstSttnRes);
|
||||
}, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]);
|
||||
|
||||
// 재이용시설 조회
|
||||
// 재이용시설 페이징처리 관련 함수
|
||||
const onPageChangeHandler = useCallback((page: number) => {
|
||||
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
|
||||
pbnstSttnSearch(
|
||||
false,
|
||||
String(page),
|
||||
String(20),
|
||||
{
|
||||
partValue: "A",
|
||||
sidoValue: "0",
|
||||
sigunValue: "0",
|
||||
regionValue: "",
|
||||
unitWaterShedValue: "",
|
||||
middleRegionValue: "",
|
||||
envPartValue: "",
|
||||
sidoText: "",
|
||||
sigunText: "",
|
||||
},
|
||||
"",
|
||||
String(new Date().getFullYear()), fclts
|
||||
);
|
||||
}, [fclts, pbnstSttnSearch]);
|
||||
// FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제.
|
||||
// const excelClick = useCallback(() => {
|
||||
// // if (codeData) pbnstSttnSearch(1, "10000", codeData);
|
||||
// excelDownload(
|
||||
// [[]],
|
||||
// "하수재이용시설 현황",
|
||||
// "sample_pbnstSttn.xlsx",
|
||||
// "A1:U2"
|
||||
// );
|
||||
// }, [pbnstSttnSearch]);
|
||||
return (
|
||||
viewMode == 'detail' ?
|
||||
// 재이용시설 상세
|
||||
<>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title title="하수재이용시설 상세정보" />
|
||||
</div>
|
||||
<div className="flex justify-between items-center mb-8">
|
||||
<UITab
|
||||
defaultValue={activeTab}
|
||||
tabList={tabData.map((tab) => ({
|
||||
value: tab.id,
|
||||
label: tab.name,
|
||||
onClick: () => setActiveTab(tab.id),
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<PbnstSttnModal
|
||||
data={actTabData?.data[0] || ({} as customPbnst)}
|
||||
titleVisible={false}
|
||||
/>
|
||||
</> :
|
||||
<div style={{ overflowY: 'auto' }}>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="하수재이용시설 현황" />
|
||||
{/* <div className="flex gap-2 mt-8">
|
||||
<Button className={btnClass} color="primary" onClick={excelClick}>
|
||||
엑셀다운로드
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={bdstTable || []}
|
||||
headlist={pbnstSttn.pbnstSttHeadList}
|
||||
pageSize={20}
|
||||
total={pbnstSttnResCount || 0}
|
||||
cellClick={(index: number | undefined) => {
|
||||
pbnstCellClick(index);
|
||||
}}
|
||||
onPageChange={onPageChangeHandler}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
|
||||
</UiTable>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default ResueFacility;
|
||||
@@ -1,107 +0,0 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
|
||||
import { Title, UiTable } from "@common/business_components/ui";
|
||||
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
|
||||
import { useEffect, useState } from "react";
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
rswtrDetailModal: { isOpen: boolean; data: customRswtBdst | undefined };
|
||||
}
|
||||
const RswtFacility = ({ seletectedLayerNm, viewMode, onFeatureSelect, onClose, rswtrDetailModal }: Props) => {
|
||||
const { code, rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
const { rswtSttnRes, rswtSttnResCount } = rswtSttn;
|
||||
const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>()
|
||||
const [rswtrPage, setRswtrPage] = useState(1);
|
||||
// 중수도시설 cellClick 이벤트 (상세정보)
|
||||
const rswtCellClick = (index: number | undefined, headId: string) => {
|
||||
if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) {
|
||||
// setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] });
|
||||
// setViewMode('detail')
|
||||
onFeatureSelect(rswtrTable[index]);
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
|
||||
if (!rswtSttn.isInit) {
|
||||
rswtSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
|
||||
}
|
||||
}, [code.cityCd, code.sggCd, rswtSttn.isInit, rswtSttnInit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
|
||||
const data = tableData(rswtSttnRes, { code });
|
||||
const chData = data
|
||||
.map((item: customRswtBdst) => {
|
||||
return {
|
||||
...item,
|
||||
...item.reuseBuilding[0],
|
||||
...item.reuseBuilding[0]?.rswtrObj,
|
||||
chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N',
|
||||
instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst,
|
||||
instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt,
|
||||
archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가'
|
||||
}
|
||||
})
|
||||
.filter(
|
||||
(item: customRswtBdst) =>
|
||||
item.reuseBuilding[0]?.rswtrObj !== undefined
|
||||
);
|
||||
setRswtrTable(chData);
|
||||
}, [code, rswtSttnRes]);
|
||||
// FIXME: 윤선화 차장님 요구사항으로 엑셀 다운로드 삭제.
|
||||
// const rswtSttnExcelDownload = useCallback(() => {
|
||||
// if (rswtSttn.excelList.length > 0) {
|
||||
// if (rswtSttn.excelList.length === 0) return;
|
||||
// excelDownload(
|
||||
// rswtSttn.excelList,
|
||||
// "중수도시설 현황",
|
||||
// "sample_rswtSttn.xlsx",
|
||||
// "A1:W3",
|
||||
// );
|
||||
// }
|
||||
// }, [rswtSttn.excelList])
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
|
||||
rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd);
|
||||
}, [code.cityCd, code.sggCd, rswtSttnSearch, rswtrPage]);
|
||||
return (
|
||||
viewMode == 'detail' ?
|
||||
// 중수도시설 상세
|
||||
(
|
||||
<SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst} />
|
||||
) : (
|
||||
<div style={{ overflowY: 'auto' }}>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="중수도시설 현황" />
|
||||
{/* <div className="flex gap-2 mt-8">
|
||||
<Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}>
|
||||
엑셀다운로드
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={rswtrTable || []}
|
||||
headlist={rswtSttn.rswtSttHeadList}
|
||||
pageSize={20}
|
||||
total={rswtSttnResCount}
|
||||
cellClick={(index: number | undefined, headId: string) => {
|
||||
rswtCellClick(index, headId);
|
||||
}}
|
||||
onPageChange={setRswtrPage}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
|
||||
</UiTable>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
export default RswtFacility;
|
||||
@@ -1,187 +0,0 @@
|
||||
// "use client"
|
||||
// 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 HasuFacility from '../layerPopup/hasuFacility';
|
||||
// import RainFacility from '../layerPopup/rainFacility';
|
||||
// import RswtFacility from '../layerPopup/rswtFacility';
|
||||
// import HtdflFacility from '../layerPopup/htdflFacility';
|
||||
// import ReuseMngFacility from '../layerPopup/reuseMngFacility';
|
||||
// import { detainSttn, fetchHasuDetail, fetchpbnstDetail } from "../util";
|
||||
|
||||
// interface NewWindowPopupProps {
|
||||
// featureData: any;
|
||||
// seletectedLayerNm?: string
|
||||
// onFeatureSelect: (data: any) => void;
|
||||
// onClose: () => void;
|
||||
// }
|
||||
|
||||
// const NewWindowPopup: 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>
|
||||
// <div>
|
||||
// {renderConditionalContent()}
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default NewWindowPopup;
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
import { useWrStore } from "@/app/store";
|
||||
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
|
||||
import CoDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/coDatailModal";
|
||||
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
|
||||
import { Title, UiTable } from "@common/business_components/ui";
|
||||
import { useSearchParams } from "next/navigation";
|
||||
@@ -15,6 +16,7 @@ export default function MapFeaturePopup() {
|
||||
rswtMapDetile,
|
||||
htdfMapDetile,
|
||||
pbnMapDetaile,
|
||||
ldrmntMapDetile,
|
||||
} = useWrStore((state) => state);
|
||||
const { pbnMapHeadList } = pbnMap;
|
||||
const [isDetail, setIsDetail] = useState<any>(null);
|
||||
@@ -64,6 +66,10 @@ export default function MapFeaturePopup() {
|
||||
htdfMapDetile(isFeatureCd).then((res) => {
|
||||
setIsDetail(res);
|
||||
});
|
||||
} else if (layerNm === "잠재수요처") {
|
||||
ldrmntMapDetile(isFeatureCd).then((res) => {
|
||||
setIsDetail(res);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, [isFeatureCd, layerNm]);
|
||||
@@ -100,6 +106,15 @@ export default function MapFeaturePopup() {
|
||||
onPageChange={() => {}}
|
||||
/>
|
||||
</div>
|
||||
) : layerNm === "잠재수요처" ? (
|
||||
<CoDetailModal
|
||||
formObj={isDetail}
|
||||
readonly={false}
|
||||
onFormSubmit={async (value) => {
|
||||
console.log(value)
|
||||
}}
|
||||
isMap={true}
|
||||
/>
|
||||
) : (
|
||||
<SttnDetailModal
|
||||
type={
|
||||
|
||||
@@ -1,148 +0,0 @@
|
||||
import React, { useState, useEffect, useRef, useCallback, createContext, useContext } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
// 현재 문서의 스타일(CSS)을 새 창으로 복사하는 함수
|
||||
const copyStyles = (sourceDoc: Document, targetDoc: Document) => {
|
||||
Array.from(sourceDoc.styleSheets).forEach(styleSheet => {
|
||||
try {
|
||||
if (styleSheet.cssRules) { // <style> 태그로 주입된 CSS
|
||||
const newStyleEl = sourceDoc.createElement('style');
|
||||
Array.from(styleSheet.cssRules).forEach(cssRule => {
|
||||
newStyleEl.appendChild(sourceDoc.createTextNode(cssRule.cssText));
|
||||
});
|
||||
targetDoc.head.appendChild(newStyleEl);
|
||||
} else if (styleSheet.href) { // <link> 태그로 연결된 CSS 파일
|
||||
const newLinkEl = sourceDoc.createElement('link');
|
||||
newLinkEl.rel = 'stylesheet';
|
||||
newLinkEl.href = styleSheet.href;
|
||||
targetDoc.head.appendChild(newLinkEl);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('스타일시트를 복사할 수 없습니다:', e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
interface NewWindowPortalProps {
|
||||
children: React.ReactNode;
|
||||
onClose: () => void;
|
||||
title?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
resizable?: string;
|
||||
scrollbars?: string;
|
||||
viewMode?: 'list' | 'detail' | 'nothing';
|
||||
}
|
||||
|
||||
// Context to provide the new window's document
|
||||
const NewWindowContext = createContext<Document | null>(null);
|
||||
|
||||
// Custom hook to consume the new window's document
|
||||
export const useNewWindowDocument = () => {
|
||||
const context = useContext(NewWindowContext);
|
||||
if (context === null) {
|
||||
throw new Error('useNewWindowDocument must be used within a NewWindowContext.Provider');
|
||||
}
|
||||
return context;
|
||||
};
|
||||
|
||||
const NewWindowPortal: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "", resizable = "yes", scrollbars = "yes", viewMode }) => {
|
||||
const [container, setContainer] = useState<HTMLElement | null>(null);
|
||||
const [targetDocument, setTargetDocument] = useState<Document | null>(null);
|
||||
const newWindowRef = useRef<Window | null>(null);
|
||||
const onCloseRef = useRef(onClose);
|
||||
|
||||
// onClose 함수를 ref로 저장하여 의존성 문제 해결
|
||||
useEffect(() => {
|
||||
onCloseRef.current = onClose;
|
||||
}, [onClose]);
|
||||
|
||||
const handleUnload = useCallback(() => {
|
||||
onCloseRef.current();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (newWindowRef.current) {
|
||||
if (viewMode == 'detail') {
|
||||
newWindowRef.current.resizeTo(1100, 700);
|
||||
} else {
|
||||
newWindowRef.current.resizeTo(screen.availWidth, screen.availHeight);
|
||||
}
|
||||
}
|
||||
}, [viewMode]);
|
||||
useEffect(() => {
|
||||
// 이미 창이 열려있으면 새로 열지 않음
|
||||
if (newWindowRef.current && !newWindowRef.current.closed) return;
|
||||
// 브라우저 화면 정보
|
||||
const screenLeft = window.screenLeft ?? window.screenX;
|
||||
const screenTop = window.screenTop ?? window.screenY;
|
||||
const screenWidth = window.innerWidth ?? document.documentElement.clientWidth;
|
||||
const screenHeight = window.innerHeight ?? document.documentElement.clientHeight;
|
||||
|
||||
// 중앙 위치 계산
|
||||
const left = screenLeft + (screenWidth - window.screen.width) / 2;
|
||||
const top = screenTop + (screenHeight - window.screen.height) / 2;
|
||||
|
||||
// 1. 새 창을 열고 참조를 저장합니다.
|
||||
const popupOptions = `width=${window.screen.width},height=${window.screen.height},left=${left}, top=${top}, resizable=${resizable},scrollbars=${scrollbars}`;
|
||||
newWindowRef.current = window.open('', title, popupOptions);
|
||||
|
||||
if (newWindowRef.current) {
|
||||
newWindowRef.current.document.title = title;
|
||||
|
||||
// 2. React 컴포넌트를 마운트할 컨테이너 div를 생성하여 새 창의 body에 추가합니다.
|
||||
const div = newWindowRef.current.document.createElement('div');
|
||||
newWindowRef.current.document.body.appendChild(div);
|
||||
setContainer(div);
|
||||
setTargetDocument(newWindowRef.current.document);
|
||||
|
||||
// 3. 메인 창의 스타일을 새 창으로 복사합니다. (매우 중요)
|
||||
copyStyles(document, newWindowRef.current.document);
|
||||
|
||||
// 4. 사용자가 창을 닫을 때 부모에게 알리기 위한 이벤트 리스너를 설정합니다.
|
||||
newWindowRef.current.addEventListener('unload', handleUnload);
|
||||
|
||||
// 5. 컴포넌트가 사라질 때 창을 닫는 클린업 함수를 반환합니다.
|
||||
return () => {
|
||||
if (newWindowRef.current) {
|
||||
newWindowRef.current.removeEventListener('unload', handleUnload);
|
||||
if (!newWindowRef.current.closed) {
|
||||
newWindowRef.current.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
alert('팝업이 차단되었습니다. 팝업 차단을 해제하고 다시 시도해주세요.');
|
||||
onCloseRef.current();
|
||||
}
|
||||
}, [handleUnload, onClose, title]);
|
||||
|
||||
// `createPortal`을 사용해 children을 새 창의 container div에 렌더링합니다.
|
||||
// children을 NewWindowContext.Provider로 감싸서 새 창의 document를 하위 컴포넌트에서 접근 가능하도록 함
|
||||
return container && targetDocument ? (
|
||||
createPortal(
|
||||
<NewWindowContext.Provider value={targetDocument}>
|
||||
{children}
|
||||
</NewWindowContext.Provider>,
|
||||
container
|
||||
)
|
||||
) : null;
|
||||
};
|
||||
|
||||
export default NewWindowPortal;
|
||||
|
||||
/*
|
||||
Usage example inside popup children:
|
||||
|
||||
import { useNewWindowDocument } from './newWindowPortal';
|
||||
|
||||
const PopupChildComponent = () => {
|
||||
const newWindowDocument = useNewWindowDocument();
|
||||
|
||||
return (
|
||||
<SomeSelectComponent
|
||||
menuPortalTarget={newWindowDocument.body} // For react-select or MUI Select to render dropdowns correctly in new window
|
||||
{...otherProps}
|
||||
/>
|
||||
);
|
||||
};
|
||||
*/
|
||||
@@ -1,89 +0,0 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { pubHasuType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import { Title, UiTable } from "@common/business_components/ui";
|
||||
import { useEffect, useState } from "react";
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
isRuseReg: { data: any | undefined };
|
||||
}
|
||||
const HasuFacility = ({ seletectedLayerNm, viewMode, onClose, onFeatureSelect, isRuseReg }: Props) => {
|
||||
const {
|
||||
code,
|
||||
pbnst,
|
||||
pubHasuInit,
|
||||
} = useWrStore((state) => state);
|
||||
const { pubFacHeadList, pbnstHasuRes, pbnstHasuResCount } = pbnst;
|
||||
const [hasuTable, setHasuTable] = useState<pubHasuType[]>();
|
||||
const [hasuPage, setHasuPage] = useState<number>(1);
|
||||
useEffect(() => {
|
||||
if (code.sggCd.length && pbnstHasuRes.length > 0) {
|
||||
setHasuTable(tableData(pbnstHasuRes, { code }));
|
||||
}
|
||||
}, [code, pbnstHasuRes]);
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '하수처리시설' || viewMode != 'list') return;
|
||||
if (!pbnst.isInit) {
|
||||
pubHasuInit("1", "0");
|
||||
}
|
||||
}, [pbnst.isInit, pubHasuInit]);
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '하수처리시설' || viewMode != 'list') return;
|
||||
pubHasuInit(String(hasuPage), "0");
|
||||
}, [hasuPage, pubHasuInit]);
|
||||
|
||||
const hasuCellClick = (index: number | undefined) => {
|
||||
if (index !== undefined && pbnstHasuRes !== undefined) {
|
||||
onFeatureSelect(pbnstHasuRes[index]);
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
return (viewMode == 'list' ? (
|
||||
<div style={{ overflowY: 'auto' }}>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title title="하수처리시설 현황" />
|
||||
</div>
|
||||
{/* 높이 조정 */}
|
||||
<UiTable
|
||||
tableData={hasuTable || []}
|
||||
headlist={pubFacHeadList}
|
||||
pageSize={11}
|
||||
total={pbnstHasuResCount || 0}
|
||||
headName={""}
|
||||
cellClick={hasuCellClick}
|
||||
onPageChange={setHasuPage}
|
||||
/>
|
||||
</div>
|
||||
) :
|
||||
(
|
||||
<div style={{ overflowX: 'hidden' }}>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title title="하수처리시설 상세정보" />
|
||||
</div>
|
||||
{/* 높이 조정 */}
|
||||
<UiTable
|
||||
tableData={isRuseReg?.data || []}
|
||||
headlist={pubFacHeadList.slice(0, 4)}
|
||||
pageSize={1}
|
||||
total={0}
|
||||
headName={"위치정보"}
|
||||
cellClick={() => { }}
|
||||
onPageChange={() => { }}
|
||||
/>
|
||||
<UiTable
|
||||
tableData={isRuseReg?.data || []}
|
||||
headlist={pubFacHeadList.slice(4)}
|
||||
pageSize={1}
|
||||
total={0}
|
||||
headName={"기본정보"}
|
||||
cellClick={() => { }}
|
||||
onPageChange={() => { }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
export default HasuFacility;
|
||||
@@ -1,83 +0,0 @@
|
||||
import { useWrStore } from '@/app/store';
|
||||
import type { customHtdflBdst } from '@/app/store/ruseFcltMng/fcltReg/htdflReg';
|
||||
import { tableData } from '@/components/lib/func/commom';
|
||||
import SttnDetailModal from '@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal';
|
||||
import { Title, UiTable } from '@common/business_components/ui';
|
||||
import { HeadMakeColSpan } from '@common/business_components/ui/table/HeadMakeColSpan';
|
||||
import React, { useEffect, useState } from 'react'
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
htdflDetailModal: { isOpen: boolean; data: customHtdflBdst | undefined };
|
||||
}
|
||||
const HtdflFacility = ({ seletectedLayerNm, viewMode, onFeatureSelect, onClose, htdflDetailModal }: Props) => {
|
||||
const { code, htdflSttn, htdflSttnSearch, initHtdfl } = useWrStore((state) => state);
|
||||
const { htdflSttnRes, htdflSttnResCount } = htdflSttn;
|
||||
const [htdflTable, setHtdflTable] = useState<customHtdflBdst[]>();
|
||||
const [htdflPage, setHtdflPage] = useState(1)
|
||||
// 온배수시설 cellClick 이벤트 (상세정보)
|
||||
const htdflCellClick = (index: number | undefined) => {
|
||||
if (index !== undefined && htdflTable !== undefined) {
|
||||
onFeatureSelect(htdflTable[index]);
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
|
||||
if (!htdflSttn.isInit) {
|
||||
initHtdfl(false, 1, "20", "0", '', code.cityCd, code.sggCd);
|
||||
}
|
||||
}, [code.cityCd, code.sggCd, htdflSttn.isInit, initHtdfl]);
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
|
||||
const data = tableData(htdflSttnRes, { code });
|
||||
const chData = data
|
||||
.map((item: any) => ({
|
||||
...item,
|
||||
...item.reuseBuilding[0],
|
||||
...item.reuseBuilding[0].htdflObj,
|
||||
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
|
||||
}))
|
||||
.filter((item: any) => item.htdflObj !== undefined);
|
||||
setHtdflTable(chData);
|
||||
}, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]);
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '온배수시설' || viewMode != 'list') return;
|
||||
htdflSttnSearch(true, htdflPage, "20", '', '', code.cityCd, code.sggCd);
|
||||
}, [code.cityCd, code.sggCd, htdflPage, htdflSttnSearch]);
|
||||
return (
|
||||
viewMode == 'detail' ? (
|
||||
<SttnDetailModal type={"HTB"} formObj={htdflDetailModal.data as customHtdflBdst} />
|
||||
) : (
|
||||
<div style={{ overflowY: 'auto' }}>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="온배수시설 현황" />
|
||||
{/* <div className="flex gap-2 mt-8">
|
||||
<Button className={btnClass} color="primary" onClick={excelClick}>
|
||||
엑셀다운로드
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={htdflTable || []}
|
||||
headlist={htdflSttn.htdflSttHeadList}
|
||||
pageSize={20}
|
||||
total={htdflSttnResCount || 0}
|
||||
cellClick={(index: number | undefined) => {
|
||||
htdflCellClick(index ?? undefined);
|
||||
}}
|
||||
onPageChange={setHtdflPage}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={htdflSttn.htdflSttNodeList} />
|
||||
</UiTable>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
export default HtdflFacility
|
||||
@@ -1,105 +0,0 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { customRainBdst } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
|
||||
import { Title, UiTable } from "@common/business_components/ui";
|
||||
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
|
||||
import { useEffect, useState } from "react";
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
rainDetailModal: { isOpen: boolean; data: customRainBdst | undefined };
|
||||
}
|
||||
const RainFacility = ({seletectedLayerNm,viewMode,onFeatureSelect,onClose,rainDetailModal}:Props) => {
|
||||
// 빗물재이용시설 변수
|
||||
const { code, rainSttn, rainSttnSearch, rainSttnInit } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
const { rainSttnRes, rainSttnResCount } = rainSttn;
|
||||
const [rainTable, setRainTable] = useState<customRainBdst[]>();
|
||||
const [rainPage, setRainPage] = useState(1)
|
||||
|
||||
// 빗물재이용시설 cellClick 이벤트 (상세정보)
|
||||
const rainCellClick = (index: number | undefined, headId: string) => {
|
||||
if (
|
||||
index !== undefined &&
|
||||
rainTable !== undefined &&
|
||||
headId !== 'chBuildingYn') {
|
||||
onFeatureSelect(rainTable[index]);
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '빗물이용시설' || viewMode != 'list') return;
|
||||
console.log('빗물이용시설 초기값 호출', viewMode)
|
||||
if (!rainSttn.isInit) {
|
||||
rainSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
|
||||
}
|
||||
}, [code.cityCd, code.sggCd, rainSttn.isInit, rainSttnInit]);
|
||||
|
||||
useEffect(() => {
|
||||
const data = tableData(rainSttnRes, { code });
|
||||
const chData = data
|
||||
.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
...item.reuseBuilding[0],
|
||||
...item.reuseBuilding[0].rainyObj,
|
||||
dtfcltCpct: item.reuseBuilding[0].rainyObj.dtfcltCpct === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].rainyObj.dtfcltCpct,
|
||||
instlCst: item.reuseBuilding[0].instlCst === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].instlCst,
|
||||
instlCstSprtAmt: item.reuseBuilding[0].instlCstSprtAmt === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].instlCstSprtAmt,
|
||||
chBuildingYn: item.chgBuilding[0]?.bdstChgNm !== null ? "Y" : "N",
|
||||
pntfColArea: item.reuseBuilding[0].rainyObj.pntfColArea === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].rainyObj.pntfColArea,
|
||||
filtrTrtmfctCpct: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct === -1
|
||||
? "확인불가"
|
||||
: item.reuseBuilding[0].rainyObj.filtrTrtmfctCpct,
|
||||
archArea: Math.floor(item.archArea) === -1 ? "확인불가" : item.archArea,
|
||||
};
|
||||
})
|
||||
.filter((item: any) => item.rainyObj !== undefined);
|
||||
setRainTable(chData);
|
||||
}, [code, rainSttnRes, rainSttn.rainSttHeadList]);
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '빗물이용시설' || viewMode != 'list') return;
|
||||
rainSttnSearch(false, rainPage, "20", '', '', code.cityCd, code.sggCd);
|
||||
}, [code.cityCd, code.sggCd, rainPage, rainSttnSearch]);
|
||||
return (viewMode == 'detail' ?
|
||||
(<SttnDetailModal type={"RNB"} formObj={rainDetailModal.data as customRainBdst} />)
|
||||
: (
|
||||
<>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="빗물이용시설 현황" />
|
||||
{/* <div className="flex gap-2 mt-8">
|
||||
<Button className={btnClass} color="primary" onClick={excelClick}>
|
||||
엑셀다운로드
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={rainTable || []}
|
||||
headlist={rainSttn.rainSttHeadList}
|
||||
pageSize={20}
|
||||
total={rainSttnResCount}
|
||||
cellClick={(index: number | undefined, headId: string) => {
|
||||
rainCellClick(index ?? undefined, headId);
|
||||
}}
|
||||
onPageChange={setRainPage}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={rainSttn.rainSttNodeList} />
|
||||
</UiTable>
|
||||
</>
|
||||
))
|
||||
}
|
||||
export default RainFacility;
|
||||
@@ -1,146 +0,0 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { customPbnst } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
|
||||
import type { WaterReuseFacility } from "@/app/store/ruseFcltMng/fcltSttn/pbnstSttn/type";
|
||||
import { PbnstSttnModal } from "@/components/ui/modal/sttn/pbnstSttnModal/pbnstSttnModal";
|
||||
import { Title, UITab, UiTable } from "@common/business_components/ui";
|
||||
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
setFcltPk: (pk: string) => void;
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
actTabData: { id: string; name: string; data: any } | undefined;
|
||||
tabData: { id: string; name: string; data: any }[];
|
||||
}
|
||||
const ResueFacility = ({ viewMode, seletectedLayerNm, tabData, actTabData, setFcltPk, onFeatureSelect, onClose}: Props) => {
|
||||
const [activeTab, setActiveTab] = useState<string>(''); // 현재 활성화된 탭
|
||||
// 하수재이용시설 변수
|
||||
const {
|
||||
pbnstSttn,
|
||||
pbnstSttnSearch,
|
||||
pbnSttnInit,
|
||||
getFlcts
|
||||
} = useWrStore((state) => state);
|
||||
const { fclts, pbnstSttnResCount } = pbnstSttn
|
||||
const [bdstTable, setBdstTable] = useState<WaterReuseFacility[]>()
|
||||
// 재이용시설 cellClick 이벤트 (상세정보)
|
||||
const pbnstCellClick = (index: number | undefined) => {
|
||||
if (
|
||||
index !== undefined &&
|
||||
pbnstSttn.pbnstSttnRes &&
|
||||
pbnstSttn.pbnstSttnRes[index]
|
||||
) {
|
||||
setFcltPk(pbnstSttn.pbnstSttnRes[index].pbnstRuseFcltId);
|
||||
onFeatureSelect(pbnstSttn.pbnstSttnRes[index]);
|
||||
onClose()
|
||||
}
|
||||
};
|
||||
|
||||
// 재이용 현황 초기값
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
|
||||
if (!pbnstSttn.isInit) {
|
||||
getFlcts()
|
||||
}
|
||||
}, [seletectedLayerNm, pbnstSttn.isInit]);
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
|
||||
pbnSttnInit("1", "20", {
|
||||
partValue: "A",
|
||||
sidoValue: '0',
|
||||
sigunValue: "0",
|
||||
regionValue: "",
|
||||
unitWaterShedValue: "",
|
||||
middleRegionValue: "",
|
||||
envPartValue: "",
|
||||
sidoText: "",
|
||||
sigunText: ""
|
||||
}, String(new Date().getFullYear()), pbnstSttn.fclts);
|
||||
}, [fclts, pbnSttnInit, pbnstSttn.fclts, seletectedLayerNm])
|
||||
useEffect(() => {
|
||||
setBdstTable(pbnstSttn.pbnstSttnRes);
|
||||
}, [seletectedLayerNm, pbnstSttn.pbnstSttnRes]);
|
||||
|
||||
// 재이용시설 조회
|
||||
// 재이용시설 페이징처리 관련 함수
|
||||
const onPageChangeHandler = useCallback((page: number) => {
|
||||
if (seletectedLayerNm !== '하수재이용시설' || viewMode !='list') return;
|
||||
pbnstSttnSearch(
|
||||
false,
|
||||
String(page),
|
||||
String(20),
|
||||
{
|
||||
partValue: "A",
|
||||
sidoValue: "0",
|
||||
sigunValue: "0",
|
||||
regionValue: "",
|
||||
unitWaterShedValue: "",
|
||||
middleRegionValue: "",
|
||||
envPartValue: "",
|
||||
sidoText: "",
|
||||
sigunText: "",
|
||||
},
|
||||
"",
|
||||
String(new Date().getFullYear()), fclts
|
||||
);
|
||||
}, [fclts, pbnstSttnSearch]);
|
||||
// FIXME: 윤선화차장님 요구사항으로 엑셀 다운로드 삭제.
|
||||
// const excelClick = useCallback(() => {
|
||||
// // if (codeData) pbnstSttnSearch(1, "10000", codeData);
|
||||
// excelDownload(
|
||||
// [[]],
|
||||
// "하수재이용시설 현황",
|
||||
// "sample_pbnstSttn.xlsx",
|
||||
// "A1:U2"
|
||||
// );
|
||||
// }, [pbnstSttnSearch]);
|
||||
return (
|
||||
viewMode == 'detail' ?
|
||||
// 재이용시설 상세
|
||||
<>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title title="하수재이용시설 상세정보" />
|
||||
</div>
|
||||
<div className="flex justify-between items-center mb-8">
|
||||
<UITab
|
||||
defaultValue={activeTab}
|
||||
tabList={tabData.map((tab) => ({
|
||||
value: tab.id,
|
||||
label: tab.name,
|
||||
onClick: () => setActiveTab(tab.id),
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
<PbnstSttnModal
|
||||
data={actTabData?.data[0] || ({} as customPbnst)}
|
||||
titleVisible={false}
|
||||
/>
|
||||
</> :
|
||||
<div style={{ overflowY: 'auto' }}>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="하수재이용시설 현황" />
|
||||
{/* <div className="flex gap-2 mt-8">
|
||||
<Button className={btnClass} color="primary" onClick={excelClick}>
|
||||
엑셀다운로드
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={bdstTable || []}
|
||||
headlist={pbnstSttn.pbnstSttHeadList}
|
||||
pageSize={20}
|
||||
total={pbnstSttnResCount || 0}
|
||||
cellClick={(index: number | undefined) => {
|
||||
pbnstCellClick(index);
|
||||
}}
|
||||
onPageChange={onPageChangeHandler}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={pbnstSttn.pbnstSttNodeList} />
|
||||
</UiTable>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
export default ResueFacility;
|
||||
@@ -1,103 +0,0 @@
|
||||
import { useWrStore } from '@/app/store';
|
||||
import { tableData, formatPhoneNumber } from '@/components/lib/func/commom';
|
||||
import { Title, UiTable } from '@common/business_components/ui';
|
||||
import type { DemandCompType } from '@common/business_components/ui/sdmInsertForm/form';
|
||||
import moment from 'moment';
|
||||
import React, { useEffect, useState } from 'react'
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
isDmdModal: { data: any | undefined };
|
||||
}
|
||||
const ReuseMngFacility = ({seletectedLayerNm, viewMode, onFeatureSelect, onClose, isDmdModal}:Props) => {
|
||||
const { code,
|
||||
coSttn,
|
||||
coSttnInit,
|
||||
coSttnSearch,
|
||||
} = useWrStore((state) => state);
|
||||
const [mngTable, setMngTable] = useState<DemandCompType[]>();
|
||||
const [mngPage, setMngPage] = useState(1);
|
||||
const { coSttnRes, coSttnResCount, coSttHeadList } = coSttn;
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '수요처' || viewMode != 'list') return;
|
||||
if (!coSttn.isInit) {
|
||||
coSttnInit("1", "20", "0");
|
||||
}
|
||||
}, [coSttn.isInit, coSttnInit]);
|
||||
const coMngCellClick = (index: number | undefined) => {
|
||||
if (index !== undefined && mngTable !== undefined) {
|
||||
onFeatureSelect(mngTable[index]);
|
||||
onClose();
|
||||
}
|
||||
};
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '수요처' || viewMode!='list') return;
|
||||
if (coSttnRes) {
|
||||
if (coSttnRes?.length > 0 && code.cityCd.length > 0) {
|
||||
const data = tableData(coSttnRes, { code });
|
||||
const chData = data.map((item: any) => ({
|
||||
...item,
|
||||
telno: formatPhoneNumber(item.telno || undefined),
|
||||
regDt: moment(item.regDt).format("YYYY-MM-DD"),
|
||||
dmdInfoId: `${item.dmdInfoId.slice(0, 3)}-${item.dmdInfoId.slice(3, 5)}-${item.dmdInfoId.slice(5, 10)}-${item.dmdInfoId.slice(10)}`
|
||||
}));
|
||||
// .filter((item: any) => item !== undefined);
|
||||
setMngTable(chData);
|
||||
}
|
||||
}
|
||||
}, [coSttnRes, code]);
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '수요처' || viewMode!='list') return;
|
||||
coSttnSearch(String(mngPage), "20", String(0));
|
||||
}, [coSttnSearch, mngPage]);
|
||||
return (
|
||||
viewMode == 'detail'
|
||||
? (
|
||||
<div style={{ overflowX: 'hidden' }}>
|
||||
<div className="flex justify-between items-center mb-4">
|
||||
<Title title="수요처 상세정보" />
|
||||
</div>
|
||||
{/* 높이 조정 */}
|
||||
<UiTable
|
||||
tableData={isDmdModal?.data || []}
|
||||
headlist={coSttHeadList.slice(0, 3)}
|
||||
pageSize={1}
|
||||
total={0}
|
||||
headName={"위치정보"}
|
||||
cellClick={() => { }}
|
||||
onPageChange={() => { }}
|
||||
/>
|
||||
<UiTable
|
||||
tableData={isDmdModal?.data || []}
|
||||
headlist={coSttHeadList.slice(3)}
|
||||
pageSize={1}
|
||||
total={0}
|
||||
headName={"기본정보"}
|
||||
cellClick={() => { }}
|
||||
onPageChange={() => { }}
|
||||
/>
|
||||
</div>
|
||||
) : (<div>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="수요처 현황" />
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={mngTable || []}
|
||||
headlist={coSttHeadList}
|
||||
pageSize={20}
|
||||
total={coSttnResCount + 10 || 0}
|
||||
cellClick={(index: number | undefined) => {
|
||||
coMngCellClick(index);
|
||||
// setUpdateData(coSttnRes[index as number]);
|
||||
}}
|
||||
onPageChange={(page) => {
|
||||
setMngPage(page);
|
||||
}}
|
||||
></UiTable></div>)
|
||||
)
|
||||
}
|
||||
|
||||
export default ReuseMngFacility
|
||||
@@ -1,107 +0,0 @@
|
||||
import { useWrStore } from "@/app/store";
|
||||
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
|
||||
import { tableData } from "@/components/lib/func/commom";
|
||||
import SttnDetailModal from "@/components/ui/modal/sttn/sttnDetailModal/sttnDetailModal";
|
||||
import { Title, UiTable } from "@common/business_components/ui";
|
||||
import { HeadMakeColSpan } from "@common/business_components/ui/table/HeadMakeColSpan";
|
||||
import { useEffect, useState } from "react";
|
||||
interface Props {
|
||||
seletectedLayerNm: string;
|
||||
viewMode: 'list' | 'detail' | 'nothing';
|
||||
onFeatureSelect: (feature: any) => void;
|
||||
onClose: () => void;
|
||||
rswtrDetailModal: { isOpen: boolean; data: customRswtBdst | undefined };
|
||||
}
|
||||
const RswtFacility = ({ seletectedLayerNm, viewMode, onFeatureSelect, onClose, rswtrDetailModal }: Props) => {
|
||||
const { code, rswtSttn, rswtSttnSearch, rswtSttnInit } = useWrStore(
|
||||
(state) => state
|
||||
);
|
||||
const { rswtSttnRes, rswtSttnResCount } = rswtSttn;
|
||||
const [rswtrTable, setRswtrTable] = useState<customRswtBdst[]>()
|
||||
const [rswtrPage, setRswtrPage] = useState(1);
|
||||
// 중수도시설 cellClick 이벤트 (상세정보)
|
||||
const rswtCellClick = (index: number | undefined, headId: string) => {
|
||||
if (headId !== 'chBuildingYn' && index !== undefined && rswtrTable !== undefined) {
|
||||
// setRswtrDetailModal({ isOpen: true, data: rswtrTable[index] });
|
||||
// setViewMode('detail')
|
||||
onFeatureSelect(rswtrTable[index]);
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
|
||||
if (!rswtSttn.isInit) {
|
||||
rswtSttnInit(false, 1, "20", "0", '', code.cityCd, code.sggCd);
|
||||
}
|
||||
}, [code.cityCd, code.sggCd, rswtSttn.isInit, rswtSttnInit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
|
||||
const data = tableData(rswtSttnRes, { code });
|
||||
const chData = data
|
||||
.map((item: customRswtBdst) => {
|
||||
return {
|
||||
...item,
|
||||
...item.reuseBuilding[0],
|
||||
...item.reuseBuilding[0]?.rswtrObj,
|
||||
chBuildingYn: item?.chgBuilding[0]?.bdstChgNm !== null && item?.chgBuilding.length > 0 ? 'Y' : 'N',
|
||||
instlCst: item.reuseBuilding[0]?.instlCst === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCst,
|
||||
instlCstSprtAmt: item.reuseBuilding[0]?.instlCstSprtAmt === -1 ? "확인불가" : item.reuseBuilding[0]?.instlCstSprtAmt,
|
||||
archArea: item?.archArea.split('.')[0] !== '-1' ? item?.archArea.split('.')[0] : '확인불가'
|
||||
}
|
||||
})
|
||||
.filter(
|
||||
(item: customRswtBdst) =>
|
||||
item.reuseBuilding[0]?.rswtrObj !== undefined
|
||||
);
|
||||
setRswtrTable(chData);
|
||||
}, [code, rswtSttnRes]);
|
||||
// FIXME: 윤선화 차장님 요구사항으로 엑셀 다운로드 삭제.
|
||||
// const rswtSttnExcelDownload = useCallback(() => {
|
||||
// if (rswtSttn.excelList.length > 0) {
|
||||
// if (rswtSttn.excelList.length === 0) return;
|
||||
// excelDownload(
|
||||
// rswtSttn.excelList,
|
||||
// "중수도시설 현황",
|
||||
// "sample_rswtSttn.xlsx",
|
||||
// "A1:W3",
|
||||
// );
|
||||
// }
|
||||
// }, [rswtSttn.excelList])
|
||||
|
||||
useEffect(() => {
|
||||
if (seletectedLayerNm !== '중수도시설' || viewMode != 'list') return;
|
||||
rswtSttnSearch(false, rswtrPage, "20", '', '', code.cityCd, code.sggCd);
|
||||
}, [code.cityCd, code.sggCd, rswtSttnSearch, rswtrPage]);
|
||||
return (
|
||||
viewMode == 'detail' ?
|
||||
// 중수도시설 상세
|
||||
(
|
||||
<SttnDetailModal type={"RST"} formObj={rswtrDetailModal.data as customRswtBdst} />
|
||||
) : (
|
||||
<div style={{ overflowY: 'auto' }}>
|
||||
<div className="flex justify-between items-center">
|
||||
<Title title="중수도시설 현황" />
|
||||
{/* <div className="flex gap-2 mt-8">
|
||||
<Button className={btnClass} color="primary" onClick={rswtSttnExcelDownload}>
|
||||
엑셀다운로드
|
||||
</Button>
|
||||
</div> */}
|
||||
</div>
|
||||
<UiTable
|
||||
headName={[]}
|
||||
tableData={rswtrTable || []}
|
||||
headlist={rswtSttn.rswtSttHeadList}
|
||||
pageSize={20}
|
||||
total={rswtSttnResCount}
|
||||
cellClick={(index: number | undefined, headId: string) => {
|
||||
rswtCellClick(index, headId);
|
||||
}}
|
||||
onPageChange={setRswtrPage}
|
||||
>
|
||||
<HeadMakeColSpan upHeadList={rswtSttn.rswtSttNodeList} />
|
||||
</UiTable>
|
||||
</div>
|
||||
))
|
||||
}
|
||||
export default RswtFacility;
|
||||
@@ -1,183 +0,0 @@
|
||||
"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;
|
||||
@@ -1,112 +0,0 @@
|
||||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
|
||||
// 현재 문서의 스타일(CSS)을 새 창으로 복사하는 함수
|
||||
const copyStyles = (sourceDoc: Document, targetDoc: Document) => {
|
||||
Array.from(sourceDoc.styleSheets).forEach(styleSheet => {
|
||||
try {
|
||||
if (styleSheet.cssRules) { // <style> 태그로 주입된 CSS
|
||||
const newStyleEl = sourceDoc.createElement('style');
|
||||
Array.from(styleSheet.cssRules).forEach(cssRule => {
|
||||
newStyleEl.appendChild(sourceDoc.createTextNode(cssRule.cssText));
|
||||
});
|
||||
targetDoc.head.appendChild(newStyleEl);
|
||||
} else if (styleSheet.href) { // <link> 태그로 연결된 CSS 파일
|
||||
const newLinkEl = sourceDoc.createElement('link');
|
||||
newLinkEl.rel = 'stylesheet';
|
||||
newLinkEl.href = styleSheet.href;
|
||||
targetDoc.head.appendChild(newLinkEl);
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('스타일시트를 복사할 수 없습니다:', e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
interface NewWindowPortalProps {
|
||||
children: React.ReactNode;
|
||||
onClose: () => void;
|
||||
title?: string;
|
||||
width?: number;
|
||||
height?: number;
|
||||
resizable?: string;
|
||||
scrollbars?: string;
|
||||
viewMode?: 'list' | 'detail' | 'nothing';
|
||||
}
|
||||
|
||||
const NewWindowPortal22: React.FC<NewWindowPortalProps> = ({ children, onClose, title = "", resizable = "yes", scrollbars = "yes", viewMode }) => {
|
||||
const [container, setContainer] = useState<HTMLElement | null>(null);
|
||||
const newWindowRef = useRef<Window | null>(null);
|
||||
const onCloseRef = useRef(onClose);
|
||||
|
||||
// onClose 함수를 ref로 저장하여 의존성 문제 해결
|
||||
useEffect(() => {
|
||||
onCloseRef.current = onClose;
|
||||
}, [onClose]);
|
||||
|
||||
const handleUnload = useCallback(() => {
|
||||
onCloseRef.current();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
if (newWindowRef.current) {
|
||||
if (viewMode == 'detail') {
|
||||
newWindowRef.current.resizeTo(1100, 700);
|
||||
} else {
|
||||
newWindowRef.current.resizeTo(screen.availWidth, screen.availHeight);
|
||||
}
|
||||
}
|
||||
}, [viewMode]);
|
||||
useEffect(() => {
|
||||
// 이미 창이 열려있으면 새로 열지 않음
|
||||
if (newWindowRef.current && !newWindowRef.current.closed) return;
|
||||
// 브라우저 화면 정보
|
||||
const screenLeft = window.screenLeft ?? window.screenX;
|
||||
const screenTop = window.screenTop ?? window.screenY;
|
||||
const screenWidth = window.innerWidth ?? document.documentElement.clientWidth;
|
||||
const screenHeight = window.innerHeight ?? document.documentElement.clientHeight;
|
||||
|
||||
// 중앙 위치 계산
|
||||
const left = screenLeft + (screenWidth - window.screen.width) / 2;
|
||||
const top = screenTop + (screenHeight - window.screen.height) / 2;
|
||||
|
||||
// 1. 새 창을 열고 참조를 저장합니다.
|
||||
const popupOptions = `width=${window.screen.width},height=${window.screen.height},left=${left}, top=${top}, resizable=${resizable},scrollbars=${scrollbars}`;
|
||||
newWindowRef.current = window.open('', title, popupOptions);
|
||||
|
||||
if (newWindowRef.current) {
|
||||
newWindowRef.current.document.title = title;
|
||||
|
||||
// 2. React 컴포넌트를 마운트할 컨테이너 div를 생성하여 새 창의 body에 추가합니다.
|
||||
const div = newWindowRef.current.document.createElement('div');
|
||||
newWindowRef.current.document.body.appendChild(div);
|
||||
setContainer(div);
|
||||
|
||||
// 3. 메인 창의 스타일을 새 창으로 복사합니다. (매우 중요)
|
||||
copyStyles(document, newWindowRef.current.document);
|
||||
// 4. 사용자가 창을 닫을 때 부모에게 알리기 위한 이벤트 리스너를 설정합니다.
|
||||
// const handleUnload = () => {
|
||||
// onClose();
|
||||
// };
|
||||
newWindowRef.current.addEventListener('unload', handleUnload);
|
||||
|
||||
// 5. 컴포넌트가 사라질 때 창을 닫는 클린업 함수를 반환합니다.
|
||||
return () => {
|
||||
if (newWindowRef.current) {
|
||||
newWindowRef.current.removeEventListener('unload', handleUnload);
|
||||
if (!newWindowRef.current.closed) {
|
||||
newWindowRef.current.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
} else {
|
||||
alert('팝업이 차단되었습니다. 팝업 차단을 해제하고 다시 시도해주세요.');
|
||||
onCloseRef.current();
|
||||
// onClose();
|
||||
}
|
||||
}, [handleUnload, onClose, title]);
|
||||
|
||||
// `createPortal`을 사용해 children을 새 창의 container div에 렌더링합니다.
|
||||
return container ? createPortal(children, container) : null;
|
||||
};
|
||||
|
||||
export default NewWindowPortal22;
|
||||
@@ -1,149 +1,153 @@
|
||||
"use client";
|
||||
// "use client";
|
||||
|
||||
import Gis from "@common/business_components/ui/map/Gis";
|
||||
import { useEffect, useRef, useState, useCallback } from "react";
|
||||
import { mapService } from "../service";
|
||||
import NewWindowPopup from "../components/newWindowPopup";
|
||||
import GisApp from "@common/business_components/ui/map/lib/gis.core";
|
||||
// import Gis from "@common/business_components/ui/map/Gis";
|
||||
// import { useEffect, useRef, useState, useCallback } from "react";
|
||||
// import { mapService } from "../service";
|
||||
// import NewWindowPopup from "../components/newWindowPopup";
|
||||
// import GisApp from "@common/business_components/ui/map/lib/gis.core";
|
||||
|
||||
const Map = () => {
|
||||
const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
|
||||
const gisMaps = useRef<any | null>(null);
|
||||
const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
|
||||
const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태
|
||||
const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
|
||||
const [checkedLayers, setCheckedLayers] = useState<string[]>([]);
|
||||
const [checkedLayersData, setCheckedLayersData] = useState<any[]>([]);
|
||||
// const Map = () => {
|
||||
// const [treeData, setTreeData] = useState([]); // 초기값을 객체 또는 null로 설정
|
||||
// const gisMaps = useRef<any | null>(null);
|
||||
// const [isOpen, setIsOpen] = useState(false); // 팝업 열기/닫기 상태
|
||||
// const [isSearchModalOpen, setIsSearchModalOpen] = useState(true); // SearchModal 열림 상태
|
||||
// const [featureData, setFeatureData] = useState(null); // 선택된 피쳐 데이터
|
||||
// const [checkedLayers, setCheckedLayers] = useState<string[]>([]);
|
||||
// const [checkedLayersData, setCheckedLayersData] = useState<any[]>([]);
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const response = await mapService.getLyrStngs();
|
||||
setTreeData(response); // API 응답 저장
|
||||
} catch (error) {
|
||||
console.error("데이터 불러오기 실패:", error);
|
||||
}
|
||||
};
|
||||
// const fetchData = async () => {
|
||||
// try {
|
||||
// const response = await mapService.getLyrStngs();
|
||||
// setTreeData(response); // API 응답 저장
|
||||
// } catch (error) {
|
||||
// console.error("데이터 불러오기 실패:", error);
|
||||
// }
|
||||
// };
|
||||
|
||||
// 팝업 닫기 핸들러를 useCallback으로 메모이제이션
|
||||
const handlePopupClose = useCallback(() => {
|
||||
setIsOpen(false);
|
||||
setFeatureData(null);
|
||||
}, []);
|
||||
// // 팝업 닫기 핸들러를 useCallback으로 메모이제이션
|
||||
// const handlePopupClose = useCallback(() => {
|
||||
// setIsOpen(false);
|
||||
// setFeatureData(null);
|
||||
// }, []);
|
||||
|
||||
// 컴포넌트 마운트 시 1회 실행
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
}, []);
|
||||
// // 컴포넌트 마운트 시 1회 실행
|
||||
// useEffect(() => {
|
||||
// fetchData();
|
||||
// }, []);
|
||||
|
||||
// 체크된 레이어 정보를 받는 핸들러
|
||||
const handleCheckedLayersChange = (checkedIds: string[], checkedNodesData: any[]) => {
|
||||
setCheckedLayers(checkedIds);
|
||||
setCheckedLayersData(checkedNodesData);
|
||||
};
|
||||
// // 체크된 레이어 정보를 받는 핸들러
|
||||
// const handleCheckedLayersChange = (checkedIds: string[], checkedNodesData: any[]) => {
|
||||
// setCheckedLayers(checkedIds);
|
||||
// setCheckedLayersData(checkedNodesData);
|
||||
// };
|
||||
|
||||
// SearchModal, GisContent 등에서 호출
|
||||
const onFeatureSelect = (data: any) => {
|
||||
const map = gisMaps.current;
|
||||
if (!map) {
|
||||
console.warn("지도가 초기화되지 않았습니다.");
|
||||
return;
|
||||
}
|
||||
// // SearchModal, GisContent 등에서 호출
|
||||
// const onFeatureSelect = (data: any) => {
|
||||
// const map = gisMaps.current;
|
||||
// if (!map) {
|
||||
// console.warn("지도가 초기화되지 않았습니다.");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// 항상 같은 select 객체 사용
|
||||
const select = GisApp.Module.select as any;
|
||||
if (!select) return;
|
||||
// // 항상 같은 select 객체 사용
|
||||
// const select = GisApp.Module.select as any;
|
||||
// if (!select) return;
|
||||
|
||||
// 1. 기존 선택 초기화
|
||||
select.resetSelectedFeature();
|
||||
// // 1. 기존 선택 초기화
|
||||
// select.resetSelectedFeature();
|
||||
|
||||
// 2. data가 OpenLayers Feature 인스턴스인지 확인
|
||||
let foundFeature: any = null;
|
||||
if (
|
||||
data &&
|
||||
typeof data.getGeometry === "function" &&
|
||||
typeof data.setStyle === "function"
|
||||
) {
|
||||
// 이미 Feature 인스턴스라면 그대로 사용
|
||||
foundFeature = data;
|
||||
} else {
|
||||
// 아니면 featureId로 맵에서 Feature 인스턴스를 찾아서 사용
|
||||
const featureId = data.fid || data.ftrIdn || data.id;
|
||||
map
|
||||
.getLayers()
|
||||
.getArray()
|
||||
.forEach((layer: any) => {
|
||||
const source = layer.getSource?.();
|
||||
if (source?.getFeatureById) {
|
||||
const feature = source.getFeatureById(String(featureId).trim());
|
||||
if (feature) foundFeature = feature;
|
||||
}
|
||||
});
|
||||
}
|
||||
// // 2. data가 OpenLayers Feature 인스턴스인지 확인
|
||||
// let foundFeature: any = null;
|
||||
// if (
|
||||
// data &&
|
||||
// typeof data.getGeometry === "function" &&
|
||||
// typeof data.setStyle === "function"
|
||||
// ) {
|
||||
// // 이미 Feature 인스턴스라면 그대로 사용
|
||||
// foundFeature = data;
|
||||
// } else {
|
||||
// // 아니면 featureId로 맵에서 Feature 인스턴스를 찾아서 사용
|
||||
// const featureId = data.fid || data.ftrIdn || data.id;
|
||||
// map
|
||||
// .getLayers()
|
||||
// .getArray()
|
||||
// .forEach((layer: any) => {
|
||||
// const source = layer.getSource?.();
|
||||
// if (source?.getFeatureById) {
|
||||
// const feature = source.getFeatureById(String(featureId).trim());
|
||||
// if (feature) foundFeature = feature;
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
|
||||
// 3. 피처 선택
|
||||
if (foundFeature) {
|
||||
const geometry = foundFeature.getGeometry();
|
||||
if (geometry) {
|
||||
const extent = geometry.getExtent();
|
||||
// // 3. 피처 선택
|
||||
// if (foundFeature) {
|
||||
// const geometry = foundFeature.getGeometry();
|
||||
// if (geometry) {
|
||||
// const extent = geometry.getExtent();
|
||||
|
||||
map.getView().fit(extent, {
|
||||
duration: 300,
|
||||
padding: [50, 50, 50, 50],
|
||||
maxZoom: 16,
|
||||
constrainResolution: true,
|
||||
nearest: true,
|
||||
});
|
||||
}
|
||||
select.selectFeature(foundFeature, true);
|
||||
} else {
|
||||
console.warn("OpenLayers Feature를 찾을 수 없습니다:", data);
|
||||
}
|
||||
// map.getView().fit(extent, {
|
||||
// duration: 300,
|
||||
// padding: [50, 50, 50, 50],
|
||||
// maxZoom: 16,
|
||||
// constrainResolution: true,
|
||||
// nearest: true,
|
||||
// });
|
||||
// }
|
||||
// select.selectFeature(foundFeature, true);
|
||||
// } else {
|
||||
// console.warn("OpenLayers Feature를 찾을 수 없습니다:", data);
|
||||
// }
|
||||
|
||||
setFeatureData(data);
|
||||
setIsOpen(true);
|
||||
setIsSearchModalOpen(false);
|
||||
};
|
||||
// setFeatureData(data);
|
||||
// setIsOpen(true);
|
||||
// setIsSearchModalOpen(false);
|
||||
// };
|
||||
|
||||
// MapSearchBar 래퍼 컴포넌트
|
||||
// const CustomMapSearchBar = (props: any) => {
|
||||
// return (
|
||||
// <MapSearchBar
|
||||
// {...props}
|
||||
// searchType="공급처 후보지 조회"
|
||||
// showApplyButton={false}
|
||||
// />
|
||||
// );
|
||||
// };
|
||||
// // MapSearchBar 래퍼 컴포넌트
|
||||
// // const CustomMapSearchBar = (props: any) => {
|
||||
// // return (
|
||||
// // <MapSearchBar
|
||||
// // {...props}
|
||||
// // searchType="공급처 후보지 조회"
|
||||
// // showApplyButton={false}
|
||||
// // />
|
||||
// // );
|
||||
// // };
|
||||
|
||||
return (
|
||||
<div className="bg-container">
|
||||
<Gis
|
||||
treeData={treeData}
|
||||
isSearch={false}
|
||||
gisMaps={gisMaps}
|
||||
isMiniMap={false}
|
||||
searchView={undefined}
|
||||
detailView={(props: any) =>(
|
||||
<NewWindowPopup
|
||||
onClose={handlePopupClose} // 메모이제이션된 함수 사용
|
||||
checkedLayers={checkedLayers}
|
||||
checkedLayersData={checkedLayersData}
|
||||
{...props}
|
||||
/>
|
||||
)}
|
||||
onFeatureSelect={onFeatureSelect}
|
||||
setIsOpen={setIsOpen}
|
||||
setFeatureData={setFeatureData}
|
||||
featureData={featureData}
|
||||
setIsSearchModalOpen={setIsSearchModalOpen}
|
||||
isOpen={isOpen}
|
||||
isSearchModalOpen={isSearchModalOpen}
|
||||
onCheckedLayersChange={handleCheckedLayersChange}
|
||||
imgVisble={true}
|
||||
searchBar={undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
// return (
|
||||
// <div className="bg-container">
|
||||
// <Gis
|
||||
// treeData={treeData}
|
||||
// isSearch={false}
|
||||
// gisMaps={gisMaps}
|
||||
// isMiniMap={false}
|
||||
// searchView={undefined}
|
||||
// detailView={(props: any) =>
|
||||
// // <NewWindowPopup
|
||||
// // onClose={handlePopupClose} // 메모이제이션된 함수 사용
|
||||
// // checkedLayers={checkedLayers}
|
||||
// // checkedLayersData={checkedLayersData}
|
||||
// // {...props}
|
||||
// // />
|
||||
// {
|
||||
|
||||
export default Map;
|
||||
// console.log('p' ,props)
|
||||
// }
|
||||
// }
|
||||
// onFeatureSelect={onFeatureSelect}
|
||||
// setIsOpen={setIsOpen}
|
||||
// setFeatureData={setFeatureData}
|
||||
// featureData={featureData}
|
||||
// setIsSearchModalOpen={setIsSearchModalOpen}
|
||||
// isOpen={isOpen}
|
||||
// isSearchModalOpen={isSearchModalOpen}
|
||||
// onCheckedLayersChange={handleCheckedLayersChange}
|
||||
// imgVisble={true}
|
||||
// searchBar={undefined}
|
||||
// />
|
||||
// </div>
|
||||
// );
|
||||
// };
|
||||
|
||||
// export default Map;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { fetchType, getFetchWithCount } from "@/components/lib/api";
|
||||
import { fetchType, getFetch, getFetchWithCount } from "@/components/lib/api";
|
||||
import type { CommonTableProps } from "../../common/type/header";
|
||||
import type { customLdrmnt } from "../../matDmd/ldrmntCoSttn";
|
||||
import {
|
||||
@@ -26,6 +26,7 @@ type ldrmntMapActions = {
|
||||
con: string,
|
||||
coNm: string
|
||||
) => void;
|
||||
ldrmntMapDetile:(featureCd:string) => Promise<customLdrmnt | undefined>;
|
||||
};
|
||||
|
||||
export type ldrmntMapType = ldrmntMapState & ldrmntMapActions;
|
||||
@@ -97,6 +98,21 @@ export const ldrmntMapActionsExport: (set: any) => ldrmntMapActions = (
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
},
|
||||
},ldrmntMapDetile: async (featureCd: string) => {
|
||||
try {
|
||||
|
||||
const ldrmtDetail = await getFetch(fetchType.WR,
|
||||
`/reuseFc/request/temp/1/4/0/${featureCd}` )
|
||||
if(ldrmtDetail&&ldrmtDetail.length>0){
|
||||
|
||||
return ldrmtDetail[0];
|
||||
}else{
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
throw error; // 호출부에서 catch 가능하도록
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
export const getFeatureCd = (featurePropertise:any, layerNm:string) => {
|
||||
console.log('layerNm ', layerNm )
|
||||
console.log('featurePropertise ', featurePropertise )
|
||||
|
||||
const featureCd =
|
||||
layerNm === "하수재이용시설"
|
||||
? featurePropertise?.swtrmt_fclt_cd
|
||||
: ["빗물이용시설", "중수도시설", "온배수시설", "수요처"].includes(
|
||||
: ["빗물이용시설", "중수도시설", "온배수시설", "수요처" ,'잠재수요처'].includes(
|
||||
layerNm
|
||||
)
|
||||
? featurePropertise?.bdst_nm
|
||||
@@ -15,5 +16,6 @@
|
||||
? featurePropertise?.swtrmt_fclt_nm
|
||||
: null;
|
||||
|
||||
console.log('featureCd ', featureCd)
|
||||
return featureCd;
|
||||
};
|
||||
@@ -14,11 +14,13 @@ import type { z } from "zod";
|
||||
export default function CoDetailModal({
|
||||
formObj,
|
||||
onFormSubmit,
|
||||
readonly
|
||||
readonly,
|
||||
isMap =false,
|
||||
}: {
|
||||
formObj: any;
|
||||
onFormSubmit: (values: customLdrmnt) => void;
|
||||
readonly?: boolean;
|
||||
isMap?:boolean
|
||||
}) {
|
||||
const defaultValues: z.infer<typeof ldrmntZod> = ldrmntZod.parse({});
|
||||
const form = useForm<z.infer<typeof ldrmntZod>>({
|
||||
@@ -54,13 +56,18 @@ export default function CoDetailModal({
|
||||
<h1 className="text-2xl font-medium text-label col-span-10">
|
||||
잠재수요처 상세정보
|
||||
</h1>
|
||||
<Button type="submit"
|
||||
className="col-start-12 col-span-1"
|
||||
size={"sm"}
|
||||
disabled={readonly}
|
||||
>
|
||||
저장
|
||||
</Button>
|
||||
{!isMap ? (
|
||||
<Button
|
||||
type="submit"
|
||||
className="col-start-12 col-span-1"
|
||||
size={"sm"}
|
||||
disabled={readonly}
|
||||
>
|
||||
저장
|
||||
</Button>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
<ScrollArea className="h-[79vh] mx-8">
|
||||
<FormField
|
||||
|
||||
Reference in New Issue
Block a user