/** * πŸ“„ useOperationTab Hook * 검색 λͺ¨λ‹¬ μœ μ§€κ΄€λ¦¬ 정보 νƒ­ ν›… * * - ν•„ν„°λ§λœ 사업 ν˜„ν™© 데이터 쑰회 및 ν¬λ§·νŒ… * - 사업 ν˜„ν™© ν…Œμ΄λΈ” μ…€ 클릭 μ‹œ 상세 κ²°κ³Όν‘œ 쑰회 * - κ²°κ³Όν‘œ μ…€ 클릭 μ‹œ 지도 ν”Όμ²˜ 선택 및 쀌 κΈ°λŠ₯ * - μ—‘μ…€ λ‹€μš΄λ‘œλ“œ κΈ°λŠ₯ (사업 ν˜„ν™© 및 κ²°κ³Όν‘œ) * - CQL ν•„ν„° 생성을 ν†΅ν•œ 쿼리 쑰건 μ„€μ • * - Zustandλ₯Ό ν†΅ν•œ μƒνƒœ 관리 및 λ‘œλ”© 처리 * - 데이터 λ§€ν•‘ 및 μ½”λ“œ λ³€ν™˜ (사업 μœ ν˜•, μš©λ„, 재질 λ“±) * * πŸ”— μ‚¬μš© API * - μœ μ§€κ΄€λ¦¬ 정보 λͺ©λ‘ 쑰회: GET /api/v1/bizInfo (sewerage-service) * - μœ μ§€κ΄€λ¦¬ 정보(사업정보) κ΄€λ ¨ μ‹œμ„€ λͺ©λ‘ 쑰회: GET /api/v1/bizInfo/fclts (sewerage-service) */ import { downloadExcelWithKoreanHeaders } from "@/shared/lib/download-excel"; import { MS_SWAGE_PPL_CODES, MS_SWAGE_PPL_USE_CODES, } from "../components/common/table"; import { getData } from "@/components/lib/api"; import { formatDisplayData } from "@/components/lib/utils/formatDisplayValue"; import GisApp from "@common/business_components/ui/map/lib/gis.core"; import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { useAlertStore } from "@/shared/lib"; import useSearchModalStore from "@/store/useSearchModalStore"; import useStore from "@/store/useStore"; import { postPopupMessageAndClose } from "@/features/windowPopup/lib/popupMessage"; import { WINDOW_POPUP_MESSAGE_TYPE } from "@/features/windowPopup/model/types"; const isPopupWindow = () => typeof window !== "undefined" && !!window.opener && window.location.pathname.startsWith("/popup/"); export default function useOperationTab() { const OPERATION_TABLE_SIZE = 5; const alert = useAlertStore((state) => state.setMessage); const { confirm } = useConfirm(); const { workType, tableData, detailTableData, curPage, detailCurPage, detailBizId, var1, var2, yearFilter, todayYear, todayMonth, todayDate, setIsSearchModalOpen, setTableData, setDetailTableData, setTableCount, setDetailTableCount, setDetailCurPage, setIsLoading, setIsDetailLoading, setIsResetDetailPage, setIsResetDetailSelection, setDetailBizId, getDateString, } = useSearchModalStore(); const { BIZ_TY_CD } = useStore(); const WORK_TYPES = [ // μœ μ§€κ΄€λ¦¬ 정보 'ꡬ뢄' 선택 λͺ©λ‘ { val: "['200', '201', '204']", text: "보수 및 κ°±μ‹ " }, { val: "['100']", text: "점검 및 진단" }, { val: "['203']", text: "μ²­μ†Œ 및 μ€€μ„€" }, ]; const OPERATION_TABLE_HEADLIST = [ // μœ μ§€κ΄€λ¦¬ 정보 - 사업 ν˜„ν™© { id: "rowNumber", title: "순번" }, { id: "bizInfoNm", title: "사업λͺ…" }, { id: "flfmtBgngYmd", title: "μˆ˜ν–‰μ‹œμž‘μΌμž" }, { id: "flfmtEndYmd", title: "μˆ˜ν–‰μ’…λ£ŒμΌμž" }, { id: "flfmtYr", title: "μˆ˜ν–‰λ…„λ„" }, { id: "bizTypeCd", title: "μ‚¬μ—…μœ ν˜•" }, { id: "bizAmt", title: "μ‚¬μ—…κΈˆμ•‘" }, ]; const MAINTENANACE_TABLE_HEADLIST = [ // μœ μ§€κ΄€λ¦¬ 정보 - 보수 및 κ°±μ‹  κ²°κ³Όν‘œ { id: "rowNumber", title: "순번" }, { id: "fcltMngNo", title: "κ΄€λ¦¬λ²ˆν˜Έ" }, { id: "swtrmt_zone_nm", title: "μ²˜λ¦¬κ΅¬μ—­" }, { id: "usgCd", title: "μš©λ„" }, // { id: "lgalDrblyr", title: "λ‚΄μš©μ—°μˆ˜" }, // { id: "acqsPrmpc", title: "μ·¨λ“κΈˆμ•‘" }, { id: "mqltCd", title: "재질" }, { id: "pdmtVl", title: "κ΄€κ²½(mm)" }, { id: "prlgVl", title: "μ—°μž₯(m)" }, { id: "instlYmd", title: "μ„€μΉ˜μΌμž" }, // { id: "instlYmd", title: "사업ꡬ뢄" }, ]; const CLEANING_TABLE_HEADLIST = [ // μœ μ§€κ΄€λ¦¬ 정보 - μ²­μ†Œ 및 μ€€μ„€ κ²°κ³Όν‘œ { id: "rowNumber", title: "순번" }, { id: "fcltMngNo", title: "κ΄€λ¦¬λ²ˆν˜Έ" }, { id: "swtrmt_zone_nm", title: "μ²˜λ¦¬κ΅¬μ—­" }, { id: "usgCd", title: "μš©λ„" }, // { id: "lgalDrblyr", title: "λ‚΄μš©μ—°μˆ˜" }, // { id: "acqsPrmpc", title: "μ·¨λ“κΈˆμ•‘" }, { id: "mqltCd", title: "재질" }, { id: "pdmtVl", title: "κ΄€κ²½(mm)" }, { id: "prlgVl", title: "μ—°μž₯(m)" }, { id: "instlYmd", title: "μ„€μΉ˜μΌμž" }, ]; const INSPECTION_TABLE_HEADLIST = [ // μœ μ§€κ΄€λ¦¬ 정보 - 점검 및 진단 κ²°κ³Όν‘œ { id: "rowNumber", title: "순번" }, { id: "fcltMngNo", title: "κ΄€λ¦¬λ²ˆν˜Έ" }, { id: "swtrmt_zone_nm", title: "μ²˜λ¦¬κ΅¬μ—­" }, { id: "usgCd", title: "μš©λ„" }, // { id: "riskEval", title: "μœ„ν—˜ν‰κ°€" }, // { id: "acqsPrmpc", title: "μ·¨λ“κΈˆμ•‘" }, // { id: "lgalDrblyr", title: "λ‚΄μš©μ—°μˆ˜" }, // { id: "remLife", title: "μž”μ‘΄μˆ˜λͺ…" }, { id: "mqltCd", title: "재질" }, { id: "pdmtVl", title: "κ΄€κ²½(mm)" }, { id: "prlgVl", title: "μ—°μž₯(m)" }, { id: "instlYmd", title: "μ„€μΉ˜μΌμž" }, { id: "strc_stts_grd", title: "ꡬ쑰적 μƒνƒœλ“±κΈ‰" }, { id: "oper_stts_grd", title: "운영적 μƒνƒœλ“±κΈ‰" }, ]; const fetchOperationFilteredData = async () => { const RequestDTO: Record = { page: `${curPage - 1}`, size: `${OPERATION_TABLE_SIZE}`, }; if (var1) RequestDTO.bizInfoNm = var1; if (var2 != "0" && var2) RequestDTO.bizTypeCd = var2; // μˆ˜ν–‰κΈ°κ°„ λ²”μœ„ const startDate = getDateString(yearFilter.start, "", "", "19000101"); const endDate = getDateString( yearFilter.end, "", "", `${todayYear}${todayMonth}${todayDate}`, ); RequestDTO.fromflfmtEndYmd = startDate; RequestDTO.toflfmtEndYmd = endDate; // JSON.parse μ‚¬μš©μœΌλ‘œ λ¬Έμžμ—΄ -> λ°°μ—΄ λ³€ν™˜ RequestDTO.workTypes = JSON.parse(workType.replace(/'/g, '"')); const params = new URLSearchParams(RequestDTO).toString(); const res = await getData(`v1/bizInfo?${params}`); const totalElements = Number(res.totalElements ?? 0); const mappedContent = (res.content || []).map( (item: any, index: number) => { const formattedItem = formatDisplayData(item); const matched = BIZ_TY_CD.find( (code) => code.lwpoCd === item.bizTypeCd, ); return { ...formattedItem, rowNumber: totalElements - ((curPage - 1) * OPERATION_TABLE_SIZE + index), bizTypeCd: matched ? matched.lwpoCdNm : item.bizTypeCd, }; }, ); setTableData(mappedContent || []); setTableCount(totalElements); setDetailTableData([]); setDetailTableCount(0); }; // μœ μ§€κ΄€λ¦¬ 정보 ν…Œμ΄λΈ” cellClick ν•Έλ“€λŸ¬ const handleOperationCellClick = async ( index?: number | undefined, headId?: String, ) => { setIsResetDetailPage(true); // νŽ˜μ΄μ§€λ₯Ό 1둜 μ΄ˆκΈ°ν™” setIsResetDetailSelection(true); // 선택 μ΄ˆκΈ°ν™” setIsResetDetailPage(true); // λ””ν…ŒμΌ νŽ˜μ΄μ§€λ₯Ό μ΄ˆκΈ°ν™” if (typeof index === "number") { setIsDetailLoading(true); setDetailBizId(tableData[index].bizId); setDetailCurPage(1); // 상세 νŽ˜μ΄μ§€ μ΄ˆκΈ°ν™” try { const RequestDTO: Record = { page: "0", size: `${OPERATION_TABLE_SIZE}`, bizId: tableData[index % OPERATION_TABLE_SIZE].bizId, }; RequestDTO.workTypes = JSON.parse(workType.replace(/'/g, '"')); const res = await getData( `v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`, ); const totalDetailElements = Number(res.count ?? 0); const mappedData = (res.data || []).map( (item: any, detailIndex: number) => { const formattedItem = formatDisplayData(item); const usgCdObj = MS_SWAGE_PPL_USE_CODES.find( (code) => code.val === item?.usgCd?.trim(), ); const mqltCdObj = MS_SWAGE_PPL_CODES.find( (code) => code.val === item?.mqltCd?.trim(), ); return { ...formattedItem, rowNumber: totalDetailElements - detailIndex, usgCd: usgCdObj ? usgCdObj.text : item.usgCd, mqltCd: mqltCdObj ? mqltCdObj.text : item.mqltCd, swtrmt_zone_nm: item.swtrmt_zone_nm ? item.swtrmt_zone_nm : "-", }; }, ); setDetailTableData(mappedData); setDetailTableCount(totalDetailElements); } catch (error) { console.error("μœ μ§€κ΄€λ¦¬ 정보 cellClick μ—λŸ¬:", error); setDetailTableData([]); setDetailTableCount(0); alert("μ„ νƒν•œ μ‚¬μ—…μ˜ κ²°κ³Ό λͺ©λ‘μ„ λΆˆλŸ¬μ˜€μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€."); } finally { setIsDetailLoading(false); setIsResetDetailPage(false); setIsResetDetailSelection(false); } } }; // μœ μ§€κ΄€λ¦¬ 정보 λ””ν…ŒμΌ ν…Œμ΄λΈ” cellClick ν•Έλ“€λŸ¬ const handleOperationResultCellClick = async ( index?: number | undefined, headId?: String, ) => { if (typeof index === "number") { const row = detailTableData[index]; if (isPopupWindow()) { postPopupMessageAndClose( WINDOW_POPUP_MESSAGE_TYPE.MAP_SEARCH_SELECT_FEATURE, { layerNm: row.lyrTypeNm, fid: String(row.fid), }, ); return; } setIsLoading(true); const layerNm = row.lyrTypeNm; const fid = row.fid; const core = GisApp.Module.layer as any; await core.showSearchResultsFromGeoJSON(layerNm, fid); setIsLoading(false); setIsSearchModalOpen(false); // SearchModal λ‹«κΈ° } }; // μœ μ§€κ΄€λ¦¬ 정보 λ””ν…ŒμΌ ν…Œμ΄λΈ” νŽ˜μ΄μ§€λ„€μ΄μ…˜ ν•Έλ“€λŸ¬ const handleOperationPageNation = async (index?: number | undefined) => { if (typeof index === "number") { setIsDetailLoading(true); try { const RequestDTO: Record = { page: `${detailCurPage - 1}`, size: `${OPERATION_TABLE_SIZE}`, bizId: String(detailBizId), }; const res = await getData( `v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`, ); const totalElements = Number(res.count ?? 0); const mappedData = (res.data || []).map( (item: any, detailIndex: number) => { const formattedItem = formatDisplayData(item); const usgCdObj = MS_SWAGE_PPL_USE_CODES.find( (code) => code.val === item?.usgCd?.trim(), ); const mqltCdObj = MS_SWAGE_PPL_CODES.find( (code) => code.val === item?.mqltCd?.trim(), ); return { ...formattedItem, rowNumber: totalElements - ((detailCurPage - 1) * OPERATION_TABLE_SIZE + detailIndex), usgCd: usgCdObj ? usgCdObj.text : item.usgCd, mqltCd: mqltCdObj ? mqltCdObj.text : item.mqltCd, swtrmt_zone_nm: item.swtrmt_zone_nm ? item.swtrmt_zone_nm : "-", }; }, ); setDetailTableData(mappedData); setDetailTableCount(totalElements); } catch (error) { console.error("μœ μ§€κ΄€λ¦¬ 정보 νŽ˜μ΄μ§€λ„€μ΄μ…˜ μ—λŸ¬:", error); alert("μ„ νƒν•œ μ‚¬μ—…μ˜ κ²°κ³Ό λͺ©λ‘μ„ λΆˆλŸ¬μ˜€μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€."); } finally { setIsDetailLoading(false); } } }; // μœ μ§€κ΄€λ¦¬ 정보 Excel λ‹€μš΄λ‘œλ“œ ν•Έλ“€λŸ¬ μΆ”κ°€ const operationExcelDownload = async () => { if (tableData.length === 0) { alert("λ‹€μš΄λ‘œλ“œ ν•  Excel 파일이 μ—†μŠ΅λ‹ˆλ‹€.\n쑰회 ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”."); return; } if ( !(await confirm( "파일 λ‹€μš΄λ‘œλ“œμ—λŠ” 2λΆ„ λ‚΄μ™Έμ˜ μ‹œκ°„μ΄ μ†Œμš”λ  수 μžˆμŠ΅λ‹ˆλ‹€.\n파일 λ‹€μš΄λ‘œλ“œλ₯Ό μ§„ν–‰ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?", )) ) return; await onAnalysis(); async function onAnalysis() { setIsLoading(true); try { const RequestDTO: Record = { size: "10000", }; if (var1) RequestDTO.bizInfoNm = var1; if (var2 != "0" && var2) RequestDTO.bizTypeCd = var2; // μˆ˜ν–‰κΈ°κ°„ λ²”μœ„ const startDate = getDateString(yearFilter.start, "", "", "19000101"); const endDate = getDateString( yearFilter.end, "", "", `${todayYear}${todayMonth}${todayDate}`, ); RequestDTO.fromflfmtEndYmd = startDate; RequestDTO.toflfmtEndYmd = endDate; // JSON.parse μ‚¬μš©μœΌλ‘œ λ¬Έμžμ—΄ -> λ°°μ—΄ λ³€ν™˜ RequestDTO.workTypes = JSON.parse(workType.replace(/'/g, '"')); const params = new URLSearchParams(RequestDTO).toString(); const res = await getData(`v1/bizInfo?${params}`); // 헀더 λ§€ν•‘ μ •μ˜ const headerMapping: { [key: string]: string } = { bizInfoNm: "사업λͺ…", flfmtBgngYmd: "μˆ˜ν–‰μ‹œμž‘μΌμž", flfmtEndYmd: "μˆ˜ν–‰μ’…λ£ŒμΌμž", flfmtYr: "μˆ˜ν–‰λ…„λ„", bizTypeCd: "μ‚¬μ—…μœ ν˜•", bizAmt: "μ‚¬μ—…κΈˆμ•‘(원)", }; const bizTyCdMap = new Map( BIZ_TY_CD.map((code) => [code.lwpoCd, code.lwpoCdNm]), ); const mappedContent = (res.content || []).map((item: any) => { const formattedItem = formatDisplayData(item); return { bizInfoNm: formattedItem.bizInfoNm ?? item.bizInfoNm ?? "", flfmtBgngYmd: formattedItem.flfmtBgngYmd ?? item.flfmtBgngYmd ?? "", flfmtEndYmd: formattedItem.flfmtEndYmd ?? item.flfmtEndYmd ?? "", flfmtYr: formattedItem.flfmtYr ?? item.flfmtYr ?? "", bizTypeCd: bizTyCdMap.get(item.bizTypeCd) || item.bizTypeCd || formattedItem.bizTypeCd || "", bizAmt: ((v) => (v === 0 || v === "0" ? "0" : (v ?? "")))( formattedItem.bizAmt ?? item.bizAmt, ), }; }); // μ„ νƒλœ ν–‰ 데이터λ₯Ό Excel λ‹€μš΄λ‘œλ“œ ν˜•μ‹μœΌλ‘œ λ³€ν™˜ const excelData = mappedContent; // λ°°μ—΄λ‘œ κ°μ‹Έμ„œ 전달 // 파일λͺ… 생성 (λΆ„μ„λ²ˆν˜Έ 기반) const label = WORK_TYPES.find((type) => type.val === workType)?.text; const fileName = `${label} 사업 ν˜„ν™©_${todayYear}${todayMonth}${todayDate}`; await downloadExcelWithKoreanHeaders({ data: excelData as JSON[], fileName: fileName, sheetNameArray: [fileName], headerRange: "A1:F1", headerMapping: headerMapping, }); setIsLoading(false); } catch (error) { setIsLoading(false); console.error("Excel λ‹€μš΄λ‘œλ“œ 쀑 였λ₯˜ λ°œμƒ:", error); alert("Excel λ‹€μš΄λ‘œλ“œ 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”."); } } }; // μœ μ§€κ΄€λ¦¬ 정보 κ²°κ³Όν‘œ Excel λ‹€μš΄λ‘œλ“œ ν•Έλ“€λŸ¬ μΆ”κ°€ const operationResultExcelDownload = async () => { if (detailTableData.length === 0) { alert("λ‹€μš΄λ‘œλ“œ ν•  Excel 파일이 μ—†μŠ΅λ‹ˆλ‹€.\n쑰회 ν›„ λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”."); return; } if ( !(await confirm( "파일 λ‹€μš΄λ‘œλ“œμ—λŠ” 2λΆ„ λ‚΄μ™Έμ˜ μ‹œκ°„μ΄ μ†Œμš”λ  수 μžˆμŠ΅λ‹ˆλ‹€.\n파일 λ‹€μš΄λ‘œλ“œλ₯Ό μ§„ν–‰ν•˜μ‹œκ² μŠ΅λ‹ˆκΉŒ?", )) ) return; await onAnalysis(); async function onAnalysis() { setIsLoading(true); try { const RequestDTO: Record = { size: "100", bizId: String(detailBizId), }; const res = await getData( `v1/bizInfo/fclts?${new URLSearchParams(RequestDTO).toString()}`, ); // 헀더 λ§€ν•‘ μ •μ˜ const headerMapping: { [key: string]: string } = { fcltMngNo: "κ΄€λ¦¬λ²ˆν˜Έ", swtrmt_zone_nm: "μ²˜λ¦¬κ΅¬μ—­", usgCd: "μš©λ„", mqltCd: "재질", pdmtVl: "κ΄€κ²½(mm)", prlgVl: "μ—°μž₯(m)", instlYmd: "μ„€μΉ˜μΌμž", strc_stts_grd: "ꡬ쑰적 μƒνƒœλ“±κΈ‰", oper_stts_grd: "운영적 μƒνƒœλ“±κΈ‰", }; const usgCdMap = new Map( MS_SWAGE_PPL_USE_CODES.map((code) => [code.val, code.text]), ); const mqltCdMap = new Map( MS_SWAGE_PPL_CODES.map((code) => [code.val, code.text]), ); // 🎯 단일 반볡문으둜 μ΅œμ ν™” - 각 μ•„μ΄ν…œλ§ˆλ‹€ ν•„μš”ν•œ ν•„λ“œλ§Œ 직접 λ§€ν•‘ const mappedData = (res.data || []).map((item: any) => { const formattedItem = formatDisplayData(item); // trim ν•œ 번만 μˆ˜ν–‰ const trimmedUsgCd = item?.usgCd?.trim(); const trimmedMqltCd = item?.mqltCd?.trim(); // zone κ°’ ν•œ 번만 계산 const zone = item.swtrmtZoneNm ?? formattedItem.swtrmt_zone_nm ?? item.swtrmt_zone_nm ?? ""; // 직접 λ§€ν•‘ - 반볡문 없이 ν•œ λ²ˆμ— 객체 생성 return { fcltMngNo: formattedItem.fcltMngNo ?? item.fcltMngNo ?? "", swtrmt_zone_nm: zone === null || zone === "" ? "-" : zone, usgCd: usgCdMap.get(trimmedUsgCd) || item.usgCd || formattedItem.usgCd || "", mqltCd: mqltCdMap.get(trimmedMqltCd) || item.mqltCd || formattedItem.mqltCd || "", pdmtVl: formattedItem.pdmtVl ?? item.pdmtVl ?? "", prlgVl: formattedItem.prlgVl ?? item.prlgVl ?? "", instlYmd: formattedItem.instlYmd ?? item.instlYmd ?? "", strc_stts_grd: ((v) => (v === 0 || v === "0" ? "0" : (v ?? "")))( formattedItem.strc_stts_grd ?? item.strc_stts_grd, ), oper_stts_grd: ((v) => (v === 0 || v === "0" ? "0" : (v ?? "")))( formattedItem.oper_stts_grd ?? item.oper_stts_grd, ), }; }); // μ„ νƒλœ ν–‰ 데이터λ₯Ό Excel λ‹€μš΄λ‘œλ“œ ν˜•μ‹μœΌλ‘œ λ³€ν™˜ const excelData = mappedData; // λ°°μ—΄λ‘œ κ°μ‹Έμ„œ 전달 // 파일λͺ… 생성 (λΆ„μ„λ²ˆν˜Έ 기반) const label = WORK_TYPES.find((type) => type.val === workType)?.text; const fileName = `${label} κ²°κ³Όν‘œ_${todayYear}${todayMonth}${todayDate}`; await downloadExcelWithKoreanHeaders({ data: excelData as JSON[], fileName: fileName, sheetNameArray: [fileName], headerRange: "A1:I1", headerMapping: headerMapping, }); setIsLoading(false); } catch (error) { setIsLoading(false); console.error("Excel λ‹€μš΄λ‘œλ“œ 쀑 였λ₯˜ λ°œμƒ:", error); alert("Excel λ‹€μš΄λ‘œλ“œ 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€. λ‹€μ‹œ μ‹œλ„ν•΄μ£Όμ„Έμš”."); } } }; const emitMultipleFeaturesToMap = () => { if (detailTableData.length === 0 || !isPopupWindow()) return false; const row = detailTableData[0]; postPopupMessageAndClose( WINDOW_POPUP_MESSAGE_TYPE.MAP_SEARCH_SHOW_MULTIPLE, { layerNm: row.lyrTypeNm, fids: JSON.stringify(detailTableData.map((item) => item.fid)), }, ); return true; }; return { WORK_TYPES, OPERATION_TABLE_HEADLIST, MAINTENANACE_TABLE_HEADLIST, CLEANING_TABLE_HEADLIST, INSPECTION_TABLE_HEADLIST, OPERATION_TABLE_SIZE, fetchOperationFilteredData, handleOperationCellClick, handleOperationResultCellClick, handleOperationPageNation, emitMultipleFeaturesToMap, operationExcelDownload, operationResultExcelDownload, }; }