Files
frontend/apps/sn/app/(map-layout)/map/components/gis-management/use-gis-management-common-codes.ts
T

129 lines
3.4 KiB
TypeScript

/** GIS 관리 화면에 필요한 공통코드를 조회하고 선택 항목으로 제공한다. */
"use client";
import { useEffect, useState } from "react";
import { getCommonCodes } from "@/entities/code/api/common-code-api";
type CodeLabelMap = Record<string, string>;
const COMMON_CODE_GROUPS = {
uploadStatus: "GISULDSTTS",
downloadStatus: "GISDWNLDSTTS",
facilityType: "SNFCLTSE",
} as const;
const DEFAULT_UPLOAD_STATUS_LABELS: CodeLabelMap = {
COMPLETED: "업로드완료",
VALIDATION_FAILED: "검증실패",
FAILED: "업로드실패",
};
const DEFAULT_DOWNLOAD_STATUS_LABELS: CodeLabelMap = {
QUEUED: "작업대기",
RUNNING: "파일생성중",
READY: "다운로드준비완료",
FAILED: "파일생성실패",
};
const DEFAULT_FACILITY_TYPE_LABELS: CodeLabelMap = {
PPL: "하수관로",
MNHL: "맨홀",
};
const cachedLabelMaps = new Map<string, CodeLabelMap>();
const pendingLabelMaps = new Map<string, Promise<CodeLabelMap>>();
/** 같은 브라우저 세션에서 각 GIS 관리 코드그룹을 한 번만 조회한다. */
const loadCodeLabelMap = async (
upCd: string,
fallback: CodeLabelMap,
): Promise<CodeLabelMap> => {
const cached = cachedLabelMaps.get(upCd);
if (cached) return cached;
const pending = pendingLabelMaps.get(upCd);
if (pending) return pending;
const request = getCommonCodes(upCd)
.then((codes) => {
const labels = { ...fallback };
codes.forEach((code) => {
if (code.lwpoCd && code.lwpoCdNm) {
labels[code.lwpoCd] = code.lwpoCdNm;
}
});
cachedLabelMaps.set(upCd, labels);
return labels;
})
.finally(() => {
pendingLabelMaps.delete(upCd);
});
pendingLabelMaps.set(upCd, request);
return request;
};
/** GIS 관리 화면의 코드값은 유지하고 상태·시설구분 표시명만 CMS 기준으로 제공한다. */
export const useGisManagementCommonCodes = () => {
const [uploadStatusLabels, setUploadStatusLabels] =
useState<CodeLabelMap>(
cachedLabelMaps.get(COMMON_CODE_GROUPS.uploadStatus) ??
DEFAULT_UPLOAD_STATUS_LABELS,
);
const [downloadStatusLabels, setDownloadStatusLabels] =
useState<CodeLabelMap>(
cachedLabelMaps.get(COMMON_CODE_GROUPS.downloadStatus) ??
DEFAULT_DOWNLOAD_STATUS_LABELS,
);
const [facilityTypeLabels, setFacilityTypeLabels] =
useState<CodeLabelMap>(
cachedLabelMaps.get(COMMON_CODE_GROUPS.facilityType) ??
DEFAULT_FACILITY_TYPE_LABELS,
);
useEffect(() => {
let cancelled = false;
const applyLabels = (
upCd: string,
fallback: CodeLabelMap,
setter: (labels: CodeLabelMap) => void,
) => {
loadCodeLabelMap(upCd, fallback)
.then((labels) => {
if (!cancelled) setter(labels);
})
.catch((error) => {
console.error(`${upCd} 공통코드 조회에 실패했습니다.`, error);
});
};
applyLabels(
COMMON_CODE_GROUPS.uploadStatus,
DEFAULT_UPLOAD_STATUS_LABELS,
setUploadStatusLabels,
);
applyLabels(
COMMON_CODE_GROUPS.downloadStatus,
DEFAULT_DOWNLOAD_STATUS_LABELS,
setDownloadStatusLabels,
);
applyLabels(
COMMON_CODE_GROUPS.facilityType,
DEFAULT_FACILITY_TYPE_LABELS,
setFacilityTypeLabels,
);
return () => {
cancelled = true;
};
}, []);
return {
uploadStatusLabels,
downloadStatusLabels,
facilityTypeLabels,
};
};