[st] - fix: 오류 수정 및 누락 기능 추가
This commit is contained in:
@@ -23,7 +23,11 @@ import {
|
||||
} from "@common/components";
|
||||
import DataGrid from "@/components/module/DataGrid";
|
||||
import { VerificationResultHistoryPagination } from "@/components/module/VerificationResultHistoryPagination";
|
||||
import type { CellEditedCallbackParams, ColumnInfo } from "@/components/type/DataGrid.type";
|
||||
import type {
|
||||
CellEditedCallbackParams,
|
||||
CellStyleCallbackParams,
|
||||
ColumnInfo,
|
||||
} from "@/components/type/DataGrid.type";
|
||||
import { getUserInfo } from "../../../../../packages/common/components/src/api";
|
||||
import { statisticsApi } from "@/entities/statistics/api/statistics-service";
|
||||
import type { VerificationResultListRequest, VerificationResultReportItem } from "@/entities/statistics/model/statistics-interface";
|
||||
@@ -31,6 +35,16 @@ import { useAlertStore } from "@/shared/lib";
|
||||
|
||||
type VerificationResultGridRow = Record<string, string | number>;
|
||||
|
||||
type VerificationMethodCd = "NV" | "IMR" | "HB";
|
||||
|
||||
const VERIFICATION_METHOD_CODES: VerificationMethodCd[] = ["NV", "IMR", "HB"];
|
||||
|
||||
const VRFC_MTHD_NAME_MAP: Record<VerificationMethodCd, string> = {
|
||||
NV: "일반",
|
||||
IMR: "I-MR",
|
||||
HB: "HB",
|
||||
};
|
||||
|
||||
export type VerificationExceptionSubmitItem = {
|
||||
vrfcSn: number;
|
||||
prcsOpnnExpln: string;
|
||||
@@ -60,9 +74,23 @@ const PRCS_YN_LABEL: Record<string, string> = {
|
||||
"3": "반려",
|
||||
};
|
||||
|
||||
/** History와 동일 + 편집 가능한 처리의견(예외사유, API 필드명 `prcsOpnnExpln`과 동일) */
|
||||
function verificationMthdCellStyle({
|
||||
fieldName,
|
||||
row,
|
||||
}: CellStyleCallbackParams): string | undefined {
|
||||
if (fieldName !== "vrfcMthdNm") return undefined;
|
||||
const code = String(row.vrfcMthdCd ?? "");
|
||||
if (code === "IMR") return "rg-cell-vrf-mthd-imr";
|
||||
if (code === "HB") return "rg-cell-vrf-mthd-hb";
|
||||
if (code === "NV") return "rg-cell-vrf-mthd-nv";
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/** History와 동일 + 구분(검증유형) + 편집 가능한 처리의견(예외사유) */
|
||||
const verificationSubmitResultColumnInfo: ColumnInfo = {
|
||||
columns: [
|
||||
{ name: "vrfcMthdNm", fieldName: "vrfcMthdNm", header: { text: "구분" }, editable: false },
|
||||
{ name: "vrfcMthdCd", fieldName: "vrfcMthdCd", header: { text: "검증유형코드" }, editable: false, visible: false },
|
||||
{ name: "ctpvNm", fieldName: "ctpvNm", header: { text: "시도" }, editable: false },
|
||||
{ name: "sggNm", fieldName: "sggNm", header: { text: "시군구" }, editable: false },
|
||||
{ name: "vrfcTrgtNm", fieldName: "vrfcTrgtNm", header: { text: "검증대상" }, editable: false },
|
||||
@@ -81,6 +109,7 @@ const verificationSubmitResultColumnInfo: ColumnInfo = {
|
||||
},
|
||||
],
|
||||
columnLayout: [
|
||||
"vrfcMthdNm",
|
||||
"ctpvNm",
|
||||
"sggNm",
|
||||
"vrfcTrgtNm",
|
||||
@@ -121,7 +150,6 @@ export function VerificationResultDialog({
|
||||
emptyMessage = "표시할 검증 결과가 없습니다.",
|
||||
onExceptionSubmitted,
|
||||
}: VerificationResultDialogProps) {
|
||||
/** 부모가 매 렌더마다 새 객체를 넘기면 queryContext 참조만 바뀌어 loadInitial이 재실행되므로 필드 값 기준으로 안정화 */
|
||||
const stableQueryContext = useMemo((): VerificationResultDialogQueryContext | null => {
|
||||
if (!queryContext) return null;
|
||||
return queryContext;
|
||||
@@ -133,47 +161,24 @@ export function VerificationResultDialog({
|
||||
queryContext?.statsCd,
|
||||
]);
|
||||
|
||||
const [normalPageIndex, setNormalPageIndex] = useState(0);
|
||||
const [imrPageIndex, setImrPageIndex] = useState(0);
|
||||
const [normalPageCount, setNormalPageCount] = useState(1);
|
||||
const [imrPageCount, setImrPageCount] = useState(1);
|
||||
const [normalLoading, setNormalLoading] = useState(false);
|
||||
const [imrLoading, setImrLoading] = useState(false);
|
||||
const [pageIndex, setPageIndex] = useState(0);
|
||||
const [pageCount, setPageCount] = useState(1);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
|
||||
const [normalRows, setNormalRows] = useState<VerificationResultGridRow[]>([]);
|
||||
const [imrRows, setImrRows] = useState<VerificationResultGridRow[]>([]);
|
||||
const [normalCheckedIndices, setNormalCheckedIndices] = useState<Set<number>>(
|
||||
() => new Set(),
|
||||
);
|
||||
const [imrCheckedIndices, setImrCheckedIndices] = useState<Set<number>>(() => new Set());
|
||||
const [rows, setRows] = useState<VerificationResultGridRow[]>([]);
|
||||
const [checkedIndices, setCheckedIndices] = useState<Set<number>>(() => new Set());
|
||||
|
||||
const normalGridRef = useRef<RealGridReact | null>(null);
|
||||
const imrGridRef = useRef<RealGridReact | null>(null);
|
||||
/** 메인 입력 화면처럼 편집 값은 그리드에 두고, 제출 시에만 스냅샷 조회 → Enter 시 rows 재주입 충돌 방지 */
|
||||
const getNormalGridDataRef = useRef<(() => VerificationResultGridRow[]) | null>(null);
|
||||
const getImrGridDataRef = useRef<(() => VerificationResultGridRow[]) | null>(null);
|
||||
const gridRef = useRef<RealGridReact | null>(null);
|
||||
const getGridDataRef = useRef<(() => VerificationResultGridRow[]) | null>(null);
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
|
||||
const onNormalPrcsOpnnExplnEdited = useCallback((params: CellEditedCallbackParams) => {
|
||||
const onPrcsOpnnExplnEdited = useCallback((params: CellEditedCallbackParams) => {
|
||||
if (params.fieldName !== "prcsOpnnExpln") return;
|
||||
const text = String(params.newValue ?? "");
|
||||
const hasValue = text.trim().length > 0;
|
||||
setRowCheckByItemIndex(normalGridRef, params.itemIndex, hasValue);
|
||||
setNormalCheckedIndices((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (hasValue) next.add(params.itemIndex);
|
||||
else next.delete(params.itemIndex);
|
||||
return next;
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onImrPrcsOpnnExplnEdited = useCallback((params: CellEditedCallbackParams) => {
|
||||
if (params.fieldName !== "prcsOpnnExpln") return;
|
||||
const text = String(params.newValue ?? "");
|
||||
const hasValue = text.trim().length > 0;
|
||||
setRowCheckByItemIndex(imrGridRef, params.itemIndex, hasValue);
|
||||
setImrCheckedIndices((prev) => {
|
||||
setRowCheckByItemIndex(gridRef, params.itemIndex, hasValue);
|
||||
setCheckedIndices((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (hasValue) next.add(params.itemIndex);
|
||||
else next.delete(params.itemIndex);
|
||||
@@ -182,38 +187,38 @@ export function VerificationResultDialog({
|
||||
}, []);
|
||||
|
||||
const resetState = useCallback(() => {
|
||||
setNormalPageIndex(0);
|
||||
setImrPageIndex(0);
|
||||
setNormalPageCount(1);
|
||||
setImrPageCount(1);
|
||||
setNormalLoading(false);
|
||||
setImrLoading(false);
|
||||
setPageIndex(0);
|
||||
setPageCount(1);
|
||||
setLoading(false);
|
||||
setErrorMessage(null);
|
||||
setNormalRows([]);
|
||||
setImrRows([]);
|
||||
setNormalCheckedIndices(new Set());
|
||||
setImrCheckedIndices(new Set());
|
||||
setRows([]);
|
||||
setCheckedIndices(new Set());
|
||||
}, []);
|
||||
|
||||
const mapItemToRow = useCallback((item: VerificationResultReportItem): VerificationResultGridRow => {
|
||||
return {
|
||||
vrfcSn: item.vrfcSn,
|
||||
ctpvNm: item.ctpvNm,
|
||||
sggNm: item.sggNm,
|
||||
vrfcTrgtNm: item.vrfcTrgtNm,
|
||||
rsnExpln: item.rsnExpln,
|
||||
nowVlCn: item.nowVlCn ?? "-",
|
||||
compVlCn: item.compVlCn ?? "-",
|
||||
prcsYn: PRCS_YN_LABEL[item.prcsYn] ?? item.prcsYn,
|
||||
pbcpAprvYn: item.pbcpAprvYn,
|
||||
regDt: (item.regDt ?? "").slice(0, 16),
|
||||
mdfcnDt: (item.mdfcnDt ?? "").slice(0, 16),
|
||||
prcsOpnnExpln: item.prcsOpnnExpln ?? "",
|
||||
};
|
||||
}, []);
|
||||
const mapItemToRow = useCallback(
|
||||
(item: VerificationResultReportItem, vrfcMthdCd: VerificationMethodCd): VerificationResultGridRow => {
|
||||
return {
|
||||
vrfcSn: item.vrfcSn,
|
||||
vrfcMthdCd,
|
||||
vrfcMthdNm: VRFC_MTHD_NAME_MAP[vrfcMthdCd] ?? item.vrfcMthdNm,
|
||||
ctpvNm: item.ctpvNm,
|
||||
sggNm: item.sggNm,
|
||||
vrfcTrgtNm: item.vrfcTrgtNm,
|
||||
rsnExpln: item.rsnExpln,
|
||||
nowVlCn: item.nowVlCn ?? "-",
|
||||
compVlCn: item.compVlCn ?? "-",
|
||||
prcsYn: PRCS_YN_LABEL[item.prcsYn] ?? item.prcsYn,
|
||||
pbcpAprvYn: item.pbcpAprvYn,
|
||||
regDt: (item.regDt ?? "").slice(0, 16),
|
||||
mdfcnDt: (item.mdfcnDt ?? "").slice(0, 16),
|
||||
prcsOpnnExpln: item.prcsOpnnExpln ?? "",
|
||||
};
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const fetchVerificationResultPage = useCallback(
|
||||
async (vrfcMthdCd: "NV" | "IMR", pageIndex: number) => {
|
||||
async (vrfcMthdCd: VerificationMethodCd, page: number) => {
|
||||
if (!stableQueryContext) return null;
|
||||
const param: VerificationResultListRequest = {
|
||||
sewerBzmnCd: stableQueryContext.sewerBzmnCd,
|
||||
@@ -224,7 +229,7 @@ export function VerificationResultDialog({
|
||||
pbcpAprvYn: "N",
|
||||
vrfcMthdCd,
|
||||
prcsYnList: "0",
|
||||
page: pageIndex + 1,
|
||||
page: page + 1,
|
||||
size: 10000,
|
||||
};
|
||||
return statisticsApi.getVerificationResultList(param);
|
||||
@@ -232,81 +237,56 @@ export function VerificationResultDialog({
|
||||
[stableQueryContext],
|
||||
);
|
||||
|
||||
const loadInitial = useCallback(async () => {
|
||||
if (!stableQueryContext) {
|
||||
setErrorMessage("조회 조건이 없어 검증 결과를 불러올 수 없습니다.");
|
||||
return;
|
||||
}
|
||||
setErrorMessage(null);
|
||||
setNormalLoading(true);
|
||||
setImrLoading(true);
|
||||
setNormalPageIndex(0);
|
||||
setImrPageIndex(0);
|
||||
try {
|
||||
const [nvRes, imrRes] = await Promise.all([
|
||||
fetchVerificationResultPage("NV", 0),
|
||||
fetchVerificationResultPage("IMR", 0),
|
||||
]);
|
||||
const nvList = nvRes?.data?.verifyResultList ?? [];
|
||||
const imrList = imrRes?.data?.verifyResultList ?? [];
|
||||
setNormalRows(nvList.map(mapItemToRow));
|
||||
setImrRows(imrList.map(mapItemToRow));
|
||||
setNormalPageCount(nvRes?.data?.pageInfo?.totalPages ?? 1);
|
||||
setImrPageCount(imrRes?.data?.pageInfo?.totalPages ?? 1);
|
||||
} catch {
|
||||
setNormalRows([]);
|
||||
setImrRows([]);
|
||||
setNormalPageCount(1);
|
||||
setImrPageCount(1);
|
||||
setErrorMessage("검증 결과 조회 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
setNormalLoading(false);
|
||||
setImrLoading(false);
|
||||
setNormalCheckedIndices(new Set());
|
||||
setImrCheckedIndices(new Set());
|
||||
}
|
||||
}, [fetchVerificationResultPage, mapItemToRow, stableQueryContext]);
|
||||
|
||||
const handleNormalPageChange = useCallback(
|
||||
async (pageIndex: number) => {
|
||||
if (pageIndex === normalPageIndex || !stableQueryContext) return;
|
||||
const loadPage = useCallback(
|
||||
async (nextPageIndex: number) => {
|
||||
if (!stableQueryContext) {
|
||||
setErrorMessage("조회 조건이 없어 검증 결과를 불러올 수 없습니다.");
|
||||
return;
|
||||
}
|
||||
setErrorMessage(null);
|
||||
setNormalLoading(true);
|
||||
setLoading(true);
|
||||
try {
|
||||
const response = await fetchVerificationResultPage("NV", pageIndex);
|
||||
const list = response?.data?.verifyResultList ?? [];
|
||||
setNormalRows(list.map(mapItemToRow));
|
||||
setNormalPageCount(response?.data?.pageInfo?.totalPages ?? 1);
|
||||
setNormalPageIndex(pageIndex);
|
||||
const responses = await Promise.all(
|
||||
VERIFICATION_METHOD_CODES.map((code) =>
|
||||
fetchVerificationResultPage(code, nextPageIndex),
|
||||
),
|
||||
);
|
||||
const merged: VerificationResultGridRow[] = [];
|
||||
let maxPageCount = 1;
|
||||
VERIFICATION_METHOD_CODES.forEach((code, index) => {
|
||||
const response = responses[index];
|
||||
const list = response?.data?.verifyResultList ?? [];
|
||||
merged.push(...list.map((item) => mapItemToRow(item, code)));
|
||||
maxPageCount = Math.max(
|
||||
maxPageCount,
|
||||
response?.data?.pageInfo?.totalPages ?? 1,
|
||||
);
|
||||
});
|
||||
setRows(merged);
|
||||
setPageCount(maxPageCount);
|
||||
setPageIndex(nextPageIndex);
|
||||
} catch {
|
||||
setErrorMessage("일반검증 내역 조회 중 오류가 발생했습니다.");
|
||||
setRows([]);
|
||||
setPageCount(1);
|
||||
setErrorMessage("검증 결과 조회 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
setNormalLoading(false);
|
||||
setNormalCheckedIndices(new Set());
|
||||
setLoading(false);
|
||||
setCheckedIndices(new Set());
|
||||
}
|
||||
},
|
||||
[fetchVerificationResultPage, mapItemToRow, normalPageIndex, stableQueryContext],
|
||||
[fetchVerificationResultPage, mapItemToRow, stableQueryContext],
|
||||
);
|
||||
|
||||
const handleImrPageChange = useCallback(
|
||||
async (pageIndex: number) => {
|
||||
if (pageIndex === imrPageIndex || !stableQueryContext) return;
|
||||
setErrorMessage(null);
|
||||
setImrLoading(true);
|
||||
try {
|
||||
const response = await fetchVerificationResultPage("IMR", pageIndex);
|
||||
const list = response?.data?.verifyResultList ?? [];
|
||||
setImrRows(list.map(mapItemToRow));
|
||||
setImrPageCount(response?.data?.pageInfo?.totalPages ?? 1);
|
||||
setImrPageIndex(pageIndex);
|
||||
} catch {
|
||||
setErrorMessage("I-MR 검증내역 조회 중 오류가 발생했습니다.");
|
||||
} finally {
|
||||
setImrLoading(false);
|
||||
setImrCheckedIndices(new Set());
|
||||
}
|
||||
const loadInitial = useCallback(async () => {
|
||||
await loadPage(0);
|
||||
}, [loadPage]);
|
||||
|
||||
const handlePageChange = useCallback(
|
||||
async (nextPageIndex: number) => {
|
||||
if (nextPageIndex === pageIndex || !stableQueryContext) return;
|
||||
await loadPage(nextPageIndex);
|
||||
},
|
||||
[fetchVerificationResultPage, mapItemToRow, imrPageIndex, stableQueryContext],
|
||||
[loadPage, pageIndex, stableQueryContext],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -317,58 +297,32 @@ export function VerificationResultDialog({
|
||||
void loadInitial();
|
||||
}, [loadInitial, open, resetState]);
|
||||
|
||||
/** 조회된 행에 예외사유 텍스트가 있으면 체크바·체크 인덱스와 맞춤 */
|
||||
useEffect(() => {
|
||||
if (normalLoading) return;
|
||||
if (loading) return;
|
||||
const id = requestAnimationFrame(() => {
|
||||
setNormalCheckedIndices((prev) => {
|
||||
setCheckedIndices((prev) => {
|
||||
const next = new Set(prev);
|
||||
normalRows.forEach((row, itemIndex) => {
|
||||
rows.forEach((row, itemIndex) => {
|
||||
const has = String(row.prcsOpnnExpln ?? "").trim().length > 0;
|
||||
setRowCheckByItemIndex(normalGridRef, itemIndex, has);
|
||||
setRowCheckByItemIndex(gridRef, itemIndex, has);
|
||||
if (has) next.add(itemIndex);
|
||||
});
|
||||
return next;
|
||||
});
|
||||
});
|
||||
return () => cancelAnimationFrame(id);
|
||||
}, [normalRows, normalLoading]);
|
||||
|
||||
useEffect(() => {
|
||||
if (imrLoading) return;
|
||||
const id = requestAnimationFrame(() => {
|
||||
setImrCheckedIndices((prev) => {
|
||||
const next = new Set(prev);
|
||||
imrRows.forEach((row, itemIndex) => {
|
||||
const has = String(row.prcsOpnnExpln ?? "").trim().length > 0;
|
||||
setRowCheckByItemIndex(imrGridRef, itemIndex, has);
|
||||
if (has) next.add(itemIndex);
|
||||
});
|
||||
return next;
|
||||
});
|
||||
});
|
||||
return () => cancelAnimationFrame(id);
|
||||
}, [imrRows, imrLoading]);
|
||||
}, [rows, loading]);
|
||||
|
||||
const handleExceptionSubmitClick = useCallback(async () => {
|
||||
const nvGrid = getNormalGridDataRef.current?.() ?? [];
|
||||
const imGrid = getImrGridDataRef.current?.() ?? [];
|
||||
const gridRows = getGridDataRef.current?.() ?? [];
|
||||
const payload: VerificationExceptionSubmitItem[] = [];
|
||||
const pushChecked = (
|
||||
indices: Set<number>,
|
||||
gridRows: VerificationResultGridRow[],
|
||||
idRows: VerificationResultGridRow[],
|
||||
) => {
|
||||
indices.forEach((idx) => {
|
||||
const prcsOpnnExpln = String(gridRows[idx]?.prcsOpnnExpln ?? "").trim();
|
||||
if (!prcsOpnnExpln) return;
|
||||
const vrfcSn = Number(idRows[idx]?.vrfcSn);
|
||||
if (!Number.isFinite(vrfcSn)) return;
|
||||
payload.push({ vrfcSn, prcsOpnnExpln });
|
||||
});
|
||||
};
|
||||
pushChecked(normalCheckedIndices, nvGrid, normalRows);
|
||||
pushChecked(imrCheckedIndices, imGrid, imrRows);
|
||||
checkedIndices.forEach((idx) => {
|
||||
const prcsOpnnExpln = String(gridRows[idx]?.prcsOpnnExpln ?? "").trim();
|
||||
if (!prcsOpnnExpln) return;
|
||||
const vrfcSn = Number(rows[idx]?.vrfcSn);
|
||||
if (!Number.isFinite(vrfcSn)) return;
|
||||
payload.push({ vrfcSn, prcsOpnnExpln });
|
||||
});
|
||||
if (payload.length === 0) {
|
||||
alert("작성된 예외 제출 항목이 없습니다.");
|
||||
return;
|
||||
@@ -402,75 +356,13 @@ export function VerificationResultDialog({
|
||||
}
|
||||
}, [
|
||||
alert,
|
||||
imrCheckedIndices,
|
||||
imrRows,
|
||||
normalCheckedIndices,
|
||||
normalRows,
|
||||
checkedIndices,
|
||||
rows,
|
||||
onExceptionSubmitted,
|
||||
onOpenChange,
|
||||
stableQueryContext,
|
||||
]);
|
||||
|
||||
const renderGrid = (
|
||||
rows: VerificationResultGridRow[],
|
||||
setRows: Dispatch<SetStateAction<VerificationResultGridRow[]>>,
|
||||
pageIndex: number,
|
||||
pageCount: number,
|
||||
onPageIndexChange: (page: number) => void,
|
||||
loading: boolean,
|
||||
gridRef: MutableRefObject<RealGridReact | null>,
|
||||
getGridDataRef: MutableRefObject<(() => VerificationResultGridRow[]) | null>,
|
||||
onPrcsOpnnExplnCellEdited: (params: CellEditedCallbackParams) => void,
|
||||
setCheckedIndices: Dispatch<SetStateAction<Set<number>>>,
|
||||
) => {
|
||||
if (!loading && rows.length === 0) {
|
||||
return <p className="p-6 text-center text-[1.3rem] text-muted-foreground">{emptyMessage}</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative space-y-2">
|
||||
<DataGrid
|
||||
columnInfo={verificationSubmitResultColumnInfo}
|
||||
rowData={rows}
|
||||
setRowData={setRows as Dispatch<SetStateAction<Record<string, string | number>[]>>}
|
||||
isExcelImport={false}
|
||||
isExcelExport={false}
|
||||
showHeaderCheckbox
|
||||
enableSort={false}
|
||||
getGridRef={gridRef}
|
||||
getGridDataRef={getGridDataRef}
|
||||
onCellEdited={onPrcsOpnnExplnCellEdited}
|
||||
onItemChecked={(itemIndex, checked) => {
|
||||
setCheckedIndices((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (checked) next.add(itemIndex);
|
||||
else next.delete(itemIndex);
|
||||
return next;
|
||||
});
|
||||
}}
|
||||
onItemAllChecked={(checked) => {
|
||||
setCheckedIndices(
|
||||
checked ? new Set(rows.map((_, i) => i)) : new Set(),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<VerificationResultHistoryPagination
|
||||
pageCount={Math.max(pageCount, 1)}
|
||||
pageIndex={Math.max(pageIndex, 0)}
|
||||
onPageIndexChange={onPageIndexChange}
|
||||
className="mx-2 mb-2"
|
||||
/>
|
||||
{loading && (
|
||||
<div className="absolute inset-0 z-10 rounded-md [data-theme='black']:bg-transparent bg-white/40 flex items-center justify-center">
|
||||
<div className="relative size-[5rem]">
|
||||
<LoadingWithAnimation color="primary" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const titleSuffix = useMemo(() => {
|
||||
if (!stableQueryContext) return "";
|
||||
const sgg = stableQueryContext.sggNm?.trim() ? ` ${stableQueryContext.sggNm}` : "";
|
||||
@@ -493,33 +385,56 @@ export function VerificationResultDialog({
|
||||
</p>
|
||||
)}
|
||||
<section className="rounded-md border border-border">
|
||||
<h3 className="border-b border-border px-4 py-2 text-[1.35rem] font-semibold">일반검증 내역</h3>
|
||||
{renderGrid(
|
||||
normalRows,
|
||||
setNormalRows,
|
||||
normalPageIndex,
|
||||
normalPageCount,
|
||||
handleNormalPageChange,
|
||||
normalLoading,
|
||||
normalGridRef,
|
||||
getNormalGridDataRef,
|
||||
onNormalPrcsOpnnExplnEdited,
|
||||
setNormalCheckedIndices,
|
||||
)}
|
||||
</section>
|
||||
<section className="rounded-md border border-border">
|
||||
<h3 className="border-b border-border px-4 py-2 text-[1.35rem] font-semibold">I-MR 검증내역</h3>
|
||||
{renderGrid(
|
||||
imrRows,
|
||||
setImrRows,
|
||||
imrPageIndex,
|
||||
imrPageCount,
|
||||
handleImrPageChange,
|
||||
imrLoading,
|
||||
imrGridRef,
|
||||
getImrGridDataRef,
|
||||
onImrPrcsOpnnExplnEdited,
|
||||
setImrCheckedIndices,
|
||||
{!loading && rows.length === 0 ? (
|
||||
<p className="p-6 text-center text-[1.3rem] text-muted-foreground">
|
||||
{emptyMessage}
|
||||
</p>
|
||||
) : (
|
||||
<div className="relative space-y-2">
|
||||
<DataGrid
|
||||
columnInfo={verificationSubmitResultColumnInfo}
|
||||
rowData={rows}
|
||||
setRowData={
|
||||
setRows as Dispatch<
|
||||
SetStateAction<Record<string, string | number>[]>
|
||||
>
|
||||
}
|
||||
isExcelImport={false}
|
||||
isExcelExport={false}
|
||||
showHeaderCheckbox
|
||||
enableSort={false}
|
||||
getGridRef={gridRef}
|
||||
getGridDataRef={getGridDataRef}
|
||||
onCellEdited={onPrcsOpnnExplnEdited}
|
||||
cellStyleCallback={verificationMthdCellStyle}
|
||||
onItemChecked={(itemIndex, checked) => {
|
||||
setCheckedIndices((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (checked) next.add(itemIndex);
|
||||
else next.delete(itemIndex);
|
||||
return next;
|
||||
});
|
||||
}}
|
||||
onItemAllChecked={(checked) => {
|
||||
setCheckedIndices(
|
||||
checked ? new Set(rows.map((_, i) => i)) : new Set(),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<VerificationResultHistoryPagination
|
||||
pageCount={Math.max(pageCount, 1)}
|
||||
pageIndex={Math.max(pageIndex, 0)}
|
||||
onPageIndexChange={handlePageChange}
|
||||
className="mx-2 mb-2"
|
||||
/>
|
||||
{loading && (
|
||||
<div className="absolute inset-0 z-10 flex items-center justify-center rounded-md bg-white/40 [data-theme='black']:bg-transparent">
|
||||
<div className="relative size-[5rem]">
|
||||
<LoadingWithAnimation color="primary" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user