Files
frontend/apps/sn/src/features/facility-detail/ui/smh.tsx
T

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;