144 lines
4.1 KiB
TypeScript
144 lines
4.1 KiB
TypeScript
import { fitMapSelection } from "@/features/map-search/lib/map-navigation";
|
|
/**
|
|
* 화면명: 하수맨홀 정보
|
|
* ➡️ 경로 : 하수관망도 메인 페이지 (시설물 클릭) - 오른쪽 팝업창 (하수맨홀)
|
|
*
|
|
* 📄 Smh
|
|
* 하수맨홀 정보 컴포넌트
|
|
*
|
|
* - 하수맨홀의 자체입력정보 표시 및 편집 기능
|
|
* - VerticalTable을 통한 입력 폼 렌더링
|
|
* - 상류관로 검색 및 지도 포커스 기능
|
|
* - 저장 버튼을 통한 데이터 저장 기능
|
|
*
|
|
* 🔗 사용 API
|
|
* - 상류관로 조회: GET /api/v1/fcltMhl/upperPpls/{fcltMngNo} (sewerage-service)
|
|
*/
|
|
import { VerticalTable } from "@/components/ui/vertical-table";
|
|
import { type ReactNode, useEffect, useState } from "react";
|
|
import GisApp from "@common/business_components/ui/map/lib/gis.core";
|
|
import { getData } from "@/shared/api/sewerage-api";
|
|
|
|
// 상류관로 보기 함수 (FeatureClickEventPopup에서 사용)
|
|
export async function searchUpperPpls(
|
|
gisMap: any,
|
|
fcltMngNo: any,
|
|
notify: (message: string) => void,
|
|
) {
|
|
let data: any = null;
|
|
try {
|
|
data = await getData(`v1/fcltMhl/upperPpls/${fcltMngNo}`);
|
|
} catch (error) {
|
|
console.error("JSON parsing error:", error);
|
|
notify(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
|
|
return;
|
|
}
|
|
|
|
if (!data) {
|
|
notify(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
|
|
return;
|
|
}
|
|
|
|
const select: any = GisApp.Module.select;
|
|
let foundFeature: any = null;
|
|
|
|
(data || []).forEach((item: any) => {
|
|
const pplMngNo = item.ppl_mng_no?.trim?.();
|
|
|
|
gisMap
|
|
.getLayers()
|
|
.getArray()
|
|
.filter((e: any) => e.get("lyrTyNm") == "tb_ms_swage_ppl")
|
|
.forEach((layer: any) => {
|
|
const source = layer.getSource?.();
|
|
if (source?.getFeatures) {
|
|
const features = source.getFeatures();
|
|
for (const f of features) {
|
|
if (f.values_.fclt_mng_no?.trim?.() === pplMngNo) {
|
|
foundFeature = f;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
if (foundFeature) select?.selectMultiFeature?.(foundFeature, true);
|
|
});
|
|
|
|
if (!foundFeature) notify(`해당 맨홀의 상류관로를 찾을 수 없습니다.`);
|
|
|
|
const geometry = foundFeature?.getGeometry();
|
|
if (geometry) {
|
|
const extent = geometry.getExtent();
|
|
fitMapSelection(gisMap, extent, {
|
|
duration: 300,
|
|
padding: [50, 50, 50, 50],
|
|
maxZoom: 14,
|
|
constrainResolution: true,
|
|
nearest: true,
|
|
});
|
|
}
|
|
}
|
|
|
|
const inputColumn = [
|
|
{ id: "swtrmtZoneNm", title: "처리구역", type: "input" },
|
|
{ id: "mltvZoneNm", title: "배수구역", type: "input" },
|
|
{ id: "mltvDtdvNm", title: "배수분구", type: "input" },
|
|
{ id: "layCd", title: "매설위치", type: "select", options: ["도로", "하상"] },
|
|
];
|
|
const Smh = ({
|
|
featureData,
|
|
onSaveClick,
|
|
surveyResultContent,
|
|
}: {
|
|
featureData: any;
|
|
onSaveClick?: () => void;
|
|
surveyResultContent?: ReactNode;
|
|
}) => {
|
|
const [formData, setFormData] = useState<any>({});
|
|
|
|
// featureData가 변경될 때 formData 초기화
|
|
useEffect(() => {
|
|
if (featureData) {
|
|
setFormData(featureData);
|
|
}
|
|
}, [featureData]);
|
|
|
|
// 폼 데이터가 변경될 때 호출될 핸들러
|
|
const handleFormDataChange = (newFormData: any) => {
|
|
setFormData(newFormData);
|
|
};
|
|
|
|
// 저장 버튼 클릭 시 최신 formData를 부모에게 전달
|
|
const handleSaveClick = () => {
|
|
if (onSaveClick) {
|
|
// 저장 전에 formData를 부모 컴포넌트의 handleSaveClick에 전달
|
|
onSaveClick();
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
<VerticalTable
|
|
headName="입력정보"
|
|
tableData={featureData ? [formData] : []}
|
|
headlist={inputColumn}
|
|
pageSize={20}
|
|
total={0}
|
|
children={undefined}
|
|
cellClick={undefined}
|
|
isEditable={true}
|
|
onPageChange={function (page: number): void {
|
|
throw new Error("Function not implemented.");
|
|
}}
|
|
showSaveButton={true}
|
|
onSaveClick={handleSaveClick}
|
|
onFormDataChange={handleFormDataChange} // 폼 데이터 변경 콜백 추가
|
|
/>
|
|
{surveyResultContent}
|
|
</>
|
|
);
|
|
};
|
|
|
|
export default Smh;
|