This commit is contained in:
@@ -5,6 +5,11 @@ import { useEffect, useState } from "react";
|
||||
import useSWR from "swr";
|
||||
|
||||
import { useAlertStore, useUserStore } from "@/shared/lib";
|
||||
import {
|
||||
fetchSearchCondition,
|
||||
fetchSearchConditionInput,
|
||||
SEARCH_CONDITION_SWR_KEY,
|
||||
} from "@/shared/lib/use-search-condition-sido-list";
|
||||
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
import type {
|
||||
ApiResponse,
|
||||
@@ -23,28 +28,28 @@ import {
|
||||
SelectValue,
|
||||
} from "@common/components";
|
||||
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
|
||||
import {
|
||||
defaultSearchFormProps,
|
||||
type SearchFormClsfCd,
|
||||
type SearchFormProps,
|
||||
type SearchFormValues,
|
||||
} from "../type/SearchForm.type";
|
||||
import { doList } from "../util/column/input/DoList";
|
||||
|
||||
const getSidoListFetcher = async (
|
||||
key: [string, string],
|
||||
): Promise<ApiResponse<SearchCondition>> => {
|
||||
return statisticsApi.getSidoList({ instSeCd: key[1] });
|
||||
};
|
||||
function isDoListBsnm(bsnmCd: string | undefined): boolean {
|
||||
return Boolean(bsnmCd && doList.includes(bsnmCd));
|
||||
}
|
||||
|
||||
const getSggListFetcher = async (
|
||||
key: [string, string, string, string],
|
||||
key: [string, string, string, "Y" | "N"],
|
||||
): Promise<ApiResponse<Sgg[]>> => {
|
||||
const gugunSkipYn = doList.includes(key[3]) ? "N" : "Y";
|
||||
return statisticsApi.getSggList(key[1], {
|
||||
instSeCd: key[2],
|
||||
gugunSkipYn,
|
||||
});
|
||||
const [, sidoName, instSeCd, gugunSkipYn] = key;
|
||||
const params = { instSeCd, gugunSkipYn };
|
||||
if (gugunSkipYn === "N") {
|
||||
return statisticsApi.getSggAllList(sidoName, params);
|
||||
}
|
||||
return statisticsApi.getSggList(sidoName, params);
|
||||
};
|
||||
|
||||
function buildSearchFormValues(
|
||||
@@ -59,9 +64,15 @@ function buildSearchFormValues(
|
||||
: "ALL";
|
||||
|
||||
if (d?.sido) {
|
||||
const sidoItem = sidoList?.data?.sidoList?.find(
|
||||
(item) => item.sido === d.sido,
|
||||
);
|
||||
const gugun =
|
||||
d.gugun ||
|
||||
(sidoItem && !isDoListBsnm(sidoItem.bsnmCd) ? "ALL" : "");
|
||||
return {
|
||||
sido: d.sido,
|
||||
gugun: d.gugun || "",
|
||||
gugun,
|
||||
year: d.year || defaultYear.toString(),
|
||||
order: d.order || "",
|
||||
fctName: d.fctName || "",
|
||||
@@ -93,7 +104,8 @@ function buildSearchFormValues(
|
||||
|
||||
return {
|
||||
sido: useFirstSido ? first.sido : "",
|
||||
gugun: "",
|
||||
gugun:
|
||||
useFirstSido && first && !isDoListBsnm(first.bsnmCd) ? "ALL" : "",
|
||||
year: d?.year || defaultYear.toString(),
|
||||
order: d?.order || "",
|
||||
fctName: d?.fctName || "",
|
||||
@@ -117,10 +129,12 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
const defaultYear = currentYear - 1;
|
||||
const isInput = Boolean(props.isInput);
|
||||
const sidoListKind = isInput ? "input" : "default";
|
||||
|
||||
const { data: sidoList } = useSWR<ApiResponse<SearchCondition>>(
|
||||
["sido-list", instSeCd],
|
||||
getSidoListFetcher,
|
||||
SEARCH_CONDITION_SWR_KEY(instSeCd, sidoListKind),
|
||||
isInput ? fetchSearchConditionInput : fetchSearchCondition,
|
||||
{
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
@@ -157,7 +171,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
: {
|
||||
...prev,
|
||||
sido: first.sido,
|
||||
gugun: "",
|
||||
gugun: isDoListBsnm(first.bsnmCd) ? "" : "ALL",
|
||||
bsnmCd: first.bsnmCd,
|
||||
},
|
||||
);
|
||||
@@ -168,9 +182,18 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
mergedProps.sido,
|
||||
]);
|
||||
|
||||
const sggKey: [string, string, string, string] | null =
|
||||
values.sido && values.sido !== "ALL"
|
||||
? ["sgg-list", values.sido, instSeCd, values.bsnmCd || ""]
|
||||
const selectedSido = sidoList?.data?.sidoList?.find(
|
||||
(item) => item.sido === values.sido,
|
||||
);
|
||||
const gugunSkipYn = selectedSido?.gugunSkipYn ?? "Y";
|
||||
const sggKey: [string, string, string, "Y" | "N"] | null =
|
||||
values.sido && values.sido !== "ALL" && sidoList?.data
|
||||
? [
|
||||
gugunSkipYn === "N" ? "sgg-all" : "sgg-list",
|
||||
values.sido,
|
||||
instSeCd,
|
||||
gugunSkipYn,
|
||||
]
|
||||
: null;
|
||||
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(
|
||||
sggKey,
|
||||
@@ -195,12 +218,25 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
);
|
||||
const sggOptions = sggList?.data ?? [];
|
||||
|
||||
// 시도 설정 후 시군구 목록이 오면 첫 번째 항목 자동 선택
|
||||
// 도(doList): 시군구 목록 첫 항목. 광역시·세종·제주: 전체
|
||||
useEffect(() => {
|
||||
if (!mergedProps.gugun) return;
|
||||
if (props.defaultRegionAll) return;
|
||||
if (props.defaultValues?.gugun) return;
|
||||
if (!values.sido || values.sido === "ALL") return;
|
||||
if (!selectedSido) return;
|
||||
|
||||
if (!isDoListBsnm(selectedSido.bsnmCd)) {
|
||||
setValues((prev) => {
|
||||
if (prev.gugun) return prev;
|
||||
return {
|
||||
...prev,
|
||||
gugun: "ALL",
|
||||
bsnmCd: selectedSido?.bsnmCd || prev.bsnmCd,
|
||||
};
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const firstSgg = sggList?.data?.[0];
|
||||
if (!firstSgg) return;
|
||||
@@ -216,6 +252,7 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
}, [
|
||||
sggList,
|
||||
values.sido,
|
||||
selectedSido?.bsnmCd,
|
||||
mergedProps.gugun,
|
||||
props.defaultValues?.gugun,
|
||||
props.defaultRegionAll,
|
||||
@@ -237,10 +274,14 @@ const SearchForm = (props: SearchFormProps = {}) => {
|
||||
? ""
|
||||
: sidoList?.data?.sidoList?.find((v) => v.sido === value)
|
||||
?.bsnmCd || "";
|
||||
const gugunAll =
|
||||
props.defaultRegionAll ||
|
||||
value === "ALL" ||
|
||||
!isDoListBsnm(selectedBsnm);
|
||||
setValues((prev) => ({
|
||||
...prev,
|
||||
sido: value,
|
||||
gugun: props.defaultRegionAll || value === "ALL" ? "ALL" : "",
|
||||
gugun: gugunAll ? "ALL" : "",
|
||||
bsnmCd: selectedBsnm,
|
||||
}));
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@ import useSWR from "swr";
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { statisticsInputSewPipeApiService } from "@/entities/statistics/api/input/statistics-sewage-pipe-input-service";
|
||||
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
import { isGugunRequiredSido } from "@/entities/statistics";
|
||||
import type {
|
||||
SeweragePipeFacilitiesListRequest,
|
||||
SeweragePipeFacilityAdminAreaListRequest,
|
||||
@@ -34,7 +35,6 @@ import {
|
||||
import { getUserInfo } from "../../../../../packages/common/components/src/api";
|
||||
import type { ColumnInfo } from "../type/DataGrid.type";
|
||||
import type { SearchFormValues } from "../type/SearchForm.type";
|
||||
import { doNameList } from "../util/column/input/DoList";
|
||||
|
||||
import CompactDataGrid from "./CompactDataGrid";
|
||||
|
||||
@@ -115,9 +115,9 @@ const getSidoListFetcher = async (): Promise<ApiResponse<SearchCondition>> => {
|
||||
};
|
||||
|
||||
const getSggAllListFetcher = async (
|
||||
key: [string, string],
|
||||
key: [string, string, "Y" | "N"],
|
||||
): Promise<ApiResponse<Sgg[]>> => {
|
||||
return statisticsApi.getSggList(key[1]);
|
||||
return statisticsApi.getSggList(key[1], { gugunSkipYn: key[2] });
|
||||
};
|
||||
|
||||
type SidoSggFacilityNameSearchFormProps = {
|
||||
@@ -185,8 +185,14 @@ const SidoSggFacilityNameSearchForm = ({
|
||||
const didAutoFetchRef = useRef(false);
|
||||
const isSavingConnectionRef = useRef(false);
|
||||
|
||||
const sggKey: [string, string] | null =
|
||||
sido && sido !== "ALL" ? ["sgg-all", sido] : null;
|
||||
const selectedSido = sidoList?.data?.sidoList?.find(
|
||||
(item) => item.sido === sido,
|
||||
);
|
||||
const gugunSkipYn = selectedSido?.gugunSkipYn ?? "Y";
|
||||
const sggKey: [string, string, "Y" | "N"] | null =
|
||||
sido && sido !== "ALL" && sidoList?.data
|
||||
? ["sgg-all", sido, gugunSkipYn]
|
||||
: null;
|
||||
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(
|
||||
sggKey,
|
||||
getSggAllListFetcher,
|
||||
@@ -299,7 +305,11 @@ const SidoSggFacilityNameSearchForm = ({
|
||||
swtrmtFcltCd,
|
||||
sewerBzmnCd: initialSearchValues?.bsnmCd || '',
|
||||
ctpvNm: initialSidoValue || '',
|
||||
...(doNameList.includes(initialSidoValue) ? { sggNm: initialGugunValue } : {}),
|
||||
...(isGugunRequiredSido(sidoList?.data?.sidoList, {
|
||||
sido: initialSidoValue,
|
||||
})
|
||||
? { sggNm: initialGugunValue }
|
||||
: {}),
|
||||
};
|
||||
|
||||
try {
|
||||
|
||||
@@ -130,7 +130,7 @@ const verificationSubmitResultColumnInfo: ColumnInfo = {
|
||||
export interface VerificationResultDialogQueryContext {
|
||||
sewerBzmnCd: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
statsYr: string;
|
||||
statsCd: string;
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { ValueType } from "realgrid";
|
||||
import type { RealGridReact } from "realgrid-react";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
@@ -35,7 +35,16 @@ import type {
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sgg,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
resolveNoApplicableForRequest,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -61,7 +70,6 @@ import type {
|
||||
ColumnConfig,
|
||||
} from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { ExcretaTreatFactInpColumn } from "@/components/util/column/input/ExcretaTreatFactInpColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import { formatCompactYmdForGrid, toCompactYmdOrNull } from "@/components/util/grid/ymdFormat";
|
||||
@@ -94,10 +102,22 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildNoApplicableForRequest(
|
||||
values: SearchFormValues | null,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
return resolveNoApplicableForRequest(sidoListRef.current, values, checked, isSaveListEmpty);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -131,9 +151,8 @@ function buildExcretaTreatmentFacilitySearchParam(
|
||||
const fcltNm = values.fctName?.trim();
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(fcltNm ? { fcltNm } : {}),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
@@ -315,6 +334,8 @@ const EXCRETA_TREATMENT_FACILITY_NAME_GUIDE_MESSAGE =
|
||||
|
||||
// 하수도 통계 관리 > 07. 분뇨처리시설
|
||||
const ExcretaTreatmentFacilityInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
@@ -470,7 +491,11 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
statusInfo: nextStatusInfo,
|
||||
excretaTreatmentFacilityList,
|
||||
} = response.data;
|
||||
const list = excretaTreatmentFacilityList ?? [];
|
||||
const list = filterBySelectedAdmdstCd(
|
||||
excretaTreatmentFacilityList ?? [],
|
||||
sidoListRef.current,
|
||||
values,
|
||||
);
|
||||
const gridRows = mapExcretaTreatmentFacilityListToGridRows(list, commonInfo.ctpvNm);
|
||||
|
||||
setRowData(gridRows);
|
||||
@@ -587,12 +612,8 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCd || EXCRETA_TREATMENT_FACILITY_STATS_CD,
|
||||
@@ -628,7 +649,7 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
if (!(await confirm("저장 하시겠습니까?"))) return;
|
||||
|
||||
commitGrid();
|
||||
const noApplicable = isNotApplicable;
|
||||
const noApplicable = buildNoApplicableForRequest(lastSearchedValues, isNotApplicable, getCurrentRows().length === 0);
|
||||
const currentData = getCurrentRows();
|
||||
const saveList = noApplicable
|
||||
? []
|
||||
@@ -639,7 +660,7 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
|
||||
.map((row) => buildExcretaTreatmentFacilitySaveItem(row, sggOptions));
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -652,11 +673,7 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
{
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: userInfo.userUnqId,
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
noApplicable,
|
||||
@@ -692,9 +709,9 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const noApplicable = isNotApplicable;
|
||||
const noApplicable = buildNoApplicableForRequest(lastSearchedValues, isNotApplicable, getCurrentRows().length === 0);
|
||||
const currentData = getCurrentRows();
|
||||
if (!noApplicable && currentData.length === 0) {
|
||||
if (!noApplicable && currentData.length === 0 && buildSubmitOkForToolbar(lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -719,7 +736,7 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
}
|
||||
|
||||
commitGrid();
|
||||
const noApplicable = isNotApplicable;
|
||||
const noApplicable = buildNoApplicableForRequest(lastSearchedValues, isNotApplicable, getCurrentRows().length === 0);
|
||||
const currentData = getCurrentRows();
|
||||
const submitList = noApplicable
|
||||
? []
|
||||
@@ -730,19 +747,15 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
|
||||
.map((row) => buildExcretaTreatmentFacilitySaveItem(row, sggOptions));
|
||||
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
const statsCdForSubmit = statsCd || EXCRETA_TREATMENT_FACILITY_STATS_CD;
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForSubmit,
|
||||
};
|
||||
@@ -761,11 +774,7 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
{
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: userInfo.userUnqId,
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
@@ -795,7 +804,7 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForSubmit,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd:
|
||||
@@ -959,7 +968,7 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const searchContextForToolbar = lastSearchedValues;
|
||||
const toolbarSnapshot = computeTabToolbarSnapshot(
|
||||
statusInfo,
|
||||
rowData.length > 0,
|
||||
@@ -979,23 +988,23 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
hasSearched &&
|
||||
toolbarGroupAllowed &&
|
||||
(showSaveInToolbar || showEnterableToolbarButtons);
|
||||
const tabEnterableForGrid =
|
||||
(computeTabEnterable(statusInfo, inputPeriodEnterable) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
const showNotApplicable =
|
||||
searchLoaded &&
|
||||
hasSearched &&
|
||||
rowData.length === 0 &&
|
||||
computeTabEnterable(statusInfo, inputPeriodEnterable);
|
||||
|
||||
const tabEnterableForGrid =
|
||||
(computeTabEnterable(statusInfo, inputPeriodEnterable) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
computeTabEnterable(statusInfo, inputPeriodEnterable) &&
|
||||
submitOk;
|
||||
|
||||
const verificationQueryContext = (() => {
|
||||
const ctx = lastSearchedValues ?? searchValues;
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -1011,6 +1020,7 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
fctName={true}
|
||||
@@ -1030,10 +1040,10 @@ const ExcretaTreatmentFacilityInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void getLastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{statusInfo?.laeSbmsnSttsCd === "2" && (
|
||||
{statusInfo?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
@@ -31,7 +31,15 @@ import type {
|
||||
cancelSubmitRequest,
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -50,7 +58,6 @@ import { VerificationResultDialog } from "@/components/module/VerificationResult
|
||||
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
|
||||
import type { ColumnConfig, ColumnInfo } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { PrivateSewageDesigStatusInpColumn } from "@/components/util/column/input/privateSewageFacility/PrivateSewageDesigStatusInpColumn";
|
||||
import { SepticTankStatusInpColumn } from "@/components/util/column/input/privateSewageFacility/SepticTankStatusInpColumn";
|
||||
import { SewageTreatFactStatusInpColumn } from "@/components/util/column/input/privateSewageFacility/SewageTreatFactStatusInpColumn";
|
||||
@@ -102,9 +109,8 @@ function buildPrivateSewageFacilitySearchParam(
|
||||
): SewageTreatFactStatusRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
}
|
||||
@@ -122,10 +128,14 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -161,8 +171,8 @@ function tabRowDataExists(
|
||||
|
||||
function mapRegionalListToGridRows<
|
||||
T extends { verificationResult?: PrivateSewageFacilityVerificationResult },
|
||||
>(list: T[], ctpvNm: string): GridRowWithVerification[] {
|
||||
return list.map((item) => {
|
||||
>(list: T[], ctpvNm: string, values?: SearchFormValues | null): GridRowWithVerification[] {
|
||||
return filterBySelectedAdmdstCd(list, sidoListRef.current, values).map((item) => {
|
||||
const { verificationResult, ...rest } = item;
|
||||
const row = toGridRows([{ ctpvNm, ...rest }])[0] as GridRowWithVerification;
|
||||
if (verificationResult) row.verificationResult = verificationResult;
|
||||
@@ -314,6 +324,8 @@ function resolvePrivateSewageFacilityTab(tabKey: string) {
|
||||
|
||||
// 하수도 통계 관리 > 08. 개인하수처리시설
|
||||
const PrivateSewageFacilityInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
@@ -340,9 +352,12 @@ const PrivateSewageFacilityInp = () => {
|
||||
const [footerVerificationByTab, setFooterVerificationByTab] = useState<
|
||||
Map<string, VerificationResultLikeMap | null>
|
||||
>(new Map());
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
Map<string, TabToolbarSnapshot>
|
||||
>(new Map());
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [verificationHistoryOpen, setVerificationHistoryOpen] = useState(false);
|
||||
const [verificationResultDialogOpen, setVerificationResultDialogOpen] = useState(false);
|
||||
const [showSubmitDialog, setShowSubmitDialog] = useState(false);
|
||||
@@ -403,6 +418,13 @@ const PrivateSewageFacilityInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const applyRowMap = (
|
||||
@@ -445,6 +467,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
const gridRows = mapRegionalListToGridRows(
|
||||
(sewageTreatFactStatusList ?? []) as SewageTreatFactStatusItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -476,6 +499,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
const gridRows = mapRegionalListToGridRows(
|
||||
(septicTankStatusList ?? []) as SepticTankStatusItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -507,6 +531,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
const gridRows = mapRegionalListToGridRows(
|
||||
(privateSewageDesigStatusList ?? []) as PrivateSewageDesigStatusItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -539,6 +564,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setActiveTab(firstTabKey);
|
||||
activeTabRef.current = firstTabKey;
|
||||
setLastSearchedValues(null);
|
||||
@@ -582,6 +608,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
activeTabRef.current = firstTabKey;
|
||||
setActiveTab(firstTabKey);
|
||||
}
|
||||
@@ -691,12 +718,8 @@ const PrivateSewageFacilityInp = () => {
|
||||
}
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -779,11 +802,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
const submitInfoBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
|
||||
@@ -795,12 +814,8 @@ const PrivateSewageFacilityInp = () => {
|
||||
};
|
||||
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
};
|
||||
@@ -868,7 +883,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd: activeTabStatus?.laeSbmsnSttsCd === "4" ? "4" : "2",
|
||||
@@ -956,11 +971,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
const baseRequest = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -1062,9 +1073,8 @@ const PrivateSewageFacilityInp = () => {
|
||||
const statsCd = tabStatsCdMap.get(activeTab);
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -1095,19 +1105,20 @@ const PrivateSewageFacilityInp = () => {
|
||||
return map;
|
||||
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo, columnGuidesByTab]);
|
||||
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
hasSearched,
|
||||
lastSearchedValues,
|
||||
searchContextForToolbar,
|
||||
inputPeriodEnterable,
|
||||
isAdminInfo,
|
||||
);
|
||||
const { showSaveInToolbar, showEnterableToolbarButtons, showActionToolbarCard } =
|
||||
activeTabToolbar;
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
|
||||
const verificationCellStyle = ({
|
||||
fieldName,
|
||||
@@ -1166,6 +1177,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
onSubmit={handleSearch}
|
||||
@@ -1186,10 +1198,10 @@ const PrivateSewageFacilityInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void lastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
@@ -1225,7 +1237,7 @@ const PrivateSewageFacilityInp = () => {
|
||||
tabStatusInfoMap.get(tabKey) ?? null,
|
||||
inputPeriodEnterable,
|
||||
) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const tabStatusInfo = tabStatusInfoMap.get(tabKey) ?? null;
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import { useConfirm } from '@frontend-opensource/use-react-hooks';
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from '@/shared/lib';
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from '@/shared/lib';
|
||||
import { STATISTICS_INPUT_URL_PATH } from '@/shared/lib/stats-cd-input-navigation';
|
||||
import { useStatisticsInputPendingNavigation } from '@/shared/lib/use-statistics-input-pending-navigation';
|
||||
import { statisticsInputSewSupplyRateApi } from '@/entities/statistics/api/input/statistics-input-sew-supply-rate-service';
|
||||
@@ -23,7 +23,9 @@ import {
|
||||
type SewerageSupplyRateVerificationResult,
|
||||
} from '@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface';
|
||||
import type { StatisticsInputSubmitInfoFormData } from '@/entities/statistics/model/statistics-input-submit-info-schema';
|
||||
import type { cancelSubmitRequest, ImrStatusResponse, SewerageStatusInfo } from '@/entities/statistics/model/statistics-interface';
|
||||
import type { cancelSubmitRequest, ImrStatusResponse, SewerageStatusInfo, Sido } from '@/entities/statistics/model/statistics-interface';
|
||||
import { filterBySelectedAdmdstCd, isGugunOkForToolbar, isSubmitOkForToolbar, resolveNoApplicableForRequest, toInputSearchRegion } from '@/entities/statistics';
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from '@common/components';
|
||||
|
||||
import { getUserInfo } from '../../../../../../packages/common/components/src/api';
|
||||
@@ -45,7 +47,6 @@ import { VerificationResultDialog } from '@/components/module/VerificationResult
|
||||
import { VerificationResultHistoryDialog } from '@/components/module/VerificationResultHistoryDialog';
|
||||
import type { CellStyleCallbackParams, ColumnInfo, ColumnInfoList } from '@/components/type/DataGrid.type';
|
||||
import type { SearchFormValues } from '@/components/type/SearchForm.type';
|
||||
import { doList } from '@/components/util/column/input/DoList';
|
||||
import { PublicSewageFactInpColumnList } from '@/components/util/column/input/PublicSewageFactInpColumn/PublicSewageFactInpColumn';
|
||||
import { fetchColumnGuidesRecord } from '@/components/util/grid/columnGuides';
|
||||
import { toGridRows } from '@/components/util/grid/gridFunction';
|
||||
@@ -66,10 +67,22 @@ type TabToolbarSnapshot = {
|
||||
showActionToolbarCard: boolean;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || '')
|
||||
? Boolean(values?.gugun && values.gugun !== 'ALL')
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildNoApplicableForRequest(
|
||||
values: SearchFormValues | null,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
return resolveNoApplicableForRequest(sidoListRef.current, values, checked, isSaveListEmpty);
|
||||
}
|
||||
|
||||
const computeTabEnterable = (
|
||||
@@ -181,6 +194,8 @@ function validatePrxyCtrtCnInRows(rows: Record<string, string | number>[]): stri
|
||||
|
||||
// 하수도 통계 관리 > 06. 공공하수처리시설
|
||||
const PublicSewageFacilityInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
@@ -209,6 +224,9 @@ const PublicSewageFacilityInp = () => {
|
||||
/** 탭키별 `engColNm -> columnGuide` 캐시 */
|
||||
const [columnGuidesByTab, setColumnGuidesByTab] = useState<Record<string, Record<string, string>>>({});
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<Map<string, TabToolbarSnapshot>>(() => new Map());
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [inputPeriodEnterable, setInputPeriodEnterable] = useState(true);
|
||||
const [periodCheckList, setPeriodCheckList] = useState<CheckInputPeriodItem[]>([]);
|
||||
const [showDailog, setShowDailog] = useState<boolean>(false);
|
||||
@@ -247,10 +265,10 @@ const PublicSewageFacilityInp = () => {
|
||||
alert('먼저 조회를 진행해주세요.');
|
||||
return;
|
||||
}
|
||||
const treatAsNoApplicable = getNoApplicableForRequest() || isNotApplicable;
|
||||
const treatAsNoApplicable = getNoApplicableForRequest();
|
||||
const currentData =
|
||||
st60001GridGetRowsRef.current?.() ?? rowDataMap.get('ST00060001') ?? [];
|
||||
if (!treatAsNoApplicable && (!currentData || currentData.length === 0)) {
|
||||
if (!treatAsNoApplicable && (!currentData || currentData.length === 0) && buildSubmitOkForToolbar(searchContextByTab.get(activeTab) ?? lastSearchedValues)) {
|
||||
alert('해당사항 없음을 체크해주세요.');
|
||||
return;
|
||||
}
|
||||
@@ -298,13 +316,14 @@ const PublicSewageFacilityInp = () => {
|
||||
};
|
||||
|
||||
const getNoApplicableForRequest = (): boolean => {
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const enterable = computeTabEnterable(activeTabStatus, inputPeriodEnterable);
|
||||
const showEnterableToolbarButtons = enterable && gugunOk;
|
||||
const noApplicableVisible = showEnterableToolbarButtons && showIsNotApplicable;
|
||||
return noApplicableVisible ? Boolean(isNotApplicable) : false;
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const currentData =
|
||||
st60001GridGetRowsRef.current?.() ?? rowDataMap.get('ST00060001') ?? [];
|
||||
return buildNoApplicableForRequest(
|
||||
searchContextForToolbar,
|
||||
Boolean(isNotApplicable),
|
||||
buildFacilitySaveList(currentData).length === 0,
|
||||
);
|
||||
};
|
||||
|
||||
const isCheckedRow = (row: Record<string, string | number>): boolean => {
|
||||
@@ -349,7 +368,7 @@ const PublicSewageFacilityInp = () => {
|
||||
return;
|
||||
}
|
||||
const noApplicable = getNoApplicableForRequest();
|
||||
const treatAsNoApplicable = noApplicable || isNotApplicable;
|
||||
const treatAsNoApplicable = noApplicable;
|
||||
const currentData =
|
||||
st60001GridGetRowsRef.current?.() ?? rowDataMap.get('ST00060001') ?? [];
|
||||
|
||||
@@ -360,7 +379,7 @@ const PublicSewageFacilityInp = () => {
|
||||
}
|
||||
|
||||
const submitList = treatAsNoApplicable ? [] : buildFacilitySaveList(currentData);
|
||||
if (!treatAsNoApplicable && submitList.length === 0) {
|
||||
if (!treatAsNoApplicable && submitList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(activeTab) ?? lastSearchedValues)) {
|
||||
alert('해당사항 없음을 체크해주세요.');
|
||||
return;
|
||||
}
|
||||
@@ -373,8 +392,7 @@ const PublicSewageFacilityInp = () => {
|
||||
const requestData = {
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
ctpvNm: lastSearchedValues.sido ?? '',
|
||||
sggNm: lastSearchedValues.gugun === 'ALL' ? '' : lastSearchedValues.gugun ?? '',
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: userInfo.userUnqId,
|
||||
noApplicable,
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
@@ -407,7 +425,7 @@ const PublicSewageFacilityInp = () => {
|
||||
setGlobalProgressLabel('시계열 검증 진행 중...');
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? '',
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? '',
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? '',
|
||||
lae_sbmsn_stts_cd: activeTabStatus?.laeSbmsnSttsCd === '4' ? '4' : '2',
|
||||
@@ -435,9 +453,8 @@ const PublicSewageFacilityInp = () => {
|
||||
);
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
{
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? '',
|
||||
sggNm: lastSearchedValues.gugun === 'ALL' ? '' : (lastSearchedValues.gugun ?? ''),
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
statsCd: statsCdForTab,
|
||||
},
|
||||
@@ -452,9 +469,8 @@ const PublicSewageFacilityInp = () => {
|
||||
);
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
{
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? '',
|
||||
sggNm: lastSearchedValues.gugun === 'ALL' ? '' : (lastSearchedValues.gugun ?? ''),
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
statsCd: statsCdForTab,
|
||||
},
|
||||
@@ -476,9 +492,8 @@ const PublicSewageFacilityInp = () => {
|
||||
);
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
{
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? '',
|
||||
sggNm: lastSearchedValues.gugun === 'ALL' ? '' : (lastSearchedValues.gugun ?? ''),
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
statsCd: statsCdForTab,
|
||||
},
|
||||
@@ -508,7 +523,7 @@ const PublicSewageFacilityInp = () => {
|
||||
|
||||
if (activeTab === 'ST00060002') {
|
||||
const statusCodeResponse = await statisticsApi.CheckStatusCode({
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
sewerBzmnCd: toInputSearchRegion(sidoListRef.current, lastSearchedValues).sewerBzmnCd,
|
||||
statsCd: 'ST00060001',
|
||||
statsYr: lastSearchedValues.year ?? ''
|
||||
});
|
||||
@@ -585,7 +600,7 @@ const PublicSewageFacilityInp = () => {
|
||||
|
||||
mainFacilityMappingSaveDraftRef.current = {
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
sewerBzmnCd: toInputSearchRegion(sidoListRef.current, lastSearchedValues).sewerBzmnCd,
|
||||
admdstCd: String(selectedMain.admdstCd ?? ''),
|
||||
admdstNm: String(selectedMain.admdstNm ?? ''),
|
||||
mainFcltSn: String(selectedMain.fcltSn ?? ''),
|
||||
@@ -616,7 +631,7 @@ const PublicSewageFacilityInp = () => {
|
||||
|
||||
if (activeTab === 'ST00060001') {
|
||||
const noApplicable = getNoApplicableForRequest();
|
||||
const treatAsNoApplicable = noApplicable || isNotApplicable;
|
||||
const treatAsNoApplicable = noApplicable;
|
||||
const currentData =
|
||||
st60001GridGetRowsRef.current?.() ?? rowDataMap.get('ST00060001') ?? [];
|
||||
const prxyCtrtCnError = validatePrxyCtrtCnInRows(currentData);
|
||||
@@ -625,7 +640,7 @@ const PublicSewageFacilityInp = () => {
|
||||
return;
|
||||
}
|
||||
const saveList = treatAsNoApplicable ? [] : buildFacilitySaveList(currentData);
|
||||
if (!treatAsNoApplicable && saveList.length === 0) {
|
||||
if (!treatAsNoApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(activeTab) ?? lastSearchedValues)) {
|
||||
alert('해당사항 없음을 체크해주세요.');
|
||||
return;
|
||||
}
|
||||
@@ -636,8 +651,7 @@ const PublicSewageFacilityInp = () => {
|
||||
const param: PublicSewageFacilitySaveRequest = {
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
ctpvNm: lastSearchedValues.sido ?? '',
|
||||
sggNm: lastSearchedValues.gugun === 'ALL' ? '' : lastSearchedValues.gugun ?? '',
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: userInfo.userUnqId,
|
||||
...(isAdminInfo ? { superAdmin: 'superAdmin' } : {}),
|
||||
noApplicable,
|
||||
@@ -724,12 +738,18 @@ const PublicSewageFacilityInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const buildPublicSewageFacilityParams = (values: SearchFormValues): PublicSewageFacilityRequestParams => ({
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
fcltNm: values.fctName,
|
||||
statsYr: values.year,
|
||||
});
|
||||
@@ -759,7 +779,11 @@ const PublicSewageFacilityInp = () => {
|
||||
const statusInfo = response.data.statusInfo ?? null;
|
||||
const statsCd = response.data.commonInfo.statsCd || tabKey;
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const list = response.data.publicSewageFacilityList ?? [];
|
||||
const list = filterBySelectedAdmdstCd(
|
||||
response.data.publicSewageFacilityList ?? [],
|
||||
sidoListRef.current,
|
||||
searchContext,
|
||||
);
|
||||
const convertedData = list.map((item) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...item,
|
||||
@@ -872,8 +896,7 @@ const PublicSewageFacilityInp = () => {
|
||||
const request = {
|
||||
statsYr: lastSearchedValues.year ?? '',
|
||||
ctpvNm: lastSearchedValues.sido ?? '',
|
||||
sggNm: lastSearchedValues.gugun === 'ALL' ? '' : lastSearchedValues.gugun ?? '',
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: userInfo.userUnqId,
|
||||
};
|
||||
|
||||
@@ -1005,6 +1028,7 @@ const PublicSewageFacilityInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
activeTabRef.current = firstTabKey;
|
||||
setActiveTab(firstTabKey);
|
||||
}
|
||||
@@ -1069,6 +1093,7 @@ const PublicSewageFacilityInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
|
||||
setInputPeriodEnterable(true);
|
||||
periodEnterableRef.current = true;
|
||||
@@ -1095,9 +1120,8 @@ const PublicSewageFacilityInp = () => {
|
||||
const userInfo = await getUserInfo();
|
||||
const statsCdForCancel = tabStatsCdMap.get(activeTab) ?? activeTab;
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues?.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues?.sido ?? '',
|
||||
sggNm: lastSearchedValues?.gugun === 'ALL' ? '' : lastSearchedValues?.gugun ?? '',
|
||||
statsYr: lastSearchedValues?.year ?? '',
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForCancel,
|
||||
@@ -1155,7 +1179,9 @@ const PublicSewageFacilityInp = () => {
|
||||
const param: PublicSewageMappingTargetsRequestParams = {
|
||||
sewerBzmnCd: searchParamRef.current.sewerBzmnCd ?? '',
|
||||
ctpvNm: searchParamRef.current.ctpvNm ?? '',
|
||||
sggNm: searchParamRef.current.sggNm ?? '',
|
||||
...(searchParamRef.current.sggNm != null
|
||||
? { sggNm: searchParamRef.current.sggNm }
|
||||
: {}),
|
||||
statsYr: searchParamRef.current.statsYr ?? '',
|
||||
fcltSn,
|
||||
};
|
||||
@@ -1195,8 +1221,9 @@ const PublicSewageFacilityInp = () => {
|
||||
return String(row.fcltSn ?? '') === selectedMainFacilitySn ? 'rg-cell-selected-row' : undefined;
|
||||
};
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const gugunOkOrNotDoList = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabToolbar = computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
@@ -1241,9 +1268,8 @@ const PublicSewageFacilityInp = () => {
|
||||
const statsCd = tabStatsCdMap.get(activeTab) ?? activeTab;
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === 'ALL' ? '' : (ctx.gugun ?? ''),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -1264,6 +1290,7 @@ const PublicSewageFacilityInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
fctName={true}
|
||||
@@ -1284,12 +1311,12 @@ const PublicSewageFacilityInp = () => {
|
||||
)}
|
||||
{showEnterableToolbarButtons && !isMainFacilityTab && (
|
||||
<>
|
||||
{showIsNotApplicable && <NotApplicableCheckButton isCheck={isNotApplicable} setIsCheck={setIsNotApplicable} />}
|
||||
{showIsNotApplicable && submitOk && <NotApplicableCheckButton isCheck={isNotApplicable} setIsCheck={setIsNotApplicable} />}
|
||||
<UpdateOperateDataButton updateOperateDataButtonFunc={updateOperateDataButtonFunc} />
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{!isMainFacilityTab && activeTabStatus?.laeSbmsnSttsCd === '2' && (
|
||||
{!isMainFacilityTab && activeTabStatus?.laeSbmsnSttsCd === '2' && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
|
||||
@@ -12,7 +12,7 @@ import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { ValueType } from "realgrid";
|
||||
import type { RealGridReact } from "realgrid-react";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
@@ -35,7 +35,16 @@ import type {
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sgg,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
resolveNoApplicableForRequest,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -61,7 +70,6 @@ import type {
|
||||
ColumnConfig,
|
||||
} from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { PumpingStationInpColumn } from "@/components/util/column/input/PumpingStationInpColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import { formatCompactYmdForGrid, toCompactYmdOrNull } from "@/components/util/grid/ymdFormat";
|
||||
@@ -94,10 +102,22 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildNoApplicableForRequest(
|
||||
values: SearchFormValues | null,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
return resolveNoApplicableForRequest(sidoListRef.current, values, checked, isSaveListEmpty);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -131,9 +151,8 @@ function buildPumpingStationSearchParam(
|
||||
const fcltNm = values.fctName?.trim();
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(fcltNm ? { fcltNm } : {}),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
@@ -309,6 +328,8 @@ const PUMPING_STATION_FACILITY_NAME_GUIDE_MESSAGE =
|
||||
|
||||
// 하수도 통계 관리 > 05. 펌프장 (SewageReservoirPumpInp 단일 탭 패턴)
|
||||
const PumpingStationInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
@@ -460,7 +481,11 @@ const PumpingStationInp = () => {
|
||||
|
||||
const { commonInfo, statusInfo: nextStatusInfo, pumpingStationList } =
|
||||
response.data;
|
||||
const list = pumpingStationList ?? [];
|
||||
const list = filterBySelectedAdmdstCd(
|
||||
pumpingStationList ?? [],
|
||||
sidoListRef.current,
|
||||
values,
|
||||
);
|
||||
const gridRows = mapPumpingStationListToGridRows(list, commonInfo.ctpvNm);
|
||||
|
||||
setPumpingStationDeleteList([]);
|
||||
@@ -578,12 +603,8 @@ const PumpingStationInp = () => {
|
||||
|
||||
const userInfo = await getUserInfo();
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCd || PUMPING_STATION_STATS_CD,
|
||||
@@ -618,9 +639,9 @@ const PumpingStationInp = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const noApplicable = isNotApplicable;
|
||||
const noApplicable = buildNoApplicableForRequest(lastSearchedValues, isNotApplicable, getCurrentRows().length === 0);
|
||||
const currentData = getCurrentRows();
|
||||
if (!noApplicable && currentData.length === 0) {
|
||||
if (!noApplicable && currentData.length === 0 && buildSubmitOkForToolbar(lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -647,7 +668,7 @@ const PumpingStationInp = () => {
|
||||
if (!(await confirm("저장 하시겠습니까?"))) return;
|
||||
|
||||
commitGrid();
|
||||
const noApplicable = isNotApplicable;
|
||||
const noApplicable = buildNoApplicableForRequest(lastSearchedValues, isNotApplicable, getCurrentRows().length === 0);
|
||||
const currentData = getCurrentRows();
|
||||
const saveList = noApplicable
|
||||
? []
|
||||
@@ -658,7 +679,7 @@ const PumpingStationInp = () => {
|
||||
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
|
||||
.map((row) => buildPumpingStationSaveItem(row, sggOptions));
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -669,11 +690,7 @@ const PumpingStationInp = () => {
|
||||
const response = await statisticsInputPumpingStationApi.savePumpingStationList({
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: userInfo.userUnqId,
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
noApplicable,
|
||||
@@ -707,7 +724,7 @@ const PumpingStationInp = () => {
|
||||
}
|
||||
|
||||
commitGrid();
|
||||
const noApplicable = isNotApplicable;
|
||||
const noApplicable = buildNoApplicableForRequest(lastSearchedValues, isNotApplicable, getCurrentRows().length === 0);
|
||||
const currentData = getCurrentRows();
|
||||
const submitList = noApplicable
|
||||
? []
|
||||
@@ -716,19 +733,15 @@ const PumpingStationInp = () => {
|
||||
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
|
||||
.map((row) => buildPumpingStationSaveItem(row, sggOptions));
|
||||
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
|
||||
const statsCdForSubmit = statsCd || PUMPING_STATION_STATS_CD;
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForSubmit,
|
||||
};
|
||||
@@ -745,11 +758,7 @@ const PumpingStationInp = () => {
|
||||
const response = await statisticsInputPumpingStationApi.submitPumpingStationList({
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: userInfo.userUnqId,
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
@@ -778,7 +787,7 @@ const PumpingStationInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForSubmit,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd:
|
||||
@@ -942,7 +951,7 @@ const PumpingStationInp = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const searchContextForToolbar = lastSearchedValues;
|
||||
const toolbarSnapshot = computeTabToolbarSnapshot(
|
||||
statusInfo,
|
||||
rowData.length > 0,
|
||||
@@ -962,23 +971,23 @@ const PumpingStationInp = () => {
|
||||
hasSearched &&
|
||||
toolbarGroupAllowed &&
|
||||
(showSaveInToolbar || showEnterableToolbarButtons);
|
||||
const tabEnterableForGrid =
|
||||
(computeTabEnterable(statusInfo, inputPeriodEnterable) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
const showNotApplicable =
|
||||
searchLoaded &&
|
||||
hasSearched &&
|
||||
rowData.length === 0 &&
|
||||
computeTabEnterable(statusInfo, inputPeriodEnterable);
|
||||
|
||||
const tabEnterableForGrid =
|
||||
(computeTabEnterable(statusInfo, inputPeriodEnterable) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
computeTabEnterable(statusInfo, inputPeriodEnterable) &&
|
||||
submitOk;
|
||||
|
||||
const verificationQueryContext = (() => {
|
||||
const ctx = lastSearchedValues ?? searchValues;
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -994,6 +1003,7 @@ const PumpingStationInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
fctName={true}
|
||||
@@ -1013,10 +1023,10 @@ const PumpingStationInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void getLastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{statusInfo?.laeSbmsnSttsCd === "2" && (
|
||||
{statusInfo?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { ValueType } from "realgrid";
|
||||
import type { RealGridReact } from "realgrid-react";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
@@ -34,7 +34,16 @@ import type {
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sgg,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
resolveNoApplicableForRequest,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -63,7 +72,6 @@ import type {
|
||||
ColumnInfo,
|
||||
} from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { ExcretaRelatedIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/ExcretaRelatedIndustryInpColumn";
|
||||
import { PrivateSewageTreatRelatedIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/PrivateSewageTreatRelatedIndustryInpColumn";
|
||||
import { PublicInstitutionExcretaIndustryInpColumn } from "@/components/util/column/input/sewageExcretaRelated/PublicInstitutionExcretaIndustryInpColumn";
|
||||
@@ -158,10 +166,22 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildNoApplicableForRequest(
|
||||
values: SearchFormValues | null,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
return resolveNoApplicableForRequest(sidoListRef.current, values, checked, isSaveListEmpty);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -543,9 +563,8 @@ function buildSewageExcretaRelatedSearchParam(
|
||||
): SewageExcretaRelatedRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
}
|
||||
@@ -553,8 +572,9 @@ function buildSewageExcretaRelatedSearchParam(
|
||||
function mapListToGridRows<T extends { verificationResult?: SewageExcretaRelatedVerificationResult }>(
|
||||
list: T[] | undefined,
|
||||
ctpvNm: string,
|
||||
values?: SearchFormValues | null,
|
||||
): GridRowWithVerification[] {
|
||||
return (list ?? []).map((item) => {
|
||||
return filterBySelectedAdmdstCd(list, sidoListRef.current, values).map((item) => {
|
||||
const row = toGridRows([{ ctpvNm, ...item }])[0] as GridRowWithVerification;
|
||||
if (item.verificationResult) {
|
||||
row.verificationResult = item.verificationResult;
|
||||
@@ -590,6 +610,8 @@ async function waitForImrJobCompleted(
|
||||
|
||||
// 하수도 통계 관리 > 12. 하수 및 분뇨관련산업
|
||||
const SewageExcretaRelatedInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const isAdminInfo = useAdminStore((state) => state.isAdminInfo);
|
||||
@@ -606,7 +628,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
const [tabStatusInfoMap, setTabStatusInfoMap] = useState<
|
||||
Map<string, SewerageStatusInfo | null>
|
||||
>(new Map());
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
Map<string, TabToolbarSnapshot>
|
||||
>(new Map());
|
||||
const [columnGuidesByTab, setColumnGuidesByTab] = useState<
|
||||
@@ -616,6 +638,9 @@ const SewageExcretaRelatedInp = () => {
|
||||
const [lastSearchedValues, setLastSearchedValues] = useState<SearchFormValues | null>(
|
||||
null,
|
||||
);
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [hasSearched, setHasSearched] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [inputPeriodEnterable, setInputPeriodEnterable] = useState(true);
|
||||
@@ -739,6 +764,13 @@ const SewageExcretaRelatedInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const markTabLoaded = (tabKey: string) => {
|
||||
@@ -854,6 +886,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
const gridRows = mapListToGridRows(
|
||||
publicInstitutionSewerIndustryList,
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
syncPublicInstitutionArticleTracking(
|
||||
tabKey,
|
||||
@@ -900,6 +933,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
const gridRows = mapListToGridRows(
|
||||
publicInstitutionExcretaIndustryList,
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
syncPublicInstitutionArticleTracking(
|
||||
tabKey,
|
||||
@@ -942,7 +976,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
return false;
|
||||
}
|
||||
const { commonInfo, statusInfo, excretaRelatedIndustryList } = response.data;
|
||||
const gridRows = mapListToGridRows(excretaRelatedIndustryList, commonInfo.ctpvNm);
|
||||
const gridRows = mapListToGridRows(excretaRelatedIndustryList, commonInfo.ctpvNm, searchContext);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
m.set(ExcretaRelatedIndustryInpColumn.tabKey, gridRows);
|
||||
});
|
||||
@@ -979,6 +1013,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
const gridRows = mapListToGridRows(
|
||||
privateSewageTreatRelatedIndustryList,
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
m.set(PrivateSewageTreatRelatedIndustryInpColumn.tabKey, gridRows);
|
||||
@@ -1010,6 +1045,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
setRowDataMap(new Map());
|
||||
setTabStatusInfoMap(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setActiveTab(firstTabKey);
|
||||
activeTabRef.current = firstTabKey;
|
||||
setLastSearchedValues(null);
|
||||
@@ -1075,6 +1111,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setIsNotApplicableByTab(new Map());
|
||||
setDeleteListByTab(new Map());
|
||||
clearArticleOgnzSnTracking(
|
||||
@@ -1139,9 +1176,8 @@ const SewageExcretaRelatedInp = () => {
|
||||
const statsCdForTab = tabStatsCdMap.get(tabKey) ?? tabKey;
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: ctx.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido ?? "",
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -1232,10 +1268,10 @@ const SewageExcretaRelatedInp = () => {
|
||||
}
|
||||
|
||||
commitActiveGrid();
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
if (NOT_APPLICABLE_TAB_KEYS.has(tabKey)) {
|
||||
if (!noApplicable && currentData.length === 0) {
|
||||
if (!noApplicable && currentData.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1269,18 +1305,14 @@ const SewageExcretaRelatedInp = () => {
|
||||
|
||||
const isDistrictRowTab = DISTRICT_ROW_TAB_KEYS.has(tabKey);
|
||||
const isPublicInstitutionTab = ARTICLE_EDIT_TAB_KEYS.has(tabKey);
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
const mapRows = rowDataMap.get(tabKey) ?? [];
|
||||
|
||||
const searchContextBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
};
|
||||
|
||||
let submitList:
|
||||
@@ -1341,7 +1373,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
)
|
||||
.map((row) => buildPublicInstitutionIndustrySaveItem(row, list));
|
||||
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1448,7 +1480,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd:
|
||||
@@ -1527,18 +1559,14 @@ const SewageExcretaRelatedInp = () => {
|
||||
|
||||
const isDistrictRowTab = DISTRICT_ROW_TAB_KEYS.has(tabKey);
|
||||
const isPublicInstitutionTab = ARTICLE_EDIT_TAB_KEYS.has(tabKey);
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
const mapRows = rowDataMap.get(tabKey) ?? [];
|
||||
|
||||
const baseSaveRequest = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
...(isPublicInstitutionTab && noApplicable
|
||||
? { noApplicable: true as const }
|
||||
: {}),
|
||||
@@ -1621,7 +1649,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
)
|
||||
.map((row) => buildPublicInstitutionIndustrySaveItem(row, list));
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1885,11 +1913,10 @@ const SewageExcretaRelatedInp = () => {
|
||||
[publicInstitutionArticleCellStyleCallback],
|
||||
);
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabHasRowData = tabRowDataExists(rowDataMap, activeTab);
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
activeTabHasRowData,
|
||||
@@ -1907,10 +1934,13 @@ const SewageExcretaRelatedInp = () => {
|
||||
(activeTabToolbar.showActionToolbarCard || (hasSearched && loadedTabKeys.has(activeTab)));
|
||||
const showArticleEditButtons =
|
||||
ARTICLE_EDIT_TAB_KEYS.has(activeTab) && showEnterableToolbarButtons;
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
const showNotApplicableForActiveTab =
|
||||
NOT_APPLICABLE_TAB_KEYS.has(activeTab) &&
|
||||
loadedTabKeys.has(activeTab) &&
|
||||
shouldShowNotApplicable(activeTab, activeTabHasRowData, activeTabStatus);
|
||||
shouldShowNotApplicable(activeTab, activeTabHasRowData, activeTabStatus) &&
|
||||
submitOk;
|
||||
const showSecondaryToolbarCard =
|
||||
hasSearched &&
|
||||
toolbarGroupAllowed &&
|
||||
@@ -1928,16 +1958,14 @@ const SewageExcretaRelatedInp = () => {
|
||||
},
|
||||
[isNotApplicableByTab, setIsNotApplicableForTab],
|
||||
);
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
|
||||
const verificationQueryContext = (() => {
|
||||
const ctx = lastSearchedValues ?? searchValues;
|
||||
const statsCd = tabStatsCdMap.get(activeTab) ?? activeTab;
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -1958,6 +1986,7 @@ const SewageExcretaRelatedInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
onSubmit={handleSearch}
|
||||
@@ -1978,10 +2007,10 @@ const SewageExcretaRelatedInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void lastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { ValueType } from "realgrid";
|
||||
import type { RealGridReact } from "realgrid-react";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
@@ -37,7 +37,15 @@ import {
|
||||
} from "@/entities/statistics/model/input/statistics-input-sewage-excreta-slurge-interface";
|
||||
import { isInputPeriodCurrent } from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
|
||||
import type { StatisticsInputSubmitInfoFormData } from "@/entities/statistics/model/statistics-input-submit-info-schema";
|
||||
import type { ApiResponse, cancelSubmitRequest, ImrStatusResponse, SewerageStatusInfo, Sgg } from "@/entities/statistics/model/statistics-interface";
|
||||
import type { ApiResponse, cancelSubmitRequest, ImrStatusResponse, SewerageStatusInfo, Sgg, Sido } from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
resolveNoApplicableForRequest,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -67,7 +75,6 @@ import type {
|
||||
ColumnInfo,
|
||||
} from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import {
|
||||
DIGESTOR_OPERATING_STATUS_EN_YN_FIELD,
|
||||
DigestorOperatingStatusInpColumn,
|
||||
@@ -163,9 +170,8 @@ function buildSewageExcretaSlurgeSearchParam(
|
||||
): SewageExcretaSlurgeRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
fcltNm: values.fctName?.trim() || undefined,
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
@@ -174,8 +180,9 @@ function buildSewageExcretaSlurgeSearchParam(
|
||||
function mapListToGridRows<T extends { verificationResult?: SewageExcretaSlurgeVerificationResult }>(
|
||||
list: T[] | undefined,
|
||||
ctpvNm: string,
|
||||
values?: SearchFormValues | null,
|
||||
): GridRowWithVerification[] {
|
||||
return (list ?? []).map((item) => {
|
||||
return filterBySelectedAdmdstCd(list, sidoListRef.current, values).map((item) => {
|
||||
const row = toGridRows([{ ctpvNm, ...item }])[0] as GridRowWithVerification;
|
||||
if (item.verificationResult) {
|
||||
row.verificationResult = item.verificationResult;
|
||||
@@ -345,10 +352,22 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildNoApplicableForRequest(
|
||||
values: SearchFormValues | null,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
return resolveNoApplicableForRequest(sidoListRef.current, values, checked, isSaveListEmpty);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -491,7 +510,7 @@ function buildSlurgeProcessingFacStatusSaveItem(
|
||||
itslfTs1AltdQnt: toGridNumber(row.itslfTs1AltdQnt),
|
||||
itslfTs1DryQnt: toGridNumber(row.itslfTs1DryQnt),
|
||||
itslfTs1FuelQnt: toGridNumber(row.itslfTs1FuelQnt),
|
||||
itslfTs2CmpstgQnt: toGridNumber(row.itslfTs2CmpstgQnt),
|
||||
itslfTs1CmpstgQnt: toGridNumber(row.itslfTs1CmpstgQnt),
|
||||
cmpsPrcsFcltBzentyNm: nullableTrimmedString(row.cmpsPrcsFcltBzentyNm),
|
||||
incnrPrcsLfvlm: toGridNumber(row.incnrPrcsLfvlm),
|
||||
incnrPrcsPrdctRmtrlQnt: toGridNumber(row.incnrPrcsPrdctRmtrlQnt),
|
||||
@@ -644,6 +663,8 @@ async function waitForImrJobCompleted(
|
||||
|
||||
// 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리
|
||||
const SewageExcretaSlurgeInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
const { confirm } = useConfirm();
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
@@ -678,6 +699,9 @@ const SewageExcretaSlurgeInp = () => {
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
Map<string, TabToolbarSnapshot>
|
||||
>(new Map());
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [sggOptions, setSggOptions] = useState<Sgg[]>([]);
|
||||
const [loadedTabKeys, setLoadedTabKeys] = useState<Set<string>>(() => new Set());
|
||||
const [verificationHistoryOpen, setVerificationHistoryOpen] = useState(false);
|
||||
@@ -790,6 +814,13 @@ const SewageExcretaSlurgeInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const getTabGridRows = (tabKey: string): Record<string, string | number>[] =>
|
||||
@@ -923,7 +954,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
return false;
|
||||
}
|
||||
const { commonInfo, statusInfo, slurgeProcessingFacStatusList } = response.data;
|
||||
const gridRows = mapListToGridRows(slurgeProcessingFacStatusList, commonInfo.ctpvNm);
|
||||
const gridRows = mapListToGridRows(slurgeProcessingFacStatusList, commonInfo.ctpvNm, searchContext);
|
||||
syncSlurgeFacStatusArticleFcltSnTracking(gridRows, fromPreYear);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
m.set(SlurgeProcessingFacStatusInpColumn.tabKey, gridRows);
|
||||
@@ -958,7 +989,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
return false;
|
||||
}
|
||||
const { commonInfo, statusInfo, digestorOperatingStatusList } = response.data;
|
||||
const gridRows = mapListToGridRows(digestorOperatingStatusList, commonInfo.ctpvNm);
|
||||
const gridRows = mapListToGridRows(digestorOperatingStatusList, commonInfo.ctpvNm, searchContext);
|
||||
if (!fromPreYear) {
|
||||
publicSewageFacilitiesAvailableRef.current = gridRows.length > 0;
|
||||
if (gridRows.length === 0 && overrides?.alertIfDigestorEmpty) {
|
||||
@@ -1002,6 +1033,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
const gridRows = mapListToGridRows(
|
||||
sewageSlurgeProcessingFacStatusList,
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
m.set(SewageSlurgeProcessingFacStatusInpColumn.tabKey, gridRows);
|
||||
@@ -1039,6 +1071,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
const gridRows = mapListToGridRows(
|
||||
excretaSlurgeProcessingStatusList,
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
if (!fromPreYear) {
|
||||
excretaTreatmentFacilitiesAvailableRef.current = gridRows.length > 0;
|
||||
@@ -1080,6 +1113,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setActiveTab(firstTabKey);
|
||||
activeTabRef.current = firstTabKey;
|
||||
setLastSearchedValues(null);
|
||||
@@ -1139,6 +1173,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
loadedTabKeysRef.current.clear();
|
||||
setLoadedTabKeys(new Set());
|
||||
setDeleteListByTab(new Map());
|
||||
@@ -1247,9 +1282,9 @@ const SewageExcretaSlurgeInp = () => {
|
||||
}
|
||||
|
||||
commitActiveGrid();
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
if (!noApplicable && currentData.length === 0) {
|
||||
if (!noApplicable && currentData.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1277,7 +1312,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
|
||||
commitActiveGrid();
|
||||
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
const mapRows = rowDataMap.get(tabKey) ?? [];
|
||||
|
||||
@@ -1335,6 +1370,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
|
||||
if (
|
||||
!noApplicable &&
|
||||
buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues) &&
|
||||
((isSlurgeFacTab && slurgeSubmitList.length === 0) ||
|
||||
(isDigestorTab && digestorSubmitList.length === 0) ||
|
||||
(isSewageSlurgeFacTab && sewageSlurgeFacSubmitList.length === 0) ||
|
||||
@@ -1356,12 +1392,8 @@ const SewageExcretaSlurgeInp = () => {
|
||||
: SEWAGE_EXCRETA_SLURGE_PROCESSING_FAC_STATUS_STATS_CD);
|
||||
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForSubmit,
|
||||
};
|
||||
@@ -1390,11 +1422,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
const submitRequestBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: "",
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
@@ -1455,7 +1483,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForSubmit,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd:
|
||||
@@ -1532,12 +1560,8 @@ const SewageExcretaSlurgeInp = () => {
|
||||
}
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -1585,7 +1609,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
|
||||
commitActiveGrid();
|
||||
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
const mapRows = rowDataMap.get(tabKey) ?? [];
|
||||
|
||||
@@ -1603,11 +1627,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
const baseSaveRequest = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
...(noApplicable ? { noApplicable: true } : {}),
|
||||
};
|
||||
|
||||
@@ -1638,7 +1658,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
.filter((row) => isPersistedArticleRowForTab(tabKey, row))
|
||||
.map((row) => buildSlurgeProcessingFacStatusSaveItem(row, list));
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1665,7 +1685,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
buildDigestorOperatingStatusSaveItem(row, list),
|
||||
);
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1691,7 +1711,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
.filter((row) => isPersistedArticleRowForTab(tabKey, row))
|
||||
.map((row) => buildSewageSlurgeProcessingFacStatusSaveItem(row, list));
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1718,7 +1738,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
buildExcretaSlurgeProcessingStatusSaveItem(row, list),
|
||||
);
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1977,7 +1997,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
[digestorOperatingCellStyleCallback],
|
||||
);
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabHasRowData = tabRowDataExists(rowDataMap, activeTab);
|
||||
const activeTabToolbar = computeTabToolbarSnapshot(
|
||||
@@ -1998,6 +2018,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
const showSaveInToolbar = baseShowSaveInToolbar && toolbarGroupAllowed;
|
||||
const showEnterableToolbarButtons =
|
||||
baseShowEnterableToolbarButtons && toolbarGroupAllowed;
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
const showActionToolbarCard =
|
||||
toolbarGroupAllowed &&
|
||||
(baseShowActionToolbarCard || (hasSearched && loadedTabKeys.has(activeTab)));
|
||||
@@ -2005,7 +2026,8 @@ const SewageExcretaSlurgeInp = () => {
|
||||
ARTICLE_EDIT_TAB_KEYS.has(activeTab) && showEnterableToolbarButtons;
|
||||
const showNotApplicableForActiveTab =
|
||||
loadedTabKeys.has(activeTab) &&
|
||||
shouldShowNotApplicable(activeTabHasRowData, activeTabStatus);
|
||||
shouldShowNotApplicable(activeTabHasRowData, activeTabStatus) &&
|
||||
submitOk;
|
||||
const showSecondaryToolbarCard =
|
||||
hasSearched &&
|
||||
toolbarGroupAllowed &&
|
||||
@@ -2039,9 +2061,8 @@ const SewageExcretaSlurgeInp = () => {
|
||||
const statsCd = tabStatsCdMap.get(activeTab);
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -2062,6 +2083,7 @@ const SewageExcretaSlurgeInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
fctName
|
||||
@@ -2083,10 +2105,10 @@ const SewageExcretaSlurgeInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void lastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useLayoutEffect,useMemo, useRef, useState } from "react";
|
||||
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import {
|
||||
STATISTICS_INPUT_URL_PATH,
|
||||
verificationSearchToFormValues,
|
||||
@@ -40,7 +40,15 @@ import type {
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
SubmitExceptionRequest,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -61,7 +69,6 @@ import { VerificationResultDialog } from "@/components/module/VerificationResult
|
||||
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
|
||||
import type { ColumnConfig, ColumnInfo, ColumnInfoList, ColumnLayoutItem } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { FactInstallStatusInpColumn } from "@/components/util/column/input/sewagePipe/FactInstallStatusInpColumn";
|
||||
import { ManholeStatusInpColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusInpColumn";
|
||||
import { PipeDiameterStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn";
|
||||
@@ -101,9 +108,8 @@ function buildSewagePipeSearchParam(
|
||||
): SeweragePipeRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
}
|
||||
@@ -431,10 +437,14 @@ type TabToolbarSnapshot = {
|
||||
showActionToolbarCard: boolean;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -466,6 +476,8 @@ function computeTabToolbarSnapshot(
|
||||
|
||||
// 하수도 통계 관리 > 02. 하수관로
|
||||
const SewagePipeInp = () => {
|
||||
const { sidoList, isReady } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const [rowDataMap, setRowDataMap] = useState<Map<string, Record<string, string | number>[]>>(new Map());
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const [activeTab, setActiveTab] = useState<string>(SewagePipeInpColumnInfoList[0]?.tabKey ?? "ST00020001");
|
||||
@@ -494,7 +506,10 @@ const SewagePipeInp = () => {
|
||||
/** checkInputPeriod — columnInfo useMemo가 입력기간 변경을 반영하도록 state로도 유지 */
|
||||
const [inputPeriodEnterable, setInputPeriodEnterable] = useState(true);
|
||||
/** 탭별 조회 시점의 상단 버튼 노출 조건(해당 탭을 다시 조회할 때만 그 탭 항목 갱신) */
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<Map<string, TabToolbarSnapshot>>(
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<Map<string, TabToolbarSnapshot>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const { confirm } = useConfirm();
|
||||
@@ -539,6 +554,7 @@ const SewagePipeInp = () => {
|
||||
const inputFocusNonce = useStatisticsInputFocusStore((s) => s.nonce);
|
||||
useLayoutEffect(() => {
|
||||
if (activeTabId !== STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE) return;
|
||||
if (!isReady) return;
|
||||
const pending = useStatisticsInputFocusStore
|
||||
.getState()
|
||||
.takePendingForUrl(STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE);
|
||||
@@ -547,12 +563,12 @@ const SewagePipeInp = () => {
|
||||
activeTabRef.current = tabKey;
|
||||
setActiveTab(tabKey);
|
||||
if (search) {
|
||||
const values = verificationSearchToFormValues(search);
|
||||
const values = verificationSearchToFormValues(search, sidoList);
|
||||
setVerificationSearchDefaults(values);
|
||||
postVerificationSearchRef.current = { values, tabKey };
|
||||
setSearchFormRemountKey((k) => k + 1);
|
||||
}
|
||||
}, [activeTabId, inputFocusNonce]);
|
||||
}, [activeTabId, inputFocusNonce, isReady, sidoList]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeTabId !== STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE) return;
|
||||
@@ -592,6 +608,7 @@ const SewagePipeInp = () => {
|
||||
setHasSearched(false);
|
||||
setInputPeriodEnterable(true);
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
searchParamRef.current = null;
|
||||
searchDoneRef.current = false;
|
||||
lazyTabLoggedRef.current.clear();
|
||||
@@ -681,6 +698,13 @@ const SewagePipeInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/** mergeIntoExistingMap: true면 기존 맵에 병합(다른 탭 rowData·검색 후 다른 탭 캐시 유지). false면 맵 전체 교체 */
|
||||
@@ -694,7 +718,7 @@ const SewagePipeInp = () => {
|
||||
const searchConditionKey = JSON.stringify({
|
||||
statsYr: searchParam.statsYr ?? "",
|
||||
ctpvNm: searchParam.ctpvNm ?? "",
|
||||
sggNm: searchParam.sggNm ?? "",
|
||||
sggNm: values?.gugun === "ALL" ? "" : (values?.gugun ?? searchParam.sggNm ?? ""),
|
||||
sewerBzmnCd: searchParam.sewerBzmnCd ?? "",
|
||||
});
|
||||
const applyRowMap = (apply: (m: Map<string, Record<string, string | number>[]>) => void) => {
|
||||
@@ -710,12 +734,14 @@ const SewagePipeInp = () => {
|
||||
setRowDataMap(next);
|
||||
}
|
||||
};
|
||||
const filterFetched = <T,>(list: readonly T[] | null | undefined) =>
|
||||
filterBySelectedAdmdstCd(list, sidoListRef.current, values);
|
||||
|
||||
if (tabKey === 'ST00020001') {
|
||||
const response = await statisticsInputSewPipeApiService.getRegionalFactStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.regionalFactStatusList ?? []).map((d) => ({
|
||||
const convertedData = filterFetched(response.data.regionalFactStatusList).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
@@ -745,7 +771,7 @@ const SewagePipeInp = () => {
|
||||
const response = await statisticsInputSewPipeApiService.getFactInstallStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.factInstallStatusList ?? []).map((d) => ({
|
||||
const convertedData = filterFetched(response.data.factInstallStatusList).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
@@ -792,7 +818,7 @@ const SewagePipeInp = () => {
|
||||
const response = await statisticsInputSewPipeApiService.getPipeTypeStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.pipeTypeStatusList ?? []).map((d) =>
|
||||
const convertedData = filterFetched(response.data.pipeTypeStatusList).map((d) =>
|
||||
normalizePipeTypeStatusRow(d, commonInfo.ctpvNm),
|
||||
);
|
||||
applyRowMap((m) => m.set('ST00020003', toGridRows(convertedData)));
|
||||
@@ -825,7 +851,7 @@ const SewagePipeInp = () => {
|
||||
const response = await statisticsInputSewPipeApiService.getPipeDiameterStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.pipeDiameterStatusList ?? []).map((d) => ({
|
||||
const convertedData = filterFetched(response.data.pipeDiameterStatusList).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
@@ -855,7 +881,7 @@ const SewagePipeInp = () => {
|
||||
const response = await statisticsInputSewPipeApiService.getManholeStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const convertedData = (response.data.manholeStatusList ?? []).map((d) =>
|
||||
const convertedData = filterFetched(response.data.manholeStatusList).map((d) =>
|
||||
normalizeManholeStatusRow(d, commonInfo.ctpvNm),
|
||||
);
|
||||
applyRowMap((m) => m.set('ST00020005', toGridRows(convertedData)));
|
||||
@@ -884,10 +910,10 @@ const SewagePipeInp = () => {
|
||||
const response = await statisticsInputSewPipeApiService.getConnectionStatus(searchParam);
|
||||
if (response.status === 'success') {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const facilityConvertedData = (response.data.facilityConnectionList ?? []).map((d) => ({
|
||||
const facilityConvertedData = filterFetched(response.data.facilityConnectionList).map((d) => ({
|
||||
...d,
|
||||
}));
|
||||
const adminConvertedData = (response.data.adminAreaConnectionList ?? []).map((d) => ({
|
||||
const adminConvertedData = filterFetched(response.data.adminAreaConnectionList).map((d) => ({
|
||||
...d,
|
||||
ctpvNm: d.ctpvNm || commonInfo.ctpvNm,
|
||||
}));
|
||||
@@ -958,6 +984,7 @@ const SewagePipeInp = () => {
|
||||
setFooterVerificationByTab(new Map());
|
||||
setStatsCd("");
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
}
|
||||
|
||||
lazyTabLoggedRef.current.clear();
|
||||
@@ -1119,9 +1146,8 @@ const SewagePipeInp = () => {
|
||||
|
||||
const params: SubmitExceptionRequest = {
|
||||
...submitInfo,
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues?.sido ?? "",
|
||||
sggNm: searchValues?.gugun === "ALL" ? "" : (searchValues?.gugun ?? ""),
|
||||
statsYr: searchValues?.year ?? "",
|
||||
userId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -1204,8 +1230,7 @@ const SewagePipeInp = () => {
|
||||
const submitBase = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
userId: userInfo.userUnqId,
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
|
||||
@@ -1463,7 +1488,7 @@ const SewagePipeInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: values.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: values?.bsnmCd ?? '',
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: values.year ?? "",
|
||||
lae_sbmsn_stts_cd: statusForTab?.laeSbmsnSttsCd === "4" ? "4" : "2",
|
||||
@@ -1493,9 +1518,8 @@ const SewagePipeInp = () => {
|
||||
);
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
{
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
statsYr: values.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
},
|
||||
@@ -1512,9 +1536,8 @@ const SewagePipeInp = () => {
|
||||
);
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
{
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
statsYr: values.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
},
|
||||
@@ -1538,9 +1561,8 @@ const SewagePipeInp = () => {
|
||||
);
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
{
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
statsYr: values.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
},
|
||||
@@ -1567,9 +1589,8 @@ const SewagePipeInp = () => {
|
||||
const userInfo = await getUserInfo();
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues?.sido ?? '',
|
||||
sggNm: searchValues?.gugun === "ALL" ? "" : (searchValues?.gugun ?? ""),
|
||||
statsYr: searchValues?.year ?? '',
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: tabStatsCdMap.get(activeTab) ?? statsCd,
|
||||
@@ -1699,8 +1720,7 @@ const SewagePipeInp = () => {
|
||||
const param: SeweragePipeInputRegionalFactStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
userId: userInfo.userUnqId,
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
saveList,
|
||||
@@ -1779,8 +1799,7 @@ const SewagePipeInp = () => {
|
||||
const param: SeweragePipeInputFactInstallStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
userId: userInfo.userUnqId,
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
saveList,
|
||||
@@ -1864,8 +1883,7 @@ const SewagePipeInp = () => {
|
||||
const param: SeweragePipeInputPipeTypeStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
userId: userInfo.userUnqId,
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
saveList,
|
||||
@@ -1927,8 +1945,7 @@ const SewagePipeInp = () => {
|
||||
const param: SeweragePipeInputPipeDiameterStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
userId: userInfo.userUnqId,
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
saveList,
|
||||
@@ -2006,8 +2023,7 @@ const SewagePipeInp = () => {
|
||||
const param: SeweragePipeInputManholeStatusSaveRequest = {
|
||||
statsYr: values.year ?? "",
|
||||
ctpvNm: values.sido ?? "",
|
||||
sggNm: values.gugun === "ALL" ? "" : (values.gugun ?? ""),
|
||||
sewerBzmnCd: values.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
userId: userInfo.userUnqId,
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
saveList,
|
||||
@@ -2036,12 +2052,12 @@ const SewagePipeInp = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const gugunOkOrNotDoList = buildGugunOkForToolbar(lastSearchedValues);
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const gugunOkOrNotDoList = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
@@ -2067,6 +2083,7 @@ const SewagePipeInp = () => {
|
||||
return (
|
||||
<>
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
onSubmit={handleSearch}
|
||||
@@ -2085,10 +2102,10 @@ const SewagePipeInp = () => {
|
||||
{showEnterableToolbarButtons && (
|
||||
<>
|
||||
{activeTab !== 'ST00020002' && <LastYearDataButton getLastYearDataFunc={() => void getLastYearDataFunc()} />}
|
||||
<SubmitButton submitFunc={() => void submitFunc(false)} />
|
||||
{submitOk && <SubmitButton submitFunc={() => void submitFunc(false)} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
@@ -2306,9 +2323,8 @@ const SewagePipeInp = () => {
|
||||
searchValues?.bsnmCd &&
|
||||
(tabStatsCdMap.get(activeTab) ?? statsCd)
|
||||
? {
|
||||
sewerBzmnCd: searchValues.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues.sido,
|
||||
sggNm: searchValues.gugun === "ALL" ? "" : (searchValues.gugun ?? ""),
|
||||
statsYr: searchValues.year,
|
||||
statsCd: tabStatsCdMap.get(activeTab) ?? statsCd,
|
||||
}
|
||||
@@ -2342,9 +2358,8 @@ const SewagePipeInp = () => {
|
||||
searchValues?.bsnmCd &&
|
||||
(tabStatsCdMap.get(activeTab) ?? statsCd)
|
||||
? {
|
||||
sewerBzmnCd: searchValues.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues.sido,
|
||||
sggNm: searchValues.gugun === "ALL" ? "" : (searchValues.gugun ?? ""),
|
||||
statsYr: searchValues.year,
|
||||
statsCd: tabStatsCdMap.get(activeTab) ?? statsCd,
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import {
|
||||
STATISTICS_INPUT_URL_PATH,
|
||||
verificationSearchToFormValues,
|
||||
@@ -27,7 +27,15 @@ import type {
|
||||
cancelSubmitRequest,
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import {
|
||||
LoadingWithAnimation,
|
||||
Tabs,
|
||||
@@ -52,7 +60,6 @@ import { VerificationResultDialog } from "@/components/module/VerificationResult
|
||||
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
|
||||
import type { ColumnInfo } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { PipeDredgingStatusInpColumn } from "@/components/util/column/input/sewagePipeMaintain/PipeDredgingStatusInpColumn";
|
||||
import { RepairStatusInpColumn } from "@/components/util/column/input/sewagePipeMaintain/RepairStatusInpColumn";
|
||||
import { fetchColumnGuidesRecord } from "@/components/util/grid/columnGuides";
|
||||
@@ -74,9 +81,8 @@ function buildSewagePipeMaintainSearchParam(
|
||||
): SewagePipeMaintainRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
}
|
||||
@@ -116,10 +122,14 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -263,6 +273,8 @@ function buildDredgingRowList(
|
||||
|
||||
// 하수도 통계 관리 > 03. 하수관로 유지관리
|
||||
const SewagePipeMaintainInp = () => {
|
||||
const { sidoList, isReady } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
const toolbarGroupAllowed = useStatisticsInputToolbarGroupGate();
|
||||
@@ -288,9 +300,12 @@ const SewagePipeMaintainInp = () => {
|
||||
const [footerVerificationByTab, setFooterVerificationByTab] = useState<
|
||||
Map<string, VerificationResultLikeMap | null>
|
||||
>(new Map());
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
Map<string, TabToolbarSnapshot>
|
||||
>(new Map());
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [verificationHistoryOpen, setVerificationHistoryOpen] = useState(false);
|
||||
const [verificationResultDialogOpen, setVerificationResultDialogOpen] = useState(false);
|
||||
const [showSubmitDialog, setShowSubmitDialog] = useState(false);
|
||||
@@ -320,6 +335,7 @@ const SewagePipeMaintainInp = () => {
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (activeTabId !== STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE_MAINTAIN) return;
|
||||
if (!isReady) return;
|
||||
const pending = useStatisticsInputFocusStore
|
||||
.getState()
|
||||
.takePendingForUrl(STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE_MAINTAIN);
|
||||
@@ -327,12 +343,12 @@ const SewagePipeMaintainInp = () => {
|
||||
const { tabKey, search } = pending;
|
||||
setActiveTab(tabKey);
|
||||
if (search) {
|
||||
const values = verificationSearchToFormValues(search);
|
||||
const values = verificationSearchToFormValues(search, sidoList);
|
||||
setVerificationSearchDefaults(values);
|
||||
postVerificationSearchRef.current = { values, tabKey };
|
||||
setSearchFormRemountKey((k) => k + 1);
|
||||
}
|
||||
}, [activeTabId, inputFocusNonce]);
|
||||
}, [activeTabId, inputFocusNonce, isReady, sidoList]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeTabId !== STATISTICS_INPUT_URL_PATH.SEWAGE_PIPE_MAINTAIN) return;
|
||||
@@ -377,6 +393,13 @@ const SewagePipeMaintainInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const applyRowMap = (
|
||||
@@ -418,7 +441,11 @@ const SewagePipeMaintainInp = () => {
|
||||
return false;
|
||||
}
|
||||
const { commonInfo, statusInfo, repairStatusList } = response.data;
|
||||
const convertedData = (repairStatusList ?? []).map((d) => ({
|
||||
const convertedData = filterBySelectedAdmdstCd(
|
||||
repairStatusList ?? [],
|
||||
sidoListRef.current,
|
||||
searchContext,
|
||||
).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
@@ -457,7 +484,11 @@ const SewagePipeMaintainInp = () => {
|
||||
return false;
|
||||
}
|
||||
const { commonInfo, statusInfo, pipeDredgingStatusList } = response.data;
|
||||
const convertedData = (pipeDredgingStatusList ?? []).map((d) => ({
|
||||
const convertedData = filterBySelectedAdmdstCd(
|
||||
pipeDredgingStatusList ?? [],
|
||||
sidoListRef.current,
|
||||
searchContext,
|
||||
).map((d) => ({
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
...d,
|
||||
}));
|
||||
@@ -581,11 +612,7 @@ const SewagePipeMaintainInp = () => {
|
||||
const submitInfoBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
|
||||
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
|
||||
@@ -597,12 +624,8 @@ const SewagePipeMaintainInp = () => {
|
||||
};
|
||||
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
};
|
||||
@@ -647,7 +670,7 @@ const SewagePipeMaintainInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd: activeTabStatus?.laeSbmsnSttsCd === "4" ? "4" : "2",
|
||||
@@ -727,11 +750,7 @@ const SewagePipeMaintainInp = () => {
|
||||
const baseRequest = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -833,12 +852,8 @@ const SewagePipeMaintainInp = () => {
|
||||
const statsCdForTab = tabStatsCdMap.get(tabKey) ?? tabKey;
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -871,6 +886,7 @@ const SewagePipeMaintainInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setActiveTab(firstTabKey);
|
||||
setLastSearchedValues(null);
|
||||
setHasSearched(false);
|
||||
@@ -917,6 +933,7 @@ const SewagePipeMaintainInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
activeTabRef.current = firstTabKey;
|
||||
setActiveTab(firstTabKey);
|
||||
}
|
||||
@@ -1012,10 +1029,9 @@ const SewagePipeMaintainInp = () => {
|
||||
return map;
|
||||
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo, columnGuidesByTab]);
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
@@ -1036,6 +1052,7 @@ const SewagePipeMaintainInp = () => {
|
||||
baseShowEnterableToolbarButtons && toolbarGroupAllowed;
|
||||
const showActionToolbarCard =
|
||||
baseShowActionToolbarCard && toolbarGroupAllowed;
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
|
||||
const openVerificationHistoryDialog = () => {
|
||||
const ctx = lastSearchedValues ?? searchValues;
|
||||
@@ -1052,9 +1069,8 @@ const SewagePipeMaintainInp = () => {
|
||||
const statsCd = tabStatsCdMap.get(activeTab);
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -1102,6 +1118,7 @@ const SewagePipeMaintainInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
onSubmit={handleSearch}
|
||||
@@ -1122,10 +1139,10 @@ const SewagePipeMaintainInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void getLastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
@@ -1161,7 +1178,7 @@ const SewagePipeMaintainInp = () => {
|
||||
tabStatusInfoMap.get(tabKey) ?? null,
|
||||
inputPeriodEnterable,
|
||||
) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const tabStatusInfo = tabStatusInfoMap.get(tabKey) ?? null;
|
||||
|
||||
return (
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { ValueType } from "realgrid";
|
||||
import type { RealGridReact } from "realgrid-react";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
@@ -38,7 +38,16 @@ import type {
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sgg,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
resolveNoApplicableForRequest,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -66,7 +75,6 @@ import type {
|
||||
ColumnInfoList,
|
||||
} from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { RainfallPumpStationInpColumn } from "@/components/util/column/input/sewageReservoirPump/RainfallPumpStationInpColumn";
|
||||
import { SewageReservoirInpColumn } from "@/components/util/column/input/sewageReservoirPump/SewageReservoirInpColumn";
|
||||
import { fetchColumnGuidesRecord } from "@/components/util/grid/columnGuides";
|
||||
@@ -126,10 +134,22 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildNoApplicableForRequest(
|
||||
values: SearchFormValues | null,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
return resolveNoApplicableForRequest(sidoListRef.current, values, checked, isSaveListEmpty);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -171,9 +191,8 @@ function buildSewageReservoirSearchParam(
|
||||
const fcltNm = values.fctName?.trim();
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(fcltNm ? { fcltNm } : {}),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
@@ -246,8 +265,9 @@ function buildSggNmColumn(
|
||||
function mapSewageReservoirListToGridRows(
|
||||
list: SewageReservoirItem[],
|
||||
ctpvNm: string,
|
||||
values?: SearchFormValues | null,
|
||||
): GridRowWithVerification[] {
|
||||
return list.map((item) => {
|
||||
return filterBySelectedAdmdstCd(list, sidoListRef.current, values).map((item) => {
|
||||
const row = toGridRows([
|
||||
{
|
||||
...item,
|
||||
@@ -399,8 +419,9 @@ function buildRainfallPumpStationSaveItem(
|
||||
function mapRainfallPumpStationListToGridRows(
|
||||
list: RainfallPumpStationItem[],
|
||||
ctpvNm: string,
|
||||
values?: SearchFormValues | null,
|
||||
): GridRowWithVerification[] {
|
||||
return list.map((item) => {
|
||||
return filterBySelectedAdmdstCd(list, sidoListRef.current, values).map((item) => {
|
||||
const row = toGridRows([
|
||||
{
|
||||
...item,
|
||||
@@ -447,6 +468,8 @@ async function waitForImrJobCompleted(
|
||||
|
||||
// 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장
|
||||
const SewageReservoirPumpInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
@@ -478,9 +501,9 @@ const SewageReservoirPumpInp = () => {
|
||||
alert("시군구를 선택해주세요.");
|
||||
return;
|
||||
}
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getCurrentRowsForTab(tabKey).length === 0);
|
||||
const currentData = getCurrentRowsForTab(tabKey);
|
||||
if (!noApplicable && currentData.length === 0) {
|
||||
if (!noApplicable && currentData.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -505,12 +528,8 @@ const SewageReservoirPumpInp = () => {
|
||||
const userInfo = await getUserInfo();
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -663,7 +682,7 @@ const SewageReservoirPumpInp = () => {
|
||||
if (!(await confirm("저장 하시겠습니까?"))) return;
|
||||
|
||||
commitGridForTab(tabKey);
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getCurrentRowsForTab(tabKey).length === 0);
|
||||
const currentData = getCurrentRowsForTab(tabKey);
|
||||
const isReservoirTab = tabKey === SEWAGE_RESERVOIR_STATS_CD;
|
||||
const saveList = noApplicable
|
||||
@@ -682,7 +701,7 @@ const SewageReservoirPumpInp = () => {
|
||||
: rainfallPumpStationDeleteList
|
||||
.filter((row) => String(row.fcltSn ?? "").trim() !== "")
|
||||
.map((row) => buildRainfallPumpStationSaveItem(row, sggOptions));
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -690,11 +709,7 @@ const SewageReservoirPumpInp = () => {
|
||||
const requestBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
...(noApplicable ? { noApplicable: true } : {}),
|
||||
};
|
||||
@@ -754,7 +769,7 @@ const SewageReservoirPumpInp = () => {
|
||||
}
|
||||
|
||||
commitGridForTab(tabKey);
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getCurrentRowsForTab(tabKey).length === 0);
|
||||
const currentData = getCurrentRowsForTab(tabKey);
|
||||
const isReservoirTab = tabKey === SEWAGE_RESERVOIR_STATS_CD;
|
||||
const submitList = noApplicable
|
||||
@@ -773,12 +788,8 @@ const SewageReservoirPumpInp = () => {
|
||||
const activeTabStatus = tabStatusInfoMap.get(tabKey) ?? null;
|
||||
const statsCdForTab = tabStatsCdMap.get(tabKey) ?? tabKey;
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
};
|
||||
@@ -792,7 +803,7 @@ const SewageReservoirPumpInp = () => {
|
||||
await loadActiveTabData(tabKey, lastSearchedValues, true, false);
|
||||
};
|
||||
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -800,11 +811,7 @@ const SewageReservoirPumpInp = () => {
|
||||
const submitRequestBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
...(noApplicable ? { noApplicable: true } : {}),
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laeKbrdrJbgdNm: submitInfo.laeKbrdrJbgdNm,
|
||||
@@ -847,7 +854,7 @@ const SewageReservoirPumpInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd:
|
||||
@@ -926,9 +933,12 @@ const SewageReservoirPumpInp = () => {
|
||||
const [tabStatusInfoMap, setTabStatusInfoMap] = useState<
|
||||
Map<string, SewerageStatusInfo | null>
|
||||
>(new Map());
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
Map<string, TabToolbarSnapshot>
|
||||
>(new Map());
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [tabStatsCdMap, setTabStatsCdMap] = useState<Map<string, string>>(new Map());
|
||||
const [isVerificationFailedByTab, setIsVerificationFailedByTab] = useState<
|
||||
Map<string, boolean>
|
||||
@@ -1024,6 +1034,13 @@ const SewageReservoirPumpInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const applyRowMap = (
|
||||
@@ -1068,6 +1085,7 @@ const SewageReservoirPumpInp = () => {
|
||||
const gridRows = mapSewageReservoirListToGridRows(
|
||||
list,
|
||||
commonInfo.ctpvNm,
|
||||
values,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -1116,6 +1134,7 @@ const SewageReservoirPumpInp = () => {
|
||||
const gridRows = mapRainfallPumpStationListToGridRows(
|
||||
list,
|
||||
commonInfo.ctpvNm,
|
||||
values,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -1198,6 +1217,7 @@ const SewageReservoirPumpInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setLastSearchedValues(null);
|
||||
setSggOptions([]);
|
||||
sggOptionsSidoRef.current = null;
|
||||
@@ -1249,6 +1269,7 @@ const SewageReservoirPumpInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
loadedTabKeysRef.current.clear();
|
||||
setActiveTab(firstTabKey);
|
||||
}
|
||||
@@ -1318,10 +1339,9 @@ const SewageReservoirPumpInp = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const searchContextForToolbar = lastSearchedValues ?? searchValues;
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
@@ -1342,6 +1362,7 @@ const SewageReservoirPumpInp = () => {
|
||||
baseShowEnterableToolbarButtons && toolbarGroupAllowed;
|
||||
const showActionToolbarCard =
|
||||
baseShowActionToolbarCard && toolbarGroupAllowed;
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
const isReservoirOrRainfallTab =
|
||||
activeTab === SEWAGE_RESERVOIR_STATS_CD || activeTab === rainfallPumpTabKey;
|
||||
const showArticleToolbarCard =
|
||||
@@ -1356,7 +1377,8 @@ const SewageReservoirPumpInp = () => {
|
||||
activeTab,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
tabStatusInfoMap.get(activeTab),
|
||||
);
|
||||
) &&
|
||||
submitOk;
|
||||
const setIsNotApplicableForActiveTab: Dispatch<SetStateAction<boolean>> = useCallback(
|
||||
(next) => {
|
||||
const tabKey = activeTabRef.current;
|
||||
@@ -1514,9 +1536,8 @@ const SewageReservoirPumpInp = () => {
|
||||
const statsCd = tabStatsCdMap.get(activeTab);
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -1537,6 +1558,7 @@ const SewageReservoirPumpInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
fctName={true}
|
||||
@@ -1558,10 +1580,10 @@ const SewageReservoirPumpInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void getLastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
@@ -1607,7 +1629,7 @@ const SewageReservoirPumpInp = () => {
|
||||
tabStatusInfoMap.get(tabKey) ?? null,
|
||||
inputPeriodEnterable,
|
||||
) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const tabStatusInfo = tabStatusInfoMap.get(tabKey) ?? null;
|
||||
const isReservoirTab = tabKey === SEWAGE_RESERVOIR_STATS_CD;
|
||||
return (
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { statisticsInputSewSupplyRateApi } from "@/entities/statistics/api/input/statistics-input-sew-supply-rate-service";
|
||||
@@ -35,7 +35,15 @@ import type {
|
||||
cancelSubmitRequest,
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -54,7 +62,6 @@ import { VerificationResultDialog } from "@/components/module/VerificationResult
|
||||
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
|
||||
import type { ColumnConfig, ColumnInfo } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { CauserBurdenInpColumn } from "@/components/util/column/input/sewerageFinance/CauserBurdenInpColumn";
|
||||
import { SewerageChargeInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageChargeInpColumn";
|
||||
import { SewerageFinanceSettleInpColumn } from "@/components/util/column/input/sewerageFinance/SewerageFinanceSettleInpColumn";
|
||||
@@ -101,9 +108,8 @@ function buildSewerageFinanceSearchParam(
|
||||
): SewerageFinanceRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
}
|
||||
@@ -121,10 +127,14 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -160,8 +170,8 @@ function tabRowDataExists(
|
||||
|
||||
function mapRegionalListToGridRows<
|
||||
T extends { verificationResult?: SewerageFinanceVerificationResult },
|
||||
>(list: T[], ctpvNm: string): GridRowWithVerification[] {
|
||||
return list.map((item) => {
|
||||
>(list: T[], ctpvNm: string, values?: SearchFormValues | null): GridRowWithVerification[] {
|
||||
return filterBySelectedAdmdstCd(list, sidoListRef.current, values).map((item) => {
|
||||
const { verificationResult, ...rest } = item;
|
||||
const row = toGridRows([{ ctpvNm, ...rest }])[0] as GridRowWithVerification;
|
||||
if (verificationResult) row.verificationResult = verificationResult;
|
||||
@@ -342,6 +352,8 @@ async function waitForImrJobCompleted(
|
||||
|
||||
// 하수도 통계 관리 > 09. 하수도재정
|
||||
const SewerageFinanceInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
@@ -369,9 +381,12 @@ const SewerageFinanceInp = () => {
|
||||
const [footerVerificationByTab, setFooterVerificationByTab] = useState<
|
||||
Map<string, VerificationResultLikeMap | null>
|
||||
>(new Map());
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
Map<string, TabToolbarSnapshot>
|
||||
>(new Map());
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [columnGuidesByTab, setColumnGuidesByTab] = useState<
|
||||
Record<string, Record<string, string>>
|
||||
>({});
|
||||
@@ -431,6 +446,13 @@ const SewerageFinanceInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const applyRowMap = (
|
||||
@@ -471,6 +493,7 @@ const SewerageFinanceInp = () => {
|
||||
const gridRows = mapRegionalListToGridRows(
|
||||
(sewerageFinanceSettleList ?? []) as SewerageFinanceSettleItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -500,6 +523,7 @@ const SewerageFinanceInp = () => {
|
||||
const gridRows = mapRegionalListToGridRows(
|
||||
(sewerageChargeList ?? []) as SewerageChargeItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -529,6 +553,7 @@ const SewerageFinanceInp = () => {
|
||||
const gridRows = mapRegionalListToGridRows(
|
||||
(sewerageUsageFeeList ?? []) as SewerageUsageFeeItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -558,6 +583,7 @@ const SewerageFinanceInp = () => {
|
||||
const gridRows = mapRegionalListToGridRows(
|
||||
(causerBurdenList ?? []) as CauserBurdenItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -590,6 +616,7 @@ const SewerageFinanceInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setActiveTab(firstTabKey);
|
||||
activeTabRef.current = firstTabKey;
|
||||
setLastSearchedValues(null);
|
||||
@@ -633,6 +660,7 @@ const SewerageFinanceInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
activeTabRef.current = firstTabKey;
|
||||
setActiveTab(firstTabKey);
|
||||
}
|
||||
@@ -742,12 +770,8 @@ const SewerageFinanceInp = () => {
|
||||
}
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -830,11 +854,7 @@ const SewerageFinanceInp = () => {
|
||||
const submitInfoBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
|
||||
@@ -846,12 +866,8 @@ const SewerageFinanceInp = () => {
|
||||
};
|
||||
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
};
|
||||
@@ -924,7 +940,7 @@ const SewerageFinanceInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd: activeTabStatus?.laeSbmsnSttsCd === "4" ? "4" : "2",
|
||||
@@ -1012,11 +1028,7 @@ const SewerageFinanceInp = () => {
|
||||
const baseRequest = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -1137,9 +1149,8 @@ const SewerageFinanceInp = () => {
|
||||
const statsCd = tabStatsCdMap.get(activeTab);
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -1170,19 +1181,20 @@ const SewerageFinanceInp = () => {
|
||||
return map;
|
||||
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo, columnGuidesByTab]);
|
||||
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
hasSearched,
|
||||
lastSearchedValues,
|
||||
searchContextForToolbar,
|
||||
inputPeriodEnterable,
|
||||
isAdminInfo,
|
||||
);
|
||||
const { showSaveInToolbar, showEnterableToolbarButtons, showActionToolbarCard } =
|
||||
activeTabToolbar;
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
|
||||
const verificationCellStyle = ({
|
||||
fieldName,
|
||||
@@ -1241,6 +1253,7 @@ const SewerageFinanceInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
onSubmit={handleSearch}
|
||||
@@ -1261,10 +1274,10 @@ const SewerageFinanceInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void lastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
@@ -1300,7 +1313,7 @@ const SewerageFinanceInp = () => {
|
||||
tabStatusInfoMap.get(tabKey) ?? null,
|
||||
inputPeriodEnterable,
|
||||
) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const tabStatusInfo = tabStatusInfoMap.get(tabKey) ?? null;
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useSearchConditionSidoList, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import {
|
||||
STATISTICS_INPUT_URL_PATH,
|
||||
verificationSearchToFormValues,
|
||||
@@ -25,8 +25,15 @@ import type {
|
||||
cancelSubmitRequest,
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sido,
|
||||
SubmitExceptionRequest,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -45,7 +52,6 @@ import SearchForm from "@/components/module/SearchForm";
|
||||
import { VerificationResultDialog } from "@/components/module/VerificationResultDialog";
|
||||
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { SeweragePenetrationRateInpColumn } from "@/components/util/column/input/SeweragePenetrationRateInpColumn";
|
||||
import { getFooterSummary } from "@/components/util/grid/footerSummary";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
@@ -118,14 +124,15 @@ async function waitForImrJobCompleted(
|
||||
throw new Error("시계열 검증 완료 대기 시간이 초과되었습니다.");
|
||||
}
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function getSewerageSupplyRateParams(
|
||||
values: SearchFormValues,
|
||||
overrides?: { yr?: string; demoYr?: string; mode?: string }
|
||||
): SewerageSupplyRateRequestParams {
|
||||
return {
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === 'ALL' ? '' : values.gugun,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
statsYr: overrides?.yr ?? values.year,
|
||||
...(overrides?.mode && { mode: overrides.mode }),
|
||||
};
|
||||
@@ -133,6 +140,8 @@ function getSewerageSupplyRateParams(
|
||||
|
||||
// 하수도 통계 관리 > 01. 하수도 보급률
|
||||
const SeweragePenetrationRateInp = () => {
|
||||
const { sidoList, isReady } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const [rowData, setRowData] = useState<Record<string, string | number>[]>([]);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
@@ -174,15 +183,16 @@ const SeweragePenetrationRateInp = () => {
|
||||
if (activeTabId !== STATISTICS_INPUT_URL_PATH.SEWERAGE_PENETRATION_RATE) {
|
||||
return;
|
||||
}
|
||||
if (!isReady) return;
|
||||
const pending = useStatisticsInputFocusStore
|
||||
.getState()
|
||||
.takePendingForUrl(STATISTICS_INPUT_URL_PATH.SEWERAGE_PENETRATION_RATE);
|
||||
if (!pending?.search) return;
|
||||
const values = verificationSearchToFormValues(pending.search);
|
||||
const values = verificationSearchToFormValues(pending.search, sidoList);
|
||||
setVerificationSearchDefaults(values);
|
||||
postVerificationSearchRef.current = values;
|
||||
setSearchFormRemountKey((k) => k + 1);
|
||||
}, [activeTabId, inputFocusNonce]);
|
||||
}, [activeTabId, inputFocusNonce, isReady, sidoList]);
|
||||
|
||||
useEffect(() => {
|
||||
if (activeTabId !== STATISTICS_INPUT_URL_PATH.SEWERAGE_PENETRATION_RATE) {
|
||||
@@ -269,14 +279,22 @@ const SeweragePenetrationRateInp = () => {
|
||||
setSearchFormRemountKey((k) => k + 1);
|
||||
};
|
||||
|
||||
const fetchSewerageSupplyRate = async (params: SewerageSupplyRateRequestParams, isEnterable: boolean) => {
|
||||
const fetchSewerageSupplyRate = async (
|
||||
params: SewerageSupplyRateRequestParams,
|
||||
isEnterable: boolean,
|
||||
values?: SearchFormValues | null,
|
||||
) => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await statisticsInputSewSupplyRateApi.getSewerageSupplyRateList(params);
|
||||
if (response.status === 'success' && response.data) {
|
||||
const commonInfo = response.data.commonInfo;
|
||||
const statusInfo = response.data.statusInfo;
|
||||
const convertedData: SewerageSupplyRateItem[] = response.data.sewerageSupplyRateList.map((d: SewerageSupplyRateItem) => ({
|
||||
const convertedData: SewerageSupplyRateItem[] = filterBySelectedAdmdstCd(
|
||||
response.data.sewerageSupplyRateList,
|
||||
sidoListRef.current,
|
||||
values,
|
||||
).map((d: SewerageSupplyRateItem) => ({
|
||||
...d,
|
||||
ctpvNm: commonInfo.ctpvNm,
|
||||
spcCtpnRgnCn: d.spcCtpnRgnCn === '' || d.spcCtpnRgnCn === null ? '해당없음' : d.spcCtpnRgnCn,
|
||||
@@ -346,7 +364,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
setPeriodCheckList(periods);
|
||||
const checkEnterable = isInputPeriodCurrent(periods);
|
||||
setLastSearchedYear(values.year || null);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values), checkEnterable);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values), checkEnterable, values);
|
||||
setLastSearchedValues(values);
|
||||
} else {
|
||||
alert(response.message);
|
||||
@@ -374,9 +392,8 @@ const SeweragePenetrationRateInp = () => {
|
||||
|
||||
const params: SubmitExceptionRequest = {
|
||||
...submitInfo,
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues?.sido ?? '',
|
||||
sggNm: searchValues?.gugun === "ALL" ? "" : (searchValues?.gugun ?? ''),
|
||||
statsYr: searchValues?.year ?? '',
|
||||
userId: userInfo.userUnqId,
|
||||
statsCd: statsCd,
|
||||
@@ -392,7 +409,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
const response = await statisticsApi.submitException(params);
|
||||
|
||||
if (response.status === 'success') {
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), false);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), false, searchValues ?? {});
|
||||
alert('제출되었습니다.');
|
||||
} else {
|
||||
alert(response.message || '데이터 제출 중 오류가 발생했습니다.');
|
||||
@@ -416,7 +433,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values, { mode: 'PRE' }), true);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(values, { mode: 'PRE' }), true, values);
|
||||
};
|
||||
|
||||
const submitFunc = async (isException: boolean) => {
|
||||
@@ -512,9 +529,8 @@ const SeweragePenetrationRateInp = () => {
|
||||
}));
|
||||
|
||||
const requestData: SewerageSupplyRateSaveRequest = {
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues?.sido ?? '',
|
||||
sggNm: searchValues?.gugun === "ALL" ? "" : (searchValues?.gugun ?? ''),
|
||||
statsYr: searchValues?.year ?? '',
|
||||
userId: userInfo.userUnqId,
|
||||
submitList: convertedData,
|
||||
@@ -558,13 +574,12 @@ const SeweragePenetrationRateInp = () => {
|
||||
);
|
||||
}
|
||||
setGlobalProgress(100);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true, searchValues ?? {});
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
searchValues?.year && searchValues?.sido && searchValues?.bsnmCd && statsCd
|
||||
? {
|
||||
sewerBzmnCd: searchValues.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues.sido,
|
||||
sggNm: searchValues.gugun === "ALL" ? "" : (searchValues.gugun ?? ""),
|
||||
statsYr: searchValues.year,
|
||||
statsCd,
|
||||
}
|
||||
@@ -573,14 +588,13 @@ const SeweragePenetrationRateInp = () => {
|
||||
{ notify: alert },
|
||||
);
|
||||
} catch (e) {
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true, searchValues ?? {});
|
||||
setIsLoading(false);
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
searchValues?.year && searchValues?.sido && searchValues?.bsnmCd && statsCd
|
||||
? {
|
||||
sewerBzmnCd: searchValues.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues.sido,
|
||||
sggNm: searchValues.gugun === "ALL" ? "" : (searchValues.gugun ?? ""),
|
||||
statsYr: searchValues.year,
|
||||
statsCd,
|
||||
}
|
||||
@@ -597,13 +611,12 @@ const SeweragePenetrationRateInp = () => {
|
||||
}
|
||||
} else {
|
||||
setGlobalProgress(100);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), false);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), false, searchValues ?? {});
|
||||
await openVerificationResultDialogIfNeeded(
|
||||
searchValues?.year && searchValues?.sido && searchValues?.bsnmCd && statsCd
|
||||
? {
|
||||
sewerBzmnCd: searchValues.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues.sido,
|
||||
sggNm: searchValues.gugun === "ALL" ? "" : (searchValues.gugun ?? ""),
|
||||
statsYr: searchValues.year,
|
||||
statsCd,
|
||||
}
|
||||
@@ -702,9 +715,8 @@ const SeweragePenetrationRateInp = () => {
|
||||
}));
|
||||
|
||||
const requestData: SewerageSupplyRateSaveRequest = {
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '', // 하수도 사업자 코드
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues?.sido ?? '', // 시도
|
||||
sggNm: searchValues?.gugun === "ALL" ? "" : (searchValues?.gugun ?? ''),
|
||||
statsYr: searchValues?.year ?? '', // 통계 연도
|
||||
userId: userInfo.userUnqId, // 사용자
|
||||
saveList: convertedData, // 저장 데이터
|
||||
@@ -720,7 +732,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
if (response.status === 'success') {
|
||||
setGlobalProgress(50);
|
||||
setGlobalProgress(100);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true);
|
||||
await fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true, searchValues ?? {});
|
||||
alert('저장되었습니다.');
|
||||
} else {
|
||||
alert(response.message || '데이터 저장 중 오류가 발생했습니다.');
|
||||
@@ -747,9 +759,8 @@ const SeweragePenetrationRateInp = () => {
|
||||
const userInfo = await getUserInfo();
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: searchValues?.bsnmCd ?? '',
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues?.sido ?? '',
|
||||
sggNm: searchValues?.gugun === "ALL" ? "" : (searchValues?.gugun ?? ""),
|
||||
statsYr: searchValues?.year ?? '',
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCd,
|
||||
@@ -758,7 +769,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
const response = await statisticsApi.cancelSubmit(requestData);
|
||||
|
||||
if (response.status === 'success') {
|
||||
fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true);
|
||||
fetchSewerageSupplyRate(getSewerageSupplyRateParams(searchValues ?? {}), true, searchValues ?? {});
|
||||
alert('제출 취소되었습니다.');
|
||||
} else {
|
||||
alert(response.message ?? '제출 취소 중 오류가 발생했습니다.');
|
||||
@@ -777,9 +788,9 @@ const SeweragePenetrationRateInp = () => {
|
||||
setVerificationHistoryOpen(true);
|
||||
};
|
||||
|
||||
const gugunOkOrNotDoList = doList.includes(lastSearchedValues?.bsnmCd || '')
|
||||
? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL')
|
||||
: true;
|
||||
const toolbarSearchContext = lastSearchedValues;
|
||||
const gugunOkOrNotDoList = isGugunOkForToolbar(sidoList, toolbarSearchContext);
|
||||
const submitOk = isSubmitOkForToolbar(sidoList, toolbarSearchContext);
|
||||
|
||||
const inputPeriodCurrent = isInputPeriodCurrent(periodCheckList);
|
||||
const isSubmitted = statusInfo?.laeSbmsnSttsCd === '2';
|
||||
@@ -802,6 +813,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
onSubmit={handleSearch}
|
||||
@@ -818,10 +830,10 @@ const SeweragePenetrationRateInp = () => {
|
||||
{showEnterableToolbarButtons && (
|
||||
<>
|
||||
<LastYearDataButton getLastYearDataFunc={() => getLastYearDataFunc(searchValues ?? {})} />
|
||||
<SubmitButton submitFunc={() => submitFunc(false)} />
|
||||
{submitOk && <SubmitButton submitFunc={() => submitFunc(false)} />}
|
||||
</>
|
||||
)}
|
||||
{statusInfo?.laeSbmsnSttsCd === '2' && <CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />}
|
||||
{statusInfo?.laeSbmsnSttsCd === '2' && submitOk && <CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
</div>
|
||||
</div>
|
||||
@@ -836,7 +848,7 @@ const SeweragePenetrationRateInp = () => {
|
||||
<DataGrid
|
||||
key={((isEnterable || isAdminInfo) && inputPeriodCurrent) ? 'enterable' : 'readonly'}
|
||||
columnInfo={columnInfo}
|
||||
isExcelImport={(rowData.length > 0) && isEnterable && (doList.includes(lastSearchedValues?.bsnmCd || '') ? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== 'ALL') : true)}
|
||||
isExcelImport={(rowData.length > 0) && isEnterable && gugunOkOrNotDoList}
|
||||
excelImportSewerBzmnCd={(lastSearchedValues ?? searchValues)?.bsnmCd}
|
||||
excelExportSearchContext={toExcelExportSearchContextFromSearchForm(lastSearchedValues ?? searchValues)}
|
||||
rowStartNum={3}
|
||||
@@ -892,9 +904,8 @@ const SeweragePenetrationRateInp = () => {
|
||||
queryContext={
|
||||
searchValues?.year && searchValues?.sido && searchValues?.bsnmCd && statsCd
|
||||
? {
|
||||
sewerBzmnCd: searchValues.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues.sido,
|
||||
sggNm: searchValues.gugun === "ALL" ? "" : (searchValues.gugun ?? ""),
|
||||
statsYr: searchValues.year,
|
||||
statsCd,
|
||||
}
|
||||
@@ -912,12 +923,8 @@ const SeweragePenetrationRateInp = () => {
|
||||
queryContext={
|
||||
searchValues?.year && searchValues?.sido && searchValues?.bsnmCd && statsCd
|
||||
? {
|
||||
sewerBzmnCd: searchValues.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, searchValues),
|
||||
ctpvNm: searchValues.sido,
|
||||
sggNm:
|
||||
searchValues.gugun === "ALL"
|
||||
? ""
|
||||
: (searchValues.gugun ?? ""),
|
||||
statsYr: searchValues.year,
|
||||
statsCd,
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
||||
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
@@ -25,7 +25,16 @@ import type {
|
||||
cancelSubmitRequest,
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
resolveNoApplicableForRequest,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -45,7 +54,6 @@ import { VerificationResultDialog } from "@/components/module/VerificationResult
|
||||
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
|
||||
import type { ColumnConfig, ColumnInfo } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { ComplaintInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ComplaintInpColumn";
|
||||
import { ResidentFriendlyFactInpColumn } from "@/components/util/column/input/sewerageServiceLevel/ResidentFriendlyFactInpColumn";
|
||||
import { fetchColumnGuidesRecord } from "@/components/util/grid/columnGuides";
|
||||
@@ -120,10 +128,22 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildNoApplicableForRequest(
|
||||
values: SearchFormValues | null,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
return resolveNoApplicableForRequest(sidoListRef.current, values, checked, isSaveListEmpty);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -155,17 +175,16 @@ function buildSewerageServiceLevelSearchParam(
|
||||
): SewerageServiceLevelComplaintRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
function mapServiceLevelListToGridRows<
|
||||
T extends { verificationResult?: SewerageServiceLevelVerificationResult },
|
||||
>(list: T[], ctpvNm: string): GridRowWithVerification[] {
|
||||
return list.map((item) => {
|
||||
>(list: T[], ctpvNm: string, values?: SearchFormValues | null): GridRowWithVerification[] {
|
||||
return filterBySelectedAdmdstCd(list, sidoListRef.current, values).map((item) => {
|
||||
const { verificationResult, ...rest } = item;
|
||||
const row = toGridRows([{ ctpvNm, ...rest }])[0] as GridRowWithVerification;
|
||||
if (verificationResult) row.verificationResult = verificationResult;
|
||||
@@ -271,6 +290,8 @@ async function waitForImrJobCompleted(
|
||||
|
||||
// 하수도 통계 관리 > 13. 하수도 서비스 수준
|
||||
const SewerageServiceLevelInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
@@ -301,9 +322,12 @@ const SewerageServiceLevelInp = () => {
|
||||
const [footerVerificationByTab, setFooterVerificationByTab] = useState<
|
||||
Map<string, VerificationResultLikeMap | null>
|
||||
>(new Map());
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
Map<string, TabToolbarSnapshot>
|
||||
>(new Map());
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [columnGuidesByTab, setColumnGuidesByTab] = useState<
|
||||
Record<string, Record<string, string>>
|
||||
>({});
|
||||
@@ -366,6 +390,13 @@ const SewerageServiceLevelInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const applyRowMap = (
|
||||
@@ -407,6 +438,7 @@ const SewerageServiceLevelInp = () => {
|
||||
const gridRows = mapServiceLevelListToGridRows(
|
||||
(complaintList ?? []) as SewerageServiceLevelComplaintItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -439,6 +471,7 @@ const SewerageServiceLevelInp = () => {
|
||||
const gridRows = mapServiceLevelListToGridRows(
|
||||
(residentFriendlyFactList ?? []) as SewerageServiceLevelResidentFriendlyFactItem[],
|
||||
commonInfo.ctpvNm,
|
||||
searchContext,
|
||||
);
|
||||
if (!fromPreYear) {
|
||||
publicSewageFacilitiesAvailableRef.current = gridRows.length > 0;
|
||||
@@ -483,6 +516,7 @@ const SewerageServiceLevelInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setActiveTab(firstTabKey);
|
||||
activeTabRef.current = firstTabKey;
|
||||
setLastSearchedValues(null);
|
||||
@@ -529,6 +563,7 @@ const SewerageServiceLevelInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setIsNotApplicable(false);
|
||||
activeTabRef.current = firstTabKey;
|
||||
setActiveTab(firstTabKey);
|
||||
@@ -647,9 +682,19 @@ const SewerageServiceLevelInp = () => {
|
||||
const tabKey = activeTabRef.current;
|
||||
const isResidentTab = tabKey === ResidentFriendlyFactInpColumn.tabKey;
|
||||
const latestRows = getTabGridRows(tabKey);
|
||||
const noApplicable = isResidentTab && isNotApplicable;
|
||||
const noApplicable =
|
||||
isResidentTab &&
|
||||
buildNoApplicableForRequest(
|
||||
searchContextByTab.get(tabKey) ?? lastSearchedValues,
|
||||
isNotApplicable,
|
||||
latestRows.length === 0,
|
||||
);
|
||||
if (latestRows.length === 0) {
|
||||
if (isResidentTab && !noApplicable) {
|
||||
if (
|
||||
isResidentTab &&
|
||||
!noApplicable &&
|
||||
buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)
|
||||
) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -690,7 +735,13 @@ const SewerageServiceLevelInp = () => {
|
||||
return next;
|
||||
});
|
||||
|
||||
const noApplicable = isResidentTab && isNotApplicable;
|
||||
const noApplicable =
|
||||
isResidentTab &&
|
||||
buildNoApplicableForRequest(
|
||||
searchContextByTab.get(tabKey) ?? lastSearchedValues,
|
||||
isNotApplicable,
|
||||
latestRows.length === 0,
|
||||
);
|
||||
const complaintSubmitList = buildComplaintSaveList(latestRows);
|
||||
const residentSubmitList = noApplicable
|
||||
? []
|
||||
@@ -700,7 +751,12 @@ const SewerageServiceLevelInp = () => {
|
||||
alert("제출할 데이터가 없습니다.");
|
||||
return;
|
||||
}
|
||||
if (isResidentTab && !noApplicable && residentSubmitList.length === 0) {
|
||||
if (
|
||||
isResidentTab &&
|
||||
!noApplicable &&
|
||||
residentSubmitList.length === 0 &&
|
||||
buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)
|
||||
) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -715,11 +771,7 @@ const SewerageServiceLevelInp = () => {
|
||||
const submitInfoBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
|
||||
@@ -731,12 +783,8 @@ const SewerageServiceLevelInp = () => {
|
||||
};
|
||||
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
};
|
||||
@@ -784,7 +832,7 @@ const SewerageServiceLevelInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd: activeTabStatus?.laeSbmsnSttsCd === "4" ? "4" : "2",
|
||||
@@ -865,15 +913,17 @@ const SewerageServiceLevelInp = () => {
|
||||
return next;
|
||||
});
|
||||
|
||||
const noApplicable = isResidentTab && isNotApplicable;
|
||||
const noApplicable =
|
||||
isResidentTab &&
|
||||
buildNoApplicableForRequest(
|
||||
searchContextByTab.get(tabKey) ?? lastSearchedValues,
|
||||
isNotApplicable,
|
||||
latestRows.length === 0,
|
||||
);
|
||||
const baseRequest = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
};
|
||||
|
||||
try {
|
||||
@@ -903,7 +953,11 @@ const SewerageServiceLevelInp = () => {
|
||||
const saveList = noApplicable
|
||||
? []
|
||||
: buildResidentFriendlyFactSaveList(latestRows);
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (
|
||||
!noApplicable &&
|
||||
saveList.length === 0 &&
|
||||
buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)
|
||||
) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -963,12 +1017,8 @@ const SewerageServiceLevelInp = () => {
|
||||
}
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -1026,15 +1076,15 @@ const SewerageServiceLevelInp = () => {
|
||||
return map;
|
||||
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo, columnGuidesByTab]);
|
||||
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabRowData = rowDataMap.get(activeTab) ?? [];
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
hasSearched,
|
||||
lastSearchedValues,
|
||||
searchContextForToolbar,
|
||||
inputPeriodEnterable,
|
||||
isAdminInfo,
|
||||
);
|
||||
@@ -1045,12 +1095,14 @@ const SewerageServiceLevelInp = () => {
|
||||
activeTabToolbar.showEnterableToolbarButtons && toolbarGroupAllowed;
|
||||
const showActionToolbarCard =
|
||||
activeTabToolbar.showActionToolbarCard && toolbarGroupAllowed;
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
const showNotApplicableForResidentTab =
|
||||
activeTab === ResidentFriendlyFactInpColumn.tabKey &&
|
||||
searchLoaded &&
|
||||
hasSearched &&
|
||||
activeTabRowData.length === 0 &&
|
||||
computeTabEnterable(activeTabStatus, inputPeriodEnterable);
|
||||
computeTabEnterable(activeTabStatus, inputPeriodEnterable) &&
|
||||
submitOk;
|
||||
const showSecondaryToolbarCard =
|
||||
hasSearched &&
|
||||
toolbarGroupAllowed &&
|
||||
@@ -1061,9 +1113,8 @@ const SewerageServiceLevelInp = () => {
|
||||
const statsCd = tabStatsCdMap.get(activeTab);
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -1126,6 +1177,7 @@ const SewerageServiceLevelInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
onSubmit={handleSearch}
|
||||
@@ -1146,10 +1198,10 @@ const SewerageServiceLevelInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void getLastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
@@ -1197,7 +1249,7 @@ const SewerageServiceLevelInp = () => {
|
||||
tabStatusInfoMap.get(tabKey) ?? null,
|
||||
inputPeriodEnterable,
|
||||
) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const tabStatusInfo = tabStatusInfoMap.get(tabKey) ?? null;
|
||||
|
||||
return (
|
||||
|
||||
@@ -70,7 +70,7 @@ const StatisticsReviewHistory = () => {
|
||||
|
||||
return (
|
||||
<div className="relative">
|
||||
<SearchForm onSubmit={handleSearch} onReset={handleReset} />
|
||||
<SearchForm isInput onSubmit={handleSearch} onReset={handleReset} />
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
|
||||
<div className="relative size-[5rem]">
|
||||
|
||||
@@ -4,7 +4,7 @@ import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { RealGridReact } from "realgrid-react";
|
||||
import useSWR, { useSWRConfig } from "swr";
|
||||
|
||||
import { useActiveTabRegAuthorityAllowed, useAlertStore } from "@/shared/lib";
|
||||
import { useActiveTabRegAuthorityAllowed, useAlertStore, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { statisticsInputSewSupplyRateApi } from "@/entities/statistics/api/input/statistics-input-sew-supply-rate-service";
|
||||
import { StatisticsInputStatusApi } from "@/entities/statistics/api/input/statistics-input-status-service";
|
||||
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
isInputPeriodCurrent,
|
||||
} from "@/entities/statistics/model/input/statistics-sewage-supply-rate-input-interface";
|
||||
import type { StatsInputStatusApproveItem } from "@/entities/statistics/model/statistics-interface";
|
||||
import { isGugunOkForToolbar } from "@/entities/statistics";
|
||||
import { LoadingWithAnimation } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -30,7 +31,6 @@ import {
|
||||
import SearchForm from "@/components/module/SearchForm";
|
||||
import type { DataCellClickCallbackParams } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { StatsInputStatusInpColumn } from "@/components/util/column/input/StatsInputStatusInpColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
import { useTabStore } from "@/store/tab-store";
|
||||
@@ -44,6 +44,7 @@ const getStatsInputStatusFetcher = async (
|
||||
// 하수도 통계 관리 > 00. 통계 입력 현황
|
||||
const StatsInputStatusInp = () => {
|
||||
|
||||
const { sidoList } = useSearchConditionSidoList();
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const activeTabId = useTabStore((state) => state.activeTabId);
|
||||
@@ -254,9 +255,7 @@ const StatsInputStatusInp = () => {
|
||||
await mutate(["stats-input-status", searchParams]);
|
||||
}, [mutate, searchParams]);
|
||||
|
||||
const gugunOkOrNotDoList = doList.includes(lastSearchedValues?.bsnmCd || "")
|
||||
? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== "ALL")
|
||||
: true;
|
||||
const gugunOkOrNotDoList = isGugunOkForToolbar(sidoList, lastSearchedValues);
|
||||
|
||||
const allRowsLaeSbmsnApproved = useMemo(
|
||||
() =>
|
||||
|
||||
@@ -13,7 +13,7 @@ import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { ValueType } from "realgrid";
|
||||
import type { RealGridReact } from "realgrid-react";
|
||||
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate } from "@/shared/lib";
|
||||
import { useAlertStore, useGlobalProgressStore, useStatisticsInputToolbarGroupGate, useSearchConditionSidoList } from "@/shared/lib";
|
||||
import { STATISTICS_INPUT_URL_PATH } from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useStatisticsInputPendingNavigation } from "@/shared/lib/use-statistics-input-pending-navigation";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
@@ -48,7 +48,16 @@ import type {
|
||||
ImrStatusResponse,
|
||||
SewerageStatusInfo,
|
||||
Sgg,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import {
|
||||
filterBySelectedAdmdstCd,
|
||||
isGugunOkForToolbar,
|
||||
isSubmitOkForToolbar,
|
||||
resolveNoApplicableForRequest,
|
||||
toInputSearchRegion,
|
||||
} from "@/entities/statistics";
|
||||
|
||||
import { LoadingWithAnimation, Tabs, TabsContent, TabsList, TabsTrigger } from "@common/components";
|
||||
|
||||
import { getUserInfo } from "../../../../../../packages/common/components/src/api";
|
||||
@@ -71,7 +80,6 @@ import { VerificationResultDialog } from "@/components/module/VerificationResult
|
||||
import { VerificationResultHistoryDialog } from "@/components/module/VerificationResultHistoryDialog";
|
||||
import type { ColumnConfig, ColumnInfo } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { PublicSewageTreatWaterReuseInpColumn } from "@/components/util/column/input/waterReuse/PublicSewageTreatWaterReuseInpColumn";
|
||||
import { RainFallUtilFactStatusInpColumn } from "@/components/util/column/input/waterReuse/RainFallUtilFactStatusInpColumn";
|
||||
import { RecycledWaterStatusInpColumn } from "@/components/util/column/input/waterReuse/RecycledWaterStatusInpColumn";
|
||||
@@ -159,10 +167,22 @@ const computeTabEnterable = (
|
||||
return periodEnterable;
|
||||
};
|
||||
|
||||
const sidoListRef: { current: Sido[] } = { current: [] };
|
||||
|
||||
function buildGugunOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return doList.includes(values?.bsnmCd || "")
|
||||
? Boolean(values?.gugun && values.gugun !== "ALL")
|
||||
: true;
|
||||
return isGugunOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildSubmitOkForToolbar(values: SearchFormValues | null): boolean {
|
||||
return isSubmitOkForToolbar(sidoListRef.current, values);
|
||||
}
|
||||
|
||||
function buildNoApplicableForRequest(
|
||||
values: SearchFormValues | null,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
return resolveNoApplicableForRequest(sidoListRef.current, values, checked, isSaveListEmpty);
|
||||
}
|
||||
|
||||
function computeTabToolbarSnapshot(
|
||||
@@ -194,9 +214,8 @@ function buildWaterReuseSearchParam(
|
||||
): WaterReuseRequestParams {
|
||||
return {
|
||||
statsYr: values.year,
|
||||
sewerBzmnCd: values.bsnmCd,
|
||||
ctpvNm: values.sido,
|
||||
sggNm: values.gugun === "ALL" ? "" : values.gugun,
|
||||
...toInputSearchRegion(sidoListRef.current, values),
|
||||
...(overrides?.mode ? { mode: overrides.mode } : {}),
|
||||
};
|
||||
}
|
||||
@@ -510,6 +529,8 @@ async function waitForImrJobCompleted(
|
||||
|
||||
// 하수도 통계 관리 > 10. 물 재이용
|
||||
const WaterReuseInp = () => {
|
||||
const { sidoList } = useSearchConditionSidoList({ isInput: true });
|
||||
sidoListRef.current = sidoList;
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const { confirm } = useConfirm();
|
||||
const { isAdminInfo } = useAdminStore();
|
||||
@@ -541,9 +562,12 @@ const WaterReuseInp = () => {
|
||||
const [footerVerificationByTab, setFooterVerificationByTab] = useState<
|
||||
Map<string, VerificationResultLikeMap | null>
|
||||
>(new Map());
|
||||
const [toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
const [_toolbarSnapshotByTab, setToolbarSnapshotByTab] = useState<
|
||||
Map<string, TabToolbarSnapshot>
|
||||
>(new Map());
|
||||
const [searchContextByTab, setSearchContextByTab] = useState<Map<string, SearchFormValues>>(
|
||||
() => new Map(),
|
||||
);
|
||||
const [columnGuidesByTab, setColumnGuidesByTab] = useState<
|
||||
Record<string, Record<string, string>>
|
||||
>({});
|
||||
@@ -644,6 +668,13 @@ const WaterReuseInp = () => {
|
||||
);
|
||||
return next;
|
||||
});
|
||||
if (searchContext) {
|
||||
setSearchContextByTab((prev) => {
|
||||
const next = new Map(prev);
|
||||
next.set(tabKey, searchContext);
|
||||
return next;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const applyRowMap = (
|
||||
@@ -673,6 +704,8 @@ const WaterReuseInp = () => {
|
||||
): Promise<boolean> => {
|
||||
const requestParam = overrides?.mode ? { ...param, mode: overrides.mode } : param;
|
||||
const fromPreYear = overrides?.mode === "PRE";
|
||||
const filterFetched = <T,>(list: T[] | undefined) =>
|
||||
filterBySelectedAdmdstCd(list, sidoListRef.current, searchContext);
|
||||
|
||||
const applyNotApplicableForLoadedTab = (
|
||||
gridRows: readonly Record<string, string | number>[],
|
||||
@@ -704,7 +737,7 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
const { commonInfo, statusInfo, publicSewageTreatWaterReuseList } = response.data;
|
||||
const gridRows = mapPublicSewageTreatWaterReuseListToGridRows(
|
||||
(publicSewageTreatWaterReuseList ?? []) as PublicSewageTreatWaterReuseItem[],
|
||||
filterFetched(publicSewageTreatWaterReuseList) as PublicSewageTreatWaterReuseItem[],
|
||||
commonInfo.ctpvNm,
|
||||
);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -735,7 +768,7 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
const { commonInfo, statusInfo, recycledWaterList } = response.data;
|
||||
const gridRows = mapRecycledWaterStatusListToGridRows(
|
||||
(recycledWaterList ?? []) as RecycledWaterStatusItem[],
|
||||
filterFetched(recycledWaterList) as RecycledWaterStatusItem[],
|
||||
commonInfo.ctpvNm,
|
||||
);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -766,7 +799,7 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
const { commonInfo, statusInfo, rainFallUtilFactStatusList } = response.data;
|
||||
const gridRows = mapRainFallUtilFactStatusListToGridRows(
|
||||
(rainFallUtilFactStatusList ?? []) as RainFallUtilFactStatusItem[],
|
||||
filterFetched(rainFallUtilFactStatusList) as RainFallUtilFactStatusItem[],
|
||||
commonInfo.ctpvNm,
|
||||
);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -798,8 +831,7 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
const { commonInfo, statusInfo, treatWaterReuseDesignConstStatusList } = response.data;
|
||||
const gridRows = mapTreatWaterReuseStatusListToGridRows(
|
||||
(treatWaterReuseDesignConstStatusList ??
|
||||
[]) as TreatWaterReuseDesignConstStatusItem[],
|
||||
filterFetched(treatWaterReuseDesignConstStatusList) as TreatWaterReuseDesignConstStatusItem[],
|
||||
commonInfo.ctpvNm,
|
||||
);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -832,8 +864,7 @@ const WaterReuseInp = () => {
|
||||
const { commonInfo, statusInfo, treatWaterReuseBusinessApprStatusList } =
|
||||
response.data;
|
||||
const gridRows = mapTreatWaterReuseStatusListToGridRows(
|
||||
(treatWaterReuseBusinessApprStatusList ??
|
||||
[]) as TreatWaterReuseBusinessApprStatusItem[],
|
||||
filterFetched(treatWaterReuseBusinessApprStatusList) as TreatWaterReuseBusinessApprStatusItem[],
|
||||
commonInfo.ctpvNm,
|
||||
);
|
||||
applyRowMap(mergeIntoExistingMap, (m) => {
|
||||
@@ -906,6 +937,7 @@ const WaterReuseInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setActiveTab(firstTabKey);
|
||||
activeTabRef.current = firstTabKey;
|
||||
setLastSearchedValues(null);
|
||||
@@ -954,6 +986,7 @@ const WaterReuseInp = () => {
|
||||
setIsVerificationFailedByTab(new Map());
|
||||
setFooterVerificationByTab(new Map());
|
||||
setToolbarSnapshotByTab(new Map());
|
||||
setSearchContextByTab(new Map());
|
||||
setDeleteListByTab(new Map());
|
||||
loadedTabKeysRef.current.clear();
|
||||
activeTabRef.current = firstTabKey;
|
||||
@@ -1076,9 +1109,9 @@ const WaterReuseInp = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
if (!noApplicable && currentData.length === 0) {
|
||||
if (!noApplicable && currentData.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1111,11 +1144,7 @@ const WaterReuseInp = () => {
|
||||
const submitRequestBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
laePicNm: submitInfo.laePicNm,
|
||||
laePicTelNo: submitInfo.laePicTelNo,
|
||||
laeKbrdrDeptNm: submitInfo.laeKbrdrDeptNm,
|
||||
@@ -1135,12 +1164,8 @@ const WaterReuseInp = () => {
|
||||
WATER_REUSE_COLUMN_GUIDE_STATS_CD_BY_TAB_KEY[tabKey] ??
|
||||
tabKey;
|
||||
const verificationQuery = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
statsCd: statsCdForTab,
|
||||
};
|
||||
@@ -1174,12 +1199,12 @@ const WaterReuseInp = () => {
|
||||
};
|
||||
|
||||
if (isPublicSewageTab) {
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
const submitList = noApplicable
|
||||
? []
|
||||
: currentData.map(buildPublicSewageTreatWaterReuseSaveItem);
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1191,7 +1216,7 @@ const WaterReuseInp = () => {
|
||||
submitList,
|
||||
});
|
||||
} else {
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
|
||||
const sido = lastSearchedValues.sido ?? "";
|
||||
@@ -1222,7 +1247,7 @@ const WaterReuseInp = () => {
|
||||
.filter((row) => isPersistedArticleRow(tabKey, row))
|
||||
.map((row) => buildRecycledWaterStatusSaveItem(row, list));
|
||||
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1242,7 +1267,7 @@ const WaterReuseInp = () => {
|
||||
.filter((row) => isPersistedArticleRow(tabKey, row))
|
||||
.map((row) => buildRainFallUtilFactStatusSaveItem(row, list));
|
||||
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1264,7 +1289,7 @@ const WaterReuseInp = () => {
|
||||
buildTreatWaterReuseDesignConstStatusSaveItem(row, list),
|
||||
);
|
||||
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1289,7 +1314,7 @@ const WaterReuseInp = () => {
|
||||
buildTreatWaterReuseBusinessApprStatusSaveItem(row, list),
|
||||
);
|
||||
|
||||
if (!noApplicable && submitList.length === 0) {
|
||||
if (!noApplicable && submitList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1321,7 +1346,7 @@ const WaterReuseInp = () => {
|
||||
setGlobalProgressLabel("시계열 검증 진행 중...");
|
||||
const imrParam = {
|
||||
user_id: userInfo.userUnqId,
|
||||
sewer_bzmn_cd: lastSearchedValues.bsnmCd ?? "",
|
||||
sewer_bzmn_cd: lastSearchedValues?.bsnmCd ?? "",
|
||||
stats_cd: statsCdForTab,
|
||||
stats_yr: lastSearchedValues.year ?? "",
|
||||
lae_sbmsn_stts_cd:
|
||||
@@ -1396,11 +1421,7 @@ const WaterReuseInp = () => {
|
||||
const requestBase = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
...(isAdminInfo ? { superAdmin: "superAdmin" } : {}),
|
||||
};
|
||||
|
||||
@@ -1418,12 +1439,12 @@ const WaterReuseInp = () => {
|
||||
};
|
||||
|
||||
if (tabKey === PublicSewageTreatWaterReuseInpColumn.tabKey) {
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
const saveList = noApplicable
|
||||
? []
|
||||
: currentData.map(buildPublicSewageTreatWaterReuseSaveItem);
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1454,7 +1475,7 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
|
||||
if (tabKey === RecycledWaterStatusInpColumn.tabKey) {
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
|
||||
const sido = lastSearchedValues.sido ?? "";
|
||||
@@ -1477,7 +1498,7 @@ const WaterReuseInp = () => {
|
||||
.filter((row) => isPersistedArticleRow(tabKey, row))
|
||||
.map((row) => buildRecycledWaterStatusSaveItem(row, list));
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1514,7 +1535,7 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
|
||||
if (tabKey === RainFallUtilFactStatusInpColumn.tabKey) {
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
|
||||
const sido = lastSearchedValues.sido ?? "";
|
||||
@@ -1537,7 +1558,7 @@ const WaterReuseInp = () => {
|
||||
.filter((row) => isPersistedArticleRow(tabKey, row))
|
||||
.map((row) => buildRainFallUtilFactStatusSaveItem(row, list));
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1575,7 +1596,7 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
|
||||
if (tabKey === TreatWaterReuseDesignConstStatusInpColumn.tabKey) {
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
|
||||
const sido = lastSearchedValues.sido ?? "";
|
||||
@@ -1600,7 +1621,7 @@ const WaterReuseInp = () => {
|
||||
buildTreatWaterReuseDesignConstStatusSaveItem(row, list),
|
||||
);
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1640,7 +1661,7 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
|
||||
if (tabKey === TreatWaterReuseBusinessApprStatusInpColumn.tabKey) {
|
||||
const noApplicable = isNotApplicableByTab.get(tabKey) ?? false;
|
||||
const noApplicable = buildNoApplicableForRequest(searchContextByTab.get(tabKey) ?? lastSearchedValues, isNotApplicableByTab.get(tabKey) ?? false, getTabGridRows(tabKey).length === 0);
|
||||
const currentData = getTabGridRows(tabKey);
|
||||
|
||||
const sido = lastSearchedValues.sido ?? "";
|
||||
@@ -1665,7 +1686,7 @@ const WaterReuseInp = () => {
|
||||
buildTreatWaterReuseBusinessApprStatusSaveItem(row, list),
|
||||
);
|
||||
|
||||
if (!noApplicable && saveList.length === 0) {
|
||||
if (!noApplicable && saveList.length === 0 && buildSubmitOkForToolbar(searchContextByTab.get(tabKey) ?? lastSearchedValues)) {
|
||||
alert("해당사항 없음을 체크해주세요.");
|
||||
return;
|
||||
}
|
||||
@@ -1719,11 +1740,7 @@ const WaterReuseInp = () => {
|
||||
const request = {
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
userId: userInfo.userUnqId,
|
||||
};
|
||||
|
||||
@@ -1881,12 +1898,8 @@ const WaterReuseInp = () => {
|
||||
}
|
||||
|
||||
const requestData: cancelSubmitRequest = {
|
||||
sewerBzmnCd: lastSearchedValues.bsnmCd ?? "",
|
||||
...toInputSearchRegion(sidoListRef.current, lastSearchedValues),
|
||||
ctpvNm: lastSearchedValues.sido ?? "",
|
||||
sggNm:
|
||||
lastSearchedValues.gugun === "ALL"
|
||||
? ""
|
||||
: (lastSearchedValues.gugun ?? ""),
|
||||
statsYr: lastSearchedValues.year ?? "",
|
||||
mdfrId: userInfo.userUnqId,
|
||||
statsCd: statsCdForTab,
|
||||
@@ -1963,14 +1976,14 @@ const WaterReuseInp = () => {
|
||||
return map;
|
||||
}, [tabStatusInfoMap, inputPeriodEnterable, isAdminInfo, columnGuidesByTab, sggOptions]);
|
||||
|
||||
const searchContextForToolbar = searchContextByTab.get(activeTab) ?? lastSearchedValues;
|
||||
const activeTabStatus = tabStatusInfoMap.get(activeTab) ?? null;
|
||||
const activeTabToolbar =
|
||||
toolbarSnapshotByTab.get(activeTab) ??
|
||||
computeTabToolbarSnapshot(
|
||||
activeTabStatus,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
hasSearched,
|
||||
lastSearchedValues,
|
||||
searchContextForToolbar,
|
||||
inputPeriodEnterable,
|
||||
isAdminInfo,
|
||||
);
|
||||
@@ -1981,6 +1994,7 @@ const WaterReuseInp = () => {
|
||||
activeTabToolbar.showEnterableToolbarButtons && toolbarGroupAllowed;
|
||||
const showActionToolbarCard =
|
||||
activeTabToolbar.showActionToolbarCard && toolbarGroupAllowed;
|
||||
const submitOk = buildSubmitOkForToolbar(searchContextForToolbar);
|
||||
const showSecondaryToolbarCard =
|
||||
hasSearched &&
|
||||
toolbarGroupAllowed &&
|
||||
@@ -1995,7 +2009,8 @@ const WaterReuseInp = () => {
|
||||
activeTab,
|
||||
tabRowDataExists(rowDataMap, activeTab),
|
||||
activeTabStatus,
|
||||
);
|
||||
) &&
|
||||
submitOk;
|
||||
const setIsNotApplicableForActiveTab: Dispatch<SetStateAction<boolean>> = useCallback(
|
||||
(next) => {
|
||||
const tabKey = activeTabRef.current;
|
||||
@@ -2014,9 +2029,8 @@ const WaterReuseInp = () => {
|
||||
const statsCd = tabStatsCdMap.get(activeTab);
|
||||
if (!ctx?.year || !ctx?.sido || !ctx?.bsnmCd || !statsCd) return null;
|
||||
return {
|
||||
sewerBzmnCd: ctx.bsnmCd,
|
||||
...toInputSearchRegion(sidoListRef.current, ctx),
|
||||
ctpvNm: ctx.sido,
|
||||
sggNm: ctx.gugun === "ALL" ? "" : (ctx.gugun ?? ""),
|
||||
statsYr: ctx.year,
|
||||
statsCd,
|
||||
};
|
||||
@@ -2079,6 +2093,7 @@ const WaterReuseInp = () => {
|
||||
<>
|
||||
<div className="relative">
|
||||
<SearchForm
|
||||
isInput
|
||||
key={searchFormRemountKey}
|
||||
defaultValues={verificationSearchDefaults ?? undefined}
|
||||
onSubmit={handleSearch}
|
||||
@@ -2099,10 +2114,10 @@ const WaterReuseInp = () => {
|
||||
<LastYearDataButton
|
||||
getLastYearDataFunc={() => void getLastYearDataFunc()}
|
||||
/>
|
||||
<SubmitButton submitFunc={submitFunc} />
|
||||
{submitOk && <SubmitButton submitFunc={submitFunc} />}
|
||||
</>
|
||||
)}
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && (
|
||||
{activeTabStatus?.laeSbmsnSttsCd === "2" && submitOk && (
|
||||
<CancelSubmitButton cnacelSubmitFunc={cnacelSubmitFunc} />
|
||||
)}
|
||||
{showSaveInToolbar && <SaveButton saveFunc={saveFunc} />}
|
||||
@@ -2161,7 +2176,7 @@ const WaterReuseInp = () => {
|
||||
tabStatusInfoMap.get(tabKey) ?? null,
|
||||
inputPeriodEnterable,
|
||||
) || isAdminInfo) && inputPeriodEnterable;
|
||||
const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
|
||||
const gugunOk = buildGugunOkForToolbar(searchContextForToolbar);
|
||||
const tabStatusInfo = tabStatusInfoMap.get(tabKey) ?? null;
|
||||
|
||||
return (
|
||||
|
||||
@@ -130,9 +130,9 @@ const getSidoListFetcher = async (): Promise<ApiResponse<SearchCondition>> => {
|
||||
};
|
||||
|
||||
const getSggListFetcher = async (
|
||||
key: [string, string],
|
||||
key: [string, string, "Y" | "N"],
|
||||
): Promise<ApiResponse<Sgg[]>> => {
|
||||
return statisticsApi.getSggList(key[1]);
|
||||
return statisticsApi.getSggList(key[1], { gugunSkipYn: key[2] });
|
||||
};
|
||||
|
||||
const LogHistory = () => {
|
||||
@@ -214,8 +214,14 @@ const LogHistory = () => {
|
||||
},
|
||||
);
|
||||
|
||||
const sggKey: [string, string] | null =
|
||||
sido && sido !== "ALL" ? ["log-history-sgg-list", sido] : null;
|
||||
const selectedSido = sidoList?.data?.sidoList?.find(
|
||||
(item) => item.sido === sido,
|
||||
);
|
||||
const gugunSkipYn = selectedSido?.gugunSkipYn ?? "Y";
|
||||
const sggKey: [string, string, "Y" | "N"] | null =
|
||||
sido && sido !== "ALL" && sidoList?.data
|
||||
? ["log-history-sgg-list", sido, gugunSkipYn]
|
||||
: null;
|
||||
const { data: sggList } = useSWR<ApiResponse<Sgg[]>>(
|
||||
sggKey,
|
||||
getSggListFetcher,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { useCallback, useMemo, useState } from "react";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { createColumnHelper, getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
||||
|
||||
import { useAlertStore, useUserStore } from "@/shared/lib";
|
||||
import { useAlertStore, useSearchConditionSidoList, useUserStore } from "@/shared/lib";
|
||||
import { statisticsManagementApi } from "@/entities/statistics/api/statistics-management-service";
|
||||
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
import type {
|
||||
@@ -14,6 +14,7 @@ import type {
|
||||
ReviewerInfoRequest,
|
||||
StatsInputStatusApproveItem,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import { isGugunOkForToolbar } from "@/entities/statistics";
|
||||
import {
|
||||
Button,
|
||||
DataTable,
|
||||
@@ -33,7 +34,6 @@ import SearchForm from "@/components/module/SearchForm";
|
||||
import { ReviewSubmitDialog } from "@/components/statistics/review/ReviewSubmitDialog";
|
||||
import type { DataCellClickCallbackParams } from "@/components/type/DataGrid.type";
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusRvwColumn";
|
||||
import { toGridRows } from "@/components/util/grid/gridFunction";
|
||||
|
||||
@@ -60,6 +60,7 @@ const mapSewerageListToGridRows = (rawList: StatsInputStatusReviewItem[]) =>
|
||||
|
||||
// 하수도 통계 검토 00. 통계 입력 현황
|
||||
const StatsInputStatusRvw = () => {
|
||||
const { sidoList } = useSearchConditionSidoList();
|
||||
const { setMessage: alert } = useAlertStore((state) => state);
|
||||
const userInfo = useUserStore((state) => state.userInfo);
|
||||
const { confirm } = useConfirm();
|
||||
@@ -232,9 +233,7 @@ const StatsInputStatusRvw = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const gugunOkOrNotDoList = doList.includes(lastSearchedValues?.bsnmCd || "")
|
||||
? Boolean(lastSearchedValues?.gugun && lastSearchedValues.gugun !== "ALL")
|
||||
: true;
|
||||
const gugunOkOrNotDoList = isGugunOkForToolbar(sidoList, lastSearchedValues);
|
||||
|
||||
const allSubmitStatusApproved = useMemo(
|
||||
() =>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
|
||||
import * as XLSX from "xlsx";
|
||||
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { NoData } from "@/shared/ui/no-data";
|
||||
@@ -43,6 +44,7 @@ const GeneralVerificationManagement = () => {
|
||||
{},
|
||||
);
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
const [isExporting, setIsExporting] = useState<boolean>(false);
|
||||
const [selectedVrfcRow, setSelectedVrfcRow] = useState<number | null>(null);
|
||||
const [showRegistForm, setShowRegistForm] = useState<boolean>(false);
|
||||
|
||||
@@ -108,6 +110,47 @@ const GeneralVerificationManagement = () => {
|
||||
setShowRegistForm(false);
|
||||
};
|
||||
|
||||
const handleExportExcel = async () => {
|
||||
try {
|
||||
setIsExporting(true);
|
||||
const response = await generalverificationApiService.getVerifyExcelList();
|
||||
if (response.status !== "success") {
|
||||
alert(response.message || "엑셀 데이터 조회 중 오류가 발생했습니다.");
|
||||
return;
|
||||
}
|
||||
const list = response.data ?? [];
|
||||
if (list.length === 0) {
|
||||
alert("내보낼 데이터가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
const header = [
|
||||
"지표명",
|
||||
"검증명",
|
||||
"검증타입",
|
||||
"소수점 자리수",
|
||||
"소수점 자리 처리 방식",
|
||||
"검증식",
|
||||
];
|
||||
const rows = list.map((item) => [
|
||||
item.trgtStatsNm,
|
||||
item.vrfcNm,
|
||||
item.vrfcClsfNm,
|
||||
item.dcptDigtCnt,
|
||||
item.dcptPrcsMthNm,
|
||||
item.vrfcEqtnCn,
|
||||
]);
|
||||
const worksheet = XLSX.utils.aoa_to_sheet([header, ...rows]);
|
||||
const workbook = XLSX.utils.book_new();
|
||||
XLSX.utils.book_append_sheet(workbook, worksheet, "일반검증목록");
|
||||
XLSX.writeFile(workbook, "일반검증목록.xlsx");
|
||||
} catch {
|
||||
alert("엑셀 내보내기 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
setIsExporting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
const resetValues = { statsCd: "", useYn: "", vrfcClsfCd: "" };
|
||||
setSearchValues(resetValues);
|
||||
@@ -210,16 +253,27 @@ const GeneralVerificationManagement = () => {
|
||||
<h3 className="text-2xl font-medium text-label">
|
||||
일반 검증 목록
|
||||
</h3>
|
||||
<RegistDialog
|
||||
open={showRegistForm}
|
||||
onOpenChange={setShowRegistForm}
|
||||
onSuccess={() => void handleSearch()}
|
||||
>
|
||||
<Button>등록</Button>
|
||||
</RegistDialog>
|
||||
<div className="flex items-center gap-2">
|
||||
<Button
|
||||
className="h-[3.2rem] w-[96px] bg-gradient-green px-6 hover:bg-gradient-green-hover"
|
||||
type="button"
|
||||
disabled={isExporting}
|
||||
onClick={() => void handleExportExcel()}
|
||||
>
|
||||
<i className="diveicon di-file-excel" />
|
||||
<span>내보내기</span>
|
||||
</Button>
|
||||
<RegistDialog
|
||||
open={showRegistForm}
|
||||
onOpenChange={setShowRegistForm}
|
||||
onSuccess={() => void handleSearch()}
|
||||
>
|
||||
<Button>등록</Button>
|
||||
</RegistDialog>
|
||||
</div>
|
||||
</div>
|
||||
<div className="card !mx-2 !my-4 h-full overflow-auto !p-0">
|
||||
{isLoading && (
|
||||
{(isLoading || isExporting) && (
|
||||
<div className="[data-theme='black']:bg-transparent absolute inset-0 z-50 flex items-center justify-center rounded-lg p-10">
|
||||
<div className="relative size-[5rem]">
|
||||
<LoadingWithAnimation color="primary" />
|
||||
|
||||
@@ -36,10 +36,12 @@ export type SearchFormProps = {
|
||||
isReset?: boolean;
|
||||
/** true면 시도·시군구 기본값을 계정 첫 항목이 아니라 「전체」로 둠 (집계표 등) */
|
||||
defaultRegionAll?: boolean;
|
||||
/** true면 입력 화면용 시도 목록 API(`getSidoListInput`)를 사용 */
|
||||
isInput?: boolean;
|
||||
};
|
||||
|
||||
export const defaultSearchFormProps: Required<
|
||||
Omit<SearchFormProps, "onSubmit" | "onReset" | "onValuesChange" | "defaultValues" | "sidoSelectText" | "searchButtonText" | "defaultRegionAll">
|
||||
Omit<SearchFormProps, "onSubmit" | "onReset" | "onValuesChange" | "defaultValues" | "sidoSelectText" | "searchButtonText" | "defaultRegionAll" | "isInput">
|
||||
> = {
|
||||
sido: true,
|
||||
gugun: true,
|
||||
|
||||
@@ -42,15 +42,15 @@ export const ExcretaTreatFactInpColumn = {
|
||||
},
|
||||
|
||||
// 사업비/용량 정보
|
||||
{ name: 'wholPjtcoAmt', fieldName: 'wholPjtcoAmt', header: { text: '사업비(백만원)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '시설용량(m³/일)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'wholPjtcoAmt', fieldName: 'wholPjtcoAmt', header: { text: '사업비(백만원)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '시설용량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'cpct', fieldName: 'cpct', header: { text: '처리량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'oprtngDayCnt', fieldName: 'oprtngDayCnt', header: { text: '가동일수(일/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 처리 공법 및 연계
|
||||
{ name: 'prcsMthdExpln', fieldName: 'prcsMthdExpln', header: { text: '처리공법' } },
|
||||
{ name: 'linkTmplntCn', fieldName: 'linkTmplntCn', header: { text: '연계처리장명' } },
|
||||
{ name: 'linkPrcsQnt', fieldName: 'linkPrcsQnt', header: { text: '연계처리량(m³/일)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'linkPrcsQnt', fieldName: 'linkPrcsQnt', header: { text: '연계처리량(m³/일)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 유입수질
|
||||
{ name: 'inflwBodWqVl', fieldName: 'inflwBodWqVl', header: { text: 'BOD' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
@@ -77,7 +77,7 @@ export const ExcretaTreatFactInpColumn = {
|
||||
// 운영 정보
|
||||
{ name: 'operMthdCdCn', fieldName: 'operMthdCdCn', header: { text: '운영주체(자체/공기업/민간위탁)' } },
|
||||
{ name: 'wholNope', fieldName: 'wholNope', header: { text: '직원총수(명)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수(건/인/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수(건/인/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 비고
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
|
||||
+4
-3
@@ -1,6 +1,6 @@
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
import { footerDecimal1, footerDecimal3,footerInt } from "@/components/util/grid/footerSummary";
|
||||
import { footerAvgDecimal, footerDecimal1, footerDecimal3, footerInt } from "@/components/util/grid/footerSummary";
|
||||
|
||||
/**
|
||||
* 하수도 통계 관리 > 06. 공공하수처리시설
|
||||
@@ -97,7 +97,7 @@ export const PublicSewageFactColumn = {
|
||||
{ name: 'telNo', fieldName: 'telNo', header: { text: '전화번호' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'cmptnStrtYmd', fieldName: 'cmptnStrtYmd', header: { text: '준공일' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'oprtngStrtYmd', fieldName: 'oprtngStrtYmd', header: { text: '가동개시일' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'wholBizVl', fieldName: 'wholBizVl', header: { text: '사업비' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
|
||||
{ name: 'wholBizVl', fieldName: 'wholBizVl', header: { text: '사업비' }, editable: false, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0', styleName: 'rg-cell-readonly' },
|
||||
|
||||
// 방류수 소독방법
|
||||
{ name: 'eflntDsnfMthdExpln', fieldName: 'eflntDsnfMthdExpln', header: { text: '방류수 소독방법' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
@@ -118,6 +118,7 @@ export const PublicSewageFactColumn = {
|
||||
fieldName: 'engySrlneRt',
|
||||
header: { text: '에너지자립률(%)' },
|
||||
editable: false,
|
||||
footer: footerAvgDecimal,
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.0',
|
||||
styleName: 'rg-cell-total',
|
||||
@@ -163,7 +164,7 @@ export const PublicSewageFactColumn = {
|
||||
// 기타
|
||||
{ name: 'intgPrcsFcltCn', fieldName: 'intgPrcsFcltCn', header: { text: '중심처리시설' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'wholNope', fieldName: 'wholNope', header: { text: '직원총수(명)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0', styleName: 'rg-cell-readonly' },
|
||||
{ name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'sftyAcdntEvntcsCnt', fieldName: 'sftyAcdntEvntcsCnt', header: { text: '안전사고건수' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
{ name: 'admdstCd', fieldName: 'admdstCd', header: { text: '행정구역코드' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, visible: false, editable: false, styleName: 'rg-cell-readonly' },
|
||||
|
||||
+6
-6
@@ -1,6 +1,6 @@
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
import { footerDecimal1 } from "@/components/util/grid/footerSummary";
|
||||
import { footerAvgDecimal, footerDecimal1 } from "@/components/util/grid/footerSummary";
|
||||
|
||||
// 하수도 통계 관리 > 11. 하수 및 분뇨찌꺼기(슬러지)처리 > tab 1: 찌꺼기(슬러지)처리시설현황
|
||||
export const SlurgeProcessingFacStatusInpColumn = {
|
||||
@@ -37,7 +37,7 @@ export const SlurgeProcessingFacStatusInpColumn = {
|
||||
{ name: 'transfPrcsQnt', fieldName: 'transfPrcsQnt', header: { text: '이송처리량(m³/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 함수율
|
||||
{ name: 'srpFncRt', fieldName: 'srpFncRt', header: { text: '함수율(%, 탈수기준)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'srpFncRt', fieldName: 'srpFncRt', header: { text: '함수율(%, 탈수기준)' }, footer: footerAvgDecimal, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 찌꺼기처리량합계
|
||||
{
|
||||
@@ -56,7 +56,7 @@ export const SlurgeProcessingFacStatusInpColumn = {
|
||||
'itslfTs1AltdQnt',
|
||||
'itslfTs1DryQnt',
|
||||
'itslfTs1FuelQnt',
|
||||
'itslfTs2CmpstgQnt',
|
||||
'itslfTs1CmpstgQnt',
|
||||
'otsdCnsgnRclmQnt',
|
||||
'otsdCnsgnIncnrQnt',
|
||||
'otsdCnsgnFuelPwplQnt',
|
||||
@@ -86,7 +86,7 @@ export const SlurgeProcessingFacStatusInpColumn = {
|
||||
'itslfTs1AltdQnt',
|
||||
'itslfTs1DryQnt',
|
||||
'itslfTs1FuelQnt',
|
||||
'itslfTs2CmpstgQnt',
|
||||
'itslfTs1CmpstgQnt',
|
||||
],
|
||||
type: 'sum' as const,
|
||||
}
|
||||
@@ -203,7 +203,7 @@ export const SlurgeProcessingFacStatusInpColumn = {
|
||||
{ name: 'fuelPrcsFcltNm', fieldName: 'fuelPrcsFcltNm', header: { text: '시설(업체명)' } },
|
||||
|
||||
// 자체 찌꺼기 처리량 > 퇴비화 - 쿼리에 없음 (임의 생성)
|
||||
{ name: 'itslfTs2CmpstgQnt', fieldName: 'itslfTs2CmpstgQnt', header: { text: '퇴비화' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'itslfTs1CmpstgQnt', fieldName: 'itslfTs1CmpstgQnt', header: { text: '퇴비화' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 자체 찌꺼기 처리량 > 퇴비화 > 시설(업체명) - 쿼리에 없음 (임의 생성)
|
||||
{ name: 'cmpsPrcsFcltBzentyNm', fieldName: 'cmpsPrcsFcltBzentyNm', header: { text: '시설(업체명)' } },
|
||||
@@ -329,7 +329,7 @@ export const SlurgeProcessingFacStatusInpColumn = {
|
||||
'fuelPrcsFcltNm'
|
||||
]
|
||||
},
|
||||
'itslfTs2CmpstgQnt',
|
||||
'itslfTs1CmpstgQnt',
|
||||
'cmpsPrcsFcltBzentyNm'
|
||||
]
|
||||
},
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
import type { GridTopButtonConfig } from "@/components/type/DataGrid.type";
|
||||
import { footerInt } from "@/components/util/grid/footerSummary";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 6. 시설별 현황관리
|
||||
// Tab 6-1: 행정구역별 연결 현황 (오른쪽 그리드)
|
||||
@@ -51,7 +52,7 @@ export const TreatPlantConnectionInpColumn = {
|
||||
columns: [
|
||||
// 하수처리장 정보
|
||||
{ name: 'fcltNm', fieldName: 'fcltNm', header: { text: '하수처리장명' }, editable: false },
|
||||
{ name: 'fcltCpct', fieldName: 'fcltCpct', header: { text: '용량' }, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false },
|
||||
{ name: 'fcltCpct', fieldName: 'fcltCpct', header: { text: '용량' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0', editable: false },
|
||||
{ name: 'fcltSn', fieldName: 'fcltSn', header: { text: '하수처리장코드' }, editable: false },
|
||||
// 연결여부
|
||||
{ name: 'isConnection', fieldName: 'isConnection', header: { text: '연결여부' }, editable: false },
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ValueType } from "realgrid";
|
||||
|
||||
import { footerDecimal2, footerDecimal3,footerInt } from "@/components/util/grid/footerSummary";
|
||||
import { footerAvgDecimal, footerDecimal2, footerDecimal3, footerInt } from "@/components/util/grid/footerSummary";
|
||||
|
||||
// 하수도 통계 관리 > 02.하수관로 > tab 2. 시설별 설치현황
|
||||
// SeweragePipeInputFactInstallStatusItem + commonInfo.ctpvNm (그리드 행에 병합)
|
||||
@@ -14,7 +14,7 @@ export const FactInstallStatusInpColumn = {
|
||||
// 하수처리장 정보
|
||||
{ name: 'swtrmtFcltNm', fieldName: 'swtrmtFcltNm', header: { text: '하수처리장명' }, footer: { text: '합계' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'admdstNm', fieldName: 'admdstNm', header: { text: '행정구역명' }, editable: false, styleName: 'rg-cell-readonly' },
|
||||
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '하수처리시설용량(m³/일)' }, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
{ name: 'prcsFcltCpct', fieldName: 'prcsFcltCpct', header: { text: '하수처리시설용량(m³/일)' }, editable: false, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 처리구역면적(km²)
|
||||
{
|
||||
@@ -37,6 +37,7 @@ export const FactInstallStatusInpColumn = {
|
||||
fieldName: 'sprsysVartnRt',
|
||||
header: { text: '분류식화율' },
|
||||
editable: false,
|
||||
footer: footerAvgDecimal,
|
||||
styleName: 'rg-cell-total',
|
||||
valueType: ValueType.NUMBER,
|
||||
dataFormat: '#,##0.0',
|
||||
|
||||
+3
-3
@@ -64,10 +64,10 @@ export const RainfallPumpStationInpColumn = {
|
||||
{ name: 'rsvrYn', fieldName: 'rsvrYn', header: { text: '유수지유무(유,무)' } },
|
||||
RAINFALL_PUMP_YN_VALUES,
|
||||
),
|
||||
{ name: 'rsvrImpndQnt', fieldName: 'rsvrImpndQnt', header: { text: '저류랑(m³)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'rsvrImpndQnt', fieldName: 'rsvrImpndQnt', header: { text: '저류랑(m³)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 흡수정
|
||||
{ name: 'abstnRgnImpdQnt', fieldName: 'abstnRgnImpdQnt', header: { text: '저류랑(m³)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'abstnRgnImpdQnt', fieldName: 'abstnRgnImpdQnt', header: { text: '저류랑(m³)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 펌프시설 > 총양수량(m³/min)
|
||||
{
|
||||
@@ -145,7 +145,7 @@ export const RainfallPumpStationInpColumn = {
|
||||
{ name: 'ctmnLastDspsMthdExpln', fieldName: 'ctmnLastDspsMthdExpln', header: { text: '협잡물' } },
|
||||
|
||||
// 운영실적
|
||||
{ name: 'oprtngDayCnt', fieldName: 'oprtngDayCnt', header: { text: '가동일수(일/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 입력값 3자리만 가능
|
||||
{ name: 'oprtngDayCnt', fieldName: 'oprtngDayCnt', header: { text: '가동일수(일/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 입력값 3자리만 가능
|
||||
{ name: 'grssMltvQnt', fieldName: 'grssMltvQnt', header: { text: '총배수량(m³/년)' }, footer: footerDecimal2, valueType: ValueType.NUMBER, dataFormat: '#,##0.00' },
|
||||
|
||||
// 비고
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ export const SewageReservoirInpColumn = {
|
||||
{ name: 'ctmnLastDspsMthdExpln', fieldName: 'ctmnLastDspsMthdExpln', header: { text: '협잡물' } },
|
||||
|
||||
// 운영실적
|
||||
{ name: 'oprtngDayCnt', fieldName: 'oprtngDayCnt', header: { text: '가동일수(일/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 3자리 수만 입력 가능
|
||||
{ name: 'oprtngDayCnt', fieldName: 'oprtngDayCnt', header: { text: '가동일수(일/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // 3자리 수만 입력 가능
|
||||
{ name: 'grssMltvQnt', fieldName: 'grssMltvQnt', header: { text: '총배수량(m³/년)' }, footer: footerInt, valueType: ValueType.NUMBER, dataFormat: '#,##0' },
|
||||
|
||||
// 비고
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ export const RainFallUtilFactStatusInpColumn = {
|
||||
},
|
||||
|
||||
// 설치비(백만원)
|
||||
{ name: 'instlAmt', fieldName: 'instlAmt', header: { text: '설치비(백만원)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'instlAmt', fieldName: 'instlAmt', header: { text: '설치비(백만원)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 집수면 종류
|
||||
{ name: 'rcptMynCn', fieldName: 'rcptMynCn', header: { text: '집수면 종류' } },
|
||||
|
||||
@@ -143,7 +143,7 @@ export const RecycledWaterStatusInpColumn = {
|
||||
),
|
||||
|
||||
// 연간운영비(백만원/년)
|
||||
{ name: 'ruswtrOperAmt', fieldName: 'ruswtrOperAmt', header: { text: '연간운영비(백만원/년)' }, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
{ name: 'ruswtrOperAmt', fieldName: 'ruswtrOperAmt', header: { text: '연간운영비(백만원/년)' }, footer: footerDecimal1, valueType: ValueType.NUMBER, dataFormat: '#,##0.0' },
|
||||
|
||||
// 비고
|
||||
{ name: 'rmrk', fieldName: 'rmrk', header: { text: '비고' } },
|
||||
|
||||
@@ -21,6 +21,7 @@ import type {
|
||||
VerifyDetailUpdateRequest,
|
||||
VerifyResultListRequest,
|
||||
VerifyResultListResponse,
|
||||
VerifyExcelDataResponse,
|
||||
VrfcOperatorsResponse,
|
||||
} from "../model/general-verification-interface";
|
||||
|
||||
@@ -176,6 +177,13 @@ export class GeneralverificationApiService implements GeneralverificationService
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getVerifyExcelList(): Promise<VerifyExcelDataResponse> {
|
||||
const response = await stClient.get<VerifyExcelDataResponse>(
|
||||
`${ENDPOINT.ST_SERVICE.INPUTVERIFY}/excel-list`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const generalverificationApiService =
|
||||
|
||||
@@ -10,6 +10,18 @@ export { dashboardApi } from "./api/dashboard/dashboard-service";
|
||||
export { useScheduleInfo } from "./api/dashboard/schedule-info-queries";
|
||||
export { scheduleInfoApi } from "./api/dashboard/schedule-info-service";
|
||||
export { imrApi } from "./api/imr-api";
|
||||
export {
|
||||
filterBySelectedAdmdstCd,
|
||||
findSidoBySearch,
|
||||
isDoListSido,
|
||||
isGugunOkForToolbar,
|
||||
isGugunRequiredSido,
|
||||
isSubmitOkForToolbar,
|
||||
resolveNoApplicableForRequest,
|
||||
toInputSearchRegion,
|
||||
type InputSearchRegion,
|
||||
type SidoGugunLookup,
|
||||
} from "./lib/sido-gugun";
|
||||
export { noticeTalkSendingApi } from "./api/notice-talk/notice-talk-sending-service";
|
||||
export {
|
||||
useNtftalkTemplateList,
|
||||
@@ -131,6 +143,8 @@ export {
|
||||
type RejectRequest,
|
||||
} from "./model/statistics-approval-interface";
|
||||
export {
|
||||
type SearchCondition,
|
||||
type Sido,
|
||||
type StatsInputStatusApproveBatchRequest,
|
||||
type StatsInputStatusApproveItem,
|
||||
type StatsInputStatusApproveKind,
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
import { doList } from "@/components/util/column/input/DoList";
|
||||
|
||||
import type { Sido } from "../model/statistics-interface";
|
||||
|
||||
export type SidoGugunLookup = {
|
||||
sido?: string | null;
|
||||
bsnmCd?: string | null;
|
||||
gugun?: string | null;
|
||||
};
|
||||
|
||||
export function findSidoBySearch(
|
||||
sidoList: readonly Sido[] | undefined,
|
||||
query: SidoGugunLookup | null | undefined,
|
||||
): Sido | undefined {
|
||||
if (!query) return undefined;
|
||||
const list = sidoList ?? [];
|
||||
const sidoName = query.sido?.trim() ?? "";
|
||||
if (sidoName && sidoName !== "ALL") {
|
||||
const byName = list.find((item) => item.sido === sidoName);
|
||||
if (byName) return byName;
|
||||
}
|
||||
const bsnmCd = query.bsnmCd?.trim() ?? "";
|
||||
if (bsnmCd) {
|
||||
return list.find((item) => item.bsnmCd === bsnmCd);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** `gugunSkipYn === "N"` 이면 시군구 선택 필수 (검색폼·시군구 API용) */
|
||||
export function isGugunRequiredSido(
|
||||
sidoList: readonly Sido[] | undefined,
|
||||
query: SidoGugunLookup | null | undefined,
|
||||
): boolean {
|
||||
return findSidoBySearch(sidoList, query)?.gugunSkipYn === "N";
|
||||
}
|
||||
|
||||
function hasSpecificGugun(values: SidoGugunLookup | null | undefined): boolean {
|
||||
const gugun = values?.gugun?.trim() ?? "";
|
||||
return Boolean(gugun && gugun !== "ALL");
|
||||
}
|
||||
|
||||
/** 시도 단위 사업자코드가 `doList`(도)에 해당하는지. 시군구 코드는 쓰지 않는다. */
|
||||
export function isDoListSido(
|
||||
sidoList: readonly Sido[] | undefined,
|
||||
values: SidoGugunLookup | null | undefined,
|
||||
): boolean {
|
||||
const sido = findSidoBySearch(sidoList, { sido: values?.sido });
|
||||
if (sido?.bsnmCd) return doList.includes(sido.bsnmCd);
|
||||
if (hasSpecificGugun(values)) return false;
|
||||
return doList.includes((values?.bsnmCd ?? "").trim());
|
||||
}
|
||||
|
||||
/** 도: 시군구 필수. 광역시·세종·제주: 시군구와 무관하게 통과 */
|
||||
export function isGugunOkForToolbar(
|
||||
sidoList: readonly Sido[] | undefined,
|
||||
values: SidoGugunLookup | null | undefined,
|
||||
): boolean {
|
||||
if (!isDoListSido(sidoList, values)) return true;
|
||||
return hasSpecificGugun(values);
|
||||
}
|
||||
|
||||
/** 도: 시군구 필수. 광역시·세종·제주: 시군구가 선택돼 있으면 제출/제출취소·해당사항 없음 숨김 */
|
||||
export function isSubmitOkForToolbar(
|
||||
sidoList: readonly Sido[] | undefined,
|
||||
values: SidoGugunLookup | null | undefined,
|
||||
): boolean {
|
||||
const hasGugun = hasSpecificGugun(values);
|
||||
if (isDoListSido(sidoList, values)) return hasGugun;
|
||||
return !hasGugun;
|
||||
}
|
||||
|
||||
/**
|
||||
* 저장·제출 `noApplicable`.
|
||||
* 해당사항 없음 버튼이 보이는 경우(도, 또는 비도+시군구 전체)는 체크 여부.
|
||||
* 버튼이 숨겨진 비도+시군구에서는 saveList가 비면 true.
|
||||
*/
|
||||
export function resolveNoApplicableForRequest(
|
||||
sidoList: readonly Sido[] | undefined,
|
||||
values: SidoGugunLookup | null | undefined,
|
||||
checked: boolean,
|
||||
isSaveListEmpty: boolean,
|
||||
): boolean {
|
||||
if (isSubmitOkForToolbar(sidoList, values)) return checked;
|
||||
return isSaveListEmpty;
|
||||
}
|
||||
|
||||
export type InputSearchRegion = {
|
||||
sewerBzmnCd: string;
|
||||
sggNm?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* 입력 화면 조회·저장·제출용 지역 조건.
|
||||
* `doList`에 없으면 시군구와 무관하게 시도 `sewerBzmnCd`만 쓰고 `sggNm`은 생략한다.
|
||||
*/
|
||||
export function toInputSearchRegion(
|
||||
sidoList: readonly Sido[] | undefined,
|
||||
values: SidoGugunLookup | null | undefined,
|
||||
): InputSearchRegion {
|
||||
const sido = findSidoBySearch(sidoList, { sido: values?.sido });
|
||||
if (!isDoListSido(sidoList, values)) {
|
||||
return {
|
||||
sewerBzmnCd: (sido?.bsnmCd ?? "").trim(),
|
||||
};
|
||||
}
|
||||
const gugun = values?.gugun?.trim() ?? "";
|
||||
return {
|
||||
sewerBzmnCd: (values?.bsnmCd || sido?.bsnmCd || "").trim(),
|
||||
sggNm: gugun && gugun !== "ALL" ? gugun : "",
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* `doList`가 아닌 시도에서 시군구가 선택된 경우,
|
||||
* 조회 결과를 `admdstCd`가 선택 시군구 코드와 같은 행만 남긴다.
|
||||
*/
|
||||
export function filterBySelectedAdmdstCd<T>(
|
||||
rows: readonly T[] | null | undefined,
|
||||
sidoList: readonly Sido[] | undefined,
|
||||
values: SidoGugunLookup | null | undefined,
|
||||
): T[] {
|
||||
const list = rows ? [...rows] : [];
|
||||
if (isDoListSido(sidoList, values)) return list;
|
||||
if (!hasSpecificGugun(values)) return list;
|
||||
const selectedCd = (values?.bsnmCd ?? "").trim();
|
||||
if (!selectedCd) return list;
|
||||
return list.filter((row) => {
|
||||
const cd = String(
|
||||
(row as { admdstCd?: unknown }).admdstCd ?? "",
|
||||
).trim();
|
||||
return cd === selectedCd;
|
||||
});
|
||||
}
|
||||
@@ -264,6 +264,22 @@ export interface VerifyResultListResponse {
|
||||
httpStatus?: number;
|
||||
}
|
||||
|
||||
/** 검증 엑셀 데이터 조회 — 요청 파라미터 없음 */
|
||||
export interface VerifyExcelDataItem {
|
||||
trgtStatsNm: string;
|
||||
vrfcNm: string;
|
||||
vrfcClsfNm: string;
|
||||
dcptDigtCnt: number;
|
||||
dcptPrcsMthNm: string;
|
||||
vrfcEqtnCn: string;
|
||||
}
|
||||
|
||||
export interface VerifyExcelDataResponse {
|
||||
status: string;
|
||||
message?: string;
|
||||
data: VerifyExcelDataItem[];
|
||||
}
|
||||
|
||||
export interface GeneralverificationService {
|
||||
getGeneralverificationList(
|
||||
param: GeneralverificationRequest,
|
||||
@@ -305,4 +321,5 @@ export interface GeneralverificationService {
|
||||
getVerifyResultList(
|
||||
param: VerifyResultListRequest,
|
||||
): Promise<VerifyResultListResponse>;
|
||||
getVerifyExcelList(): Promise<VerifyExcelDataResponse>;
|
||||
}
|
||||
|
||||
+2
-2
@@ -136,7 +136,7 @@ export type ExcretaTreatmentFacilitySaveItem = Omit<
|
||||
export interface ExcretaTreatmentFacilitySaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -157,7 +157,7 @@ export type ExcretaTreatmentFacilitySubmitItem = ExcretaTreatmentFacilitySaveIte
|
||||
export interface ExcretaTreatmentFacilitySubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
|
||||
|
||||
+6
-6
@@ -230,7 +230,7 @@ export interface SewageTreatFactStatusSaveItem {
|
||||
export interface SewageTreatFactStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -248,7 +248,7 @@ export interface SewageTreatFactStatusSaveResponse {
|
||||
export interface SewageTreatFactStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -316,7 +316,7 @@ export interface SepticTankStatusSaveItem {
|
||||
export interface SepticTankStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -334,7 +334,7 @@ export interface SepticTankStatusSaveResponse {
|
||||
export interface SepticTankStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -379,7 +379,7 @@ export interface PrivateSewageDesigStatusSaveItem {
|
||||
export interface PrivateSewageDesigStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -397,7 +397,7 @@ export interface PrivateSewageDesigStatusSaveResponse {
|
||||
export interface PrivateSewageDesigStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
|
||||
+2
-2
@@ -129,7 +129,7 @@ export type PumpingStationSaveItem = Omit<
|
||||
export interface PumpingStationSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -150,7 +150,7 @@ export type PumpingStationSubmitItem = PumpingStationSaveItem;
|
||||
export interface PumpingStationSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
|
||||
|
||||
+1
-1
@@ -228,7 +228,7 @@ export type PrivateSewageTreatRelatedIndustrySaveItem = Omit<
|
||||
export interface SewageExcretaRelatedSaveRequestBase {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
|
||||
+9
-9
@@ -90,7 +90,7 @@ export interface SlurgeProcessingFacStatusItem {
|
||||
fuelPrcsIncnrQnt: number;
|
||||
fuelPrcsFuelQnt: number;
|
||||
fuelPrcsFcltNm: string;
|
||||
itslfTs2CmpstgQnt: number;
|
||||
itslfTs1CmpstgQnt: number;
|
||||
cmpsPrcsFcltBzentyNm: string;
|
||||
otsdCnsgnWhol: number;
|
||||
otsdCnsgnRclmQnt: number;
|
||||
@@ -161,7 +161,7 @@ export type SlurgeProcessingFacStatusSaveItem = Omit<
|
||||
export interface SlurgeProcessingFacStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -180,7 +180,7 @@ export type SlurgeProcessingFacStatusSubmitItem = SlurgeProcessingFacStatusSaveI
|
||||
export interface SlurgeProcessingFacStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -271,7 +271,7 @@ export type DigestorOperatingStatusSaveItem = Omit<
|
||||
export interface DigestorOperatingStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -290,7 +290,7 @@ export type DigestorOperatingStatusSubmitItem = DigestorOperatingStatusSaveItem;
|
||||
export interface DigestorOperatingStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -374,7 +374,7 @@ export type SewageSlurgeProcessingFacStatusSaveItem = Omit<
|
||||
export interface SewageSlurgeProcessingFacStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -394,7 +394,7 @@ export type SewageSlurgeProcessingFacStatusSubmitItem =
|
||||
export interface SewageSlurgeProcessingFacStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -483,7 +483,7 @@ export type ExcretaSlurgeProcessingStatusSaveItem = Omit<
|
||||
export interface ExcretaSlurgeProcessingStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -501,7 +501,7 @@ export type ExcretaSlurgeProcessingStatusSubmitItem = ExcretaSlurgeProcessingSta
|
||||
export interface ExcretaSlurgeProcessingStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
|
||||
+4
-4
@@ -122,7 +122,7 @@ export interface SewagePipeMaintainRepairSaveItem {
|
||||
export interface SewagePipeMaintainRepairSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -139,7 +139,7 @@ export interface SewagePipeMaintainRepairSaveResponse {
|
||||
export interface SewagePipeMaintainRepairSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -193,7 +193,7 @@ export interface SewagePipeMaintainDredgingSaveItem {
|
||||
export interface SewagePipeMaintainDredgingSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -210,7 +210,7 @@ export interface SewagePipeMaintainDredgingSaveResponse {
|
||||
export interface SewagePipeMaintainDredgingSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
|
||||
+4
-4
@@ -211,7 +211,7 @@ export type SewageReservoirSaveItem = Omit<
|
||||
export interface SewageReservoirSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -230,7 +230,7 @@ export interface SewageReservoirSaveResponse {
|
||||
export interface SewageReservoirSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -301,7 +301,7 @@ export type RainfallPumpStationSaveItem = Omit<
|
||||
export interface RainfallPumpStationSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -317,7 +317,7 @@ export type RainfallPumpStationSaveResponse = SewageReservoirSaveResponse;
|
||||
export interface RainfallPumpStationSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
|
||||
+6
-6
@@ -130,7 +130,7 @@ export interface SewerageFinanceSettleSaveItem {
|
||||
export interface SewerageFinanceSettleSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -147,7 +147,7 @@ export interface SewerageFinanceSettleSaveResponse {
|
||||
export interface SewerageFinanceSettleSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -175,7 +175,7 @@ export interface SewerageFinanceSettleSubmitResponse {
|
||||
export interface SewerageFinanceSubmitRequestBase {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -268,7 +268,7 @@ export interface SewerageChargeSaveItem {
|
||||
export interface SewerageChargeSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -392,7 +392,7 @@ export interface SewerageUsageFeeSaveItem {
|
||||
export interface SewerageUsageFeeSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -486,7 +486,7 @@ export interface CauserBurdenSaveItem {
|
||||
export interface CauserBurdenSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
|
||||
+4
-4
@@ -147,7 +147,7 @@ export interface SewerageServiceLevelComplaintSaveItem {
|
||||
export interface SewerageServiceLevelComplaintSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -183,7 +183,7 @@ export interface SewerageServiceLevelResidentFriendlyFactSaveItem {
|
||||
export interface SewerageServiceLevelResidentFriendlyFactSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -204,7 +204,7 @@ export type SewerageServiceLevelComplaintSubmitItem = SewerageServiceLevelCompla
|
||||
export interface SewerageServiceLevelComplaintSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -227,7 +227,7 @@ export type SewerageServiceLevelResidentFriendlyFactSubmitItem =
|
||||
export interface SewerageServiceLevelResidentFriendlyFactSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
|
||||
+11
-11
@@ -127,7 +127,7 @@ export interface PublicSewageTreatWaterReuseSaveItem {
|
||||
export interface PublicSewageTreatWaterReuseSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -145,7 +145,7 @@ export type PublicSewageTreatWaterReuseSubmitItem = PublicSewageTreatWaterReuseS
|
||||
export interface PublicSewageTreatWaterReuseSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -238,7 +238,7 @@ export type RecycledWaterStatusSaveItem = Omit<
|
||||
export interface RecycledWaterStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -257,7 +257,7 @@ export type RecycledWaterStatusSubmitItem = RecycledWaterStatusSaveItem;
|
||||
export interface RecycledWaterStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -353,7 +353,7 @@ export type RainFallUtilFactStatusSaveItem = Omit<
|
||||
export interface RainFallUtilFactStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -372,7 +372,7 @@ export type RainFallUtilFactStatusSubmitItem = RainFallUtilFactStatusSaveItem;
|
||||
export interface RainFallUtilFactStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -452,7 +452,7 @@ export type TreatWaterReuseDesignConstStatusSaveItem = Omit<
|
||||
export interface TreatWaterReuseDesignConstStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -472,7 +472,7 @@ export type TreatWaterReuseDesignConstStatusSubmitItem =
|
||||
export interface TreatWaterReuseDesignConstStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -552,7 +552,7 @@ export type TreatWaterReuseBusinessApprStatusSaveItem = Omit<
|
||||
export interface TreatWaterReuseBusinessApprStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -572,7 +572,7 @@ export type TreatWaterReuseBusinessApprStatusSubmitItem =
|
||||
export interface TreatWaterReuseBusinessApprStatusSubmitRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -601,7 +601,7 @@ export interface TreatWaterReuseBusinessApprStatusSubmitResponse {
|
||||
export interface WaterReuseOperationDataUpdateRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
+4
-4
@@ -143,7 +143,7 @@ export interface PublicSewageMainFacilityResponse {
|
||||
export interface PublicSewageMappingTargetsRequestParams {
|
||||
sewerBzmnCd: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
statsYr: string;
|
||||
fcltSn: string;
|
||||
}
|
||||
@@ -229,7 +229,7 @@ export interface PublicSewageFacilitySaveItem {
|
||||
export interface PublicSewageFacilitySaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -253,7 +253,7 @@ export interface PublicSewageFacilitySaveResponse {
|
||||
export interface PublicSewageFacilitySubmitRequestBase {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
noApplicable?: boolean;
|
||||
@@ -284,7 +284,7 @@ export interface PublicSewageFacilitySubmitResponse {
|
||||
export interface PublicSewageFacilityOperationDataUpdateRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
}
|
||||
|
||||
+7
-7
@@ -129,7 +129,7 @@ export type SeweragePipeInputFactInstallStatusSaveItem = Omit<
|
||||
export interface SeweragePipeInputRegionalFactStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -146,7 +146,7 @@ export interface SeweragePipeInputRegionalFactStatusSaveResponse {
|
||||
export interface SeweragePipeInputSubmitRequestBase {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
laePicNm: string;
|
||||
@@ -176,7 +176,7 @@ export interface SeweragePipeInputRegionalFactStatusSubmitResponse {
|
||||
export interface SeweragePipeInputFactInstallStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -317,7 +317,7 @@ export interface SeweragePipeInputPipeTypeStatusSaveItem {
|
||||
export interface SeweragePipeInputPipeTypeStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -389,7 +389,7 @@ export interface SeweragePipeInputPipeDiameterStatusSaveItem {
|
||||
export interface SeweragePipeInputPipeDiameterStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -487,7 +487,7 @@ export interface SeweragePipeInputManholeStatusSaveItem {
|
||||
export interface SeweragePipeInputManholeStatusSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
superAdmin?: string;
|
||||
@@ -602,7 +602,7 @@ export interface SeweragePipeFactConnectionSaveItem {
|
||||
/** 시설별 연결관계 저장 요청 */
|
||||
export interface SeweragePipeFactConnectionSaveRequest {
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
fcltSn: string;
|
||||
statsYr: string;
|
||||
swtrmtFcltCd: string;
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ export interface SewerageSupplyRateSaveItem {
|
||||
export interface SewerageSupplyRateSaveRequest {
|
||||
statsYr: string;
|
||||
ctpvNm: string;
|
||||
sggNm: string;
|
||||
sggNm?: string;
|
||||
sewerBzmnCd: string;
|
||||
userId: string;
|
||||
sewerBzmnArea?: number;
|
||||
|
||||
@@ -11,4 +11,10 @@ export {
|
||||
useActiveTabRegAuthorityAllowed,
|
||||
useStatisticsInputToolbarGroupGate,
|
||||
} from "./use-statistics-input-toolbar-group-gate";
|
||||
export {
|
||||
fetchSearchCondition,
|
||||
fetchSearchConditionInput,
|
||||
SEARCH_CONDITION_SWR_KEY,
|
||||
useSearchConditionSidoList,
|
||||
} from "./use-search-condition-sido-list";
|
||||
export { useUserStore } from "./use-user-store";
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { menuMatchesStatisticsTabId } from "@/shared/lib/statistics-menu-url";
|
||||
import type { MenuItem } from "@/entities/menu";
|
||||
import { isGugunRequiredSido } from "@/entities/statistics";
|
||||
import type { Sido } from "@/entities/statistics/model/statistics-interface";
|
||||
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { doNameList } from "@/components/util/column/input/DoList";
|
||||
import {
|
||||
EXCRETA_TREATMENT_FACILITY_INP_TAB_KEYS,
|
||||
INPUT_TAB_KEY_BY_STATS_CD,
|
||||
@@ -30,12 +31,17 @@ export type StatisticsInputPendingSearch = {
|
||||
|
||||
export function verificationSearchToFormValues(
|
||||
s: StatisticsInputPendingSearch,
|
||||
sidoList?: readonly Sido[],
|
||||
): SearchFormValues {
|
||||
const ctpvNmTrimmed = s.ctpvNm?.trim() ?? "";
|
||||
const sggNmTrimmed = s.sggNm?.trim() ?? "";
|
||||
/** 시군구 필수 도(`DoList.ts`의 `doNameList`)일 때만 API `sggNm`을 검색폼에 반영 */
|
||||
/** 시군구 필수 시도(`gugunSkipYn === "N"`)일 때만 API `sggNm`을 검색폼에 반영 */
|
||||
const useSggNm =
|
||||
sggNmTrimmed.length > 0 && doNameList.includes(ctpvNmTrimmed);
|
||||
sggNmTrimmed.length > 0 &&
|
||||
isGugunRequiredSido(sidoList, {
|
||||
sido: ctpvNmTrimmed,
|
||||
bsnmCd: s.sewerBzmnCd,
|
||||
});
|
||||
|
||||
return {
|
||||
year: s.statsYr,
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
"use client";
|
||||
|
||||
import useSWR from "swr";
|
||||
|
||||
import type {
|
||||
ApiResponse,
|
||||
SearchCondition,
|
||||
Sido,
|
||||
} from "@/entities/statistics/model/statistics-interface";
|
||||
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
|
||||
import { useUserStore } from "./use-user-store";
|
||||
|
||||
export type SearchConditionKind = "default" | "input";
|
||||
|
||||
export const SEARCH_CONDITION_SWR_KEY = (
|
||||
instSeCd: string,
|
||||
kind: SearchConditionKind = "default",
|
||||
) =>
|
||||
[
|
||||
kind === "input" ? "sido-list-input" : "sido-list",
|
||||
instSeCd,
|
||||
] as const;
|
||||
|
||||
export async function fetchSearchCondition(
|
||||
key: readonly [string, string],
|
||||
): Promise<ApiResponse<SearchCondition>> {
|
||||
return statisticsApi.getSidoList({ instSeCd: key[1] });
|
||||
}
|
||||
|
||||
export async function fetchSearchConditionInput(
|
||||
key: readonly [string, string],
|
||||
): Promise<ApiResponse<SearchCondition>> {
|
||||
return statisticsApi.getSidoListInput({ instSeCd: key[1] });
|
||||
}
|
||||
|
||||
const SIDO_LIST_SWR_OPTIONS = {
|
||||
revalidateOnFocus: false,
|
||||
revalidateOnReconnect: false,
|
||||
revalidateIfStale: false,
|
||||
dedupingInterval: 2000,
|
||||
shouldRetryOnError: false,
|
||||
} as const;
|
||||
|
||||
/** SearchForm과 동일한 SWR 키로 시도 목록(`gugunSkipYn` 포함)을 재사용합니다. */
|
||||
export function useSearchConditionSidoList(options?: { isInput?: boolean }): {
|
||||
sidoList: Sido[];
|
||||
isReady: boolean;
|
||||
} {
|
||||
const instSeCd = useUserStore((state) => state.userInfo?.instSeCd ?? "");
|
||||
const kind: SearchConditionKind = options?.isInput ? "input" : "default";
|
||||
const { data } = useSWR(
|
||||
SEARCH_CONDITION_SWR_KEY(instSeCd, kind),
|
||||
kind === "input" ? fetchSearchConditionInput : fetchSearchCondition,
|
||||
SIDO_LIST_SWR_OPTIONS,
|
||||
);
|
||||
return {
|
||||
sidoList: data?.data?.sidoList ?? [],
|
||||
isReady: data != null,
|
||||
};
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
type StatisticsInputPendingSearch,
|
||||
verificationSearchToFormValues,
|
||||
} from "@/shared/lib/stats-cd-input-navigation";
|
||||
import { useSearchConditionSidoList } from "@/shared/lib/use-search-condition-sido-list";
|
||||
|
||||
import type { SearchFormValues } from "@/components/type/SearchForm.type";
|
||||
import { useStatisticsInputFocusStore } from "@/store/statistics-input-focus-store";
|
||||
@@ -43,9 +44,11 @@ export function useStatisticsInputPendingNavigation({
|
||||
|
||||
const activeTabId = useTabStore((s) => s.activeTabId);
|
||||
const inputFocusNonce = useStatisticsInputFocusStore((s) => s.nonce);
|
||||
const { sidoList, isReady } = useSearchConditionSidoList({ isInput: true });
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (activeTabId !== urlPath) return;
|
||||
if (!isReady) return;
|
||||
const pending = useStatisticsInputFocusStore
|
||||
.getState()
|
||||
.takePendingForUrl(urlPath);
|
||||
@@ -54,12 +57,15 @@ export function useStatisticsInputPendingNavigation({
|
||||
handlersRef.current.onPending?.(pending);
|
||||
|
||||
if (pending.search) {
|
||||
const values = verificationSearchToFormValues(pending.search);
|
||||
const values = verificationSearchToFormValues(
|
||||
pending.search,
|
||||
sidoList,
|
||||
);
|
||||
setVerificationSearchDefaults(values);
|
||||
autoSearchRef.current = { values, tabKey: pending.tabKey };
|
||||
setSearchFormRemountKey((k) => k + 1);
|
||||
}
|
||||
}, [activeTabId, inputFocusNonce, urlPath]);
|
||||
}, [activeTabId, inputFocusNonce, urlPath, isReady, sidoList]);
|
||||
|
||||
useEffect(() => {
|
||||
const job = autoSearchRef.current;
|
||||
|
||||
Reference in New Issue
Block a user