-
-
-
-
-
+
+ {showActionToolbarCard && (
+
+
+
+ {showEnterableToolbarButtons && (
+ <>
+ void getLastYearDataFunc()}
+ />
+
+ >
+ )}
+ {activeTabStatus?.laeSbmsnSttsCd === "2" && (
+
+ )}
+ {showSaveInToolbar && }
+
-
-
-
-
-
-
+ )}
+ {showArticleToolbarCard && (
+
+
+ {showIsNotApplicable && (
+
+ )}
+
+
+
-
-
+ )}
+ {isLoading && (
+
+ )}
+ void handleActiveTabChange(v)}
+ >
{SewageReservoirPumpInpTabList.map((tab) => (
@@ -92,10 +848,29 @@ const SewageReservoirPumpInp = () => {
{SewageReservoirPumpInpTabList.map((tab) => {
const tabKey = tab.tabKey ?? "";
+ const tabEnterableForGrid =
+ computeTabEnterable(
+ tabStatusInfoMap.get(tabKey) ?? null,
+ inputPeriodEnterable,
+ ) || isAdminInfo;
+ const gugunOk = buildGugunOkForToolbar(lastSearchedValues);
+ const tabStatusInfo = tabStatusInfoMap.get(tabKey) ?? null;
+ const isReservoirTab = tabKey === SEWAGE_RESERVOIR_STATS_CD;
return (
{
const cur = next.get(tabKey) ?? [];
const n =
typeof updater === "function"
- ? (updater as (p: Record[]) => Record[])(cur)
+ ? (updater as (
+ p: Record<
+ string,
+ string | number
+ >[],
+ ) => Record<
+ string,
+ string | number
+ >[])(cur)
: updater;
next.set(tabKey, n);
return next;
});
}}
- showHeaderCheckbox={false}
+ showHeaderCheckbox
+ statusInfo={tabStatusInfo}
+ isExcelImport={
+ tabRowDataExists(rowDataMap, tabKey) &&
+ tabEnterableForGrid &&
+ gugunOk
+ }
+ cellStyleCallback={verificationCellStyle}
+ cellTooltipCallback={verificationCellTooltip}
+ onCellEdited={
+ isReservoirTab &&
+ tabEnterableForGrid &&
+ sggOptions.length > 0
+ ? handleSewageReservoirCellEdited
+ : undefined
+ }
/>
);
})}
+
>
);
};
diff --git a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx
index 4193f2535..6a31e84da 100644
--- a/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx
+++ b/apps/st/src/components/statistics/input/SeweragePenetrationRateInp.tsx
@@ -254,7 +254,6 @@ const SeweragePenetrationRateInp = () => {
...d,
ctpvNm: commonInfo.ctpvNm,
spcCtpnRgnCn: d.spcCtpnRgnCn === '' || d.spcCtpnRgnCn === null ? '해당없음' : d.spcCtpnRgnCn,
- swagePplPsplyRt: commonInfo.swagePplPsplyRt,
}));
setRowData(
convertedData.map((d) => {
@@ -823,7 +822,7 @@ const SeweragePenetrationRateInp = () => {
if (Array.isArray(errors) && errors.length > 0) {
return errors
.map((e) => {
- const prefix = e.vrfcCd === 'IMR' ? 'IMR검증 - ' : (e.vrfcCd === 'NM' ? '일반검증 - ' : 'HB검증 -');
+ const prefix = e.vrfcCd === 'IMR' ? 'IMR검증 - ' : (e.vrfcCd === 'NV' ? '일반검증 - ' : 'HB검증 -');
return `${prefix}${e.rsnExpln}
(검증 기준값: ${e.compVlCn} / 현재 입력값: ${e.nowVlCn})`;
})
diff --git a/apps/st/src/components/statistics/management/LogHistoryDetailDialog.tsx b/apps/st/src/components/statistics/management/LogHistoryDetailDialog.tsx
index 09667bc88..359eba00d 100644
--- a/apps/st/src/components/statistics/management/LogHistoryDetailDialog.tsx
+++ b/apps/st/src/components/statistics/management/LogHistoryDetailDialog.tsx
@@ -1,6 +1,7 @@
"use client";
-import { useEffect } from "react";
+import { useEffect, useMemo, useState } from "react";
+import { GridFitStyle } from "realgrid";
import {
Button,
@@ -10,9 +11,20 @@ import {
DialogFooter,
DialogHeader,
DialogTitle,
+ LoadingWithAnimation,
} from "@common/components";
+import DataGrid from "@/components/module/DataGrid";
+import type { ColumnInfo } from "@/components/type/DataGrid.type";
+import {
+ alignLogDetailRowsToColumns,
+ buildLogHistoryDetailColumnInfo,
+ emptyLogHistoryDetailColumnInfo,
+} from "@/components/util/column/management/LogHistoryDetailColumn";
+import { toGridRows } from "@/components/util/grid/gridFunction";
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
+import type { StatisticsLogDetailRow } from "@/entities/statistics/model/statistics-interface";
+import { useAlertStore } from "@/shared/lib";
export interface LogHistoryDetailDialogProps {
open: boolean;
@@ -25,24 +37,115 @@ export function LogHistoryDetailDialog({
onOpenChange,
row,
}: LogHistoryDetailDialogProps) {
+ const { setMessage: alert } = useAlertStore((state) => state);
+ const [isLoading, setIsLoading] = useState(false);
+ const [rowData, setRowData] = useState
[]>(
+ [],
+ );
+ const [columnInfo, setColumnInfo] = useState(
+ emptyLogHistoryDetailColumnInfo,
+ );
+
useEffect(() => {
- if (!open || !row) return;
+ if (!open) {
+ setRowData([]);
+ setColumnInfo(emptyLogHistoryDetailColumnInfo);
+ setIsLoading(false);
+ return;
+ }
+
+ if (!row) return;
const sn = row.statsLogSn;
+ let cancelled = false;
+
void (async () => {
- const response = await statisticsApi.getLogDetail(
- sn !== undefined && sn !== null ? String(sn) : "",
- );
- console.log(response.data);
+ setIsLoading(true);
+ setRowData([]);
+
+ try {
+ const response = await statisticsApi.getLogDetail(
+ sn !== undefined && sn !== null ? String(sn) : "",
+ );
+
+ if (cancelled) return;
+
+ if (response.status !== "success") {
+ alert(
+ response.message ??
+ "로그 상세 정보를 불러오는데 실패했습니다.",
+ );
+ return;
+ }
+
+ const list = Array.isArray(response.data)
+ ? response.data
+ : [];
+ const nextColumnInfo = buildLogHistoryDetailColumnInfo(list);
+ const nextRows = alignLogDetailRowsToColumns(
+ toGridRows(list as StatisticsLogDetailRow[]),
+ nextColumnInfo,
+ );
+ setColumnInfo(nextColumnInfo);
+ setRowData(nextRows);
+ } catch {
+ if (!cancelled) {
+ alert("로그 상세 정보를 불러오는데 실패했습니다.");
+ }
+ } finally {
+ if (!cancelled) setIsLoading(false);
+ }
})();
- }, [open, row]);
+
+ return () => {
+ cancelled = true;
+ };
+ }, [open, row, alert]);
+
+ const gridRemountKey = useMemo(
+ () => columnInfo.columns.map((c) => c.fieldName).join("\u0001"),
+ [columnInfo],
+ );
+
+ const showGrid = !isLoading && rowData.length > 0;
return (