From 479cf5c4a0333ff35b992224ae8d81b5a7f9bf4c Mon Sep 17 00:00:00 2001 From: ljpark Date: Mon, 7 Sep 2026 16:56:35 +0900 Subject: [PATCH] =?UTF-8?q?sn:=20=EB=8B=A4=EB=8B=A8header=20=EB=AC=B6?= =?UTF-8?q?=EC=9D=8C=20=EC=B2=98=EB=A6=AC=20=EC=99=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgedPipeStatusByCtpvPopupPage.tsx | 77 +++++++++++----- .../agedPipeStatusByCtpvExport.ts | 80 +++++++++++++---- .../001-fe-SFR-011-001-시도별 노후관로현황-작업카드.md | 9 +- .../components/src/ui/data-table/index.tsx | 90 ++++++++++++------- .../common/components/src/ui/table/table.css | 12 +++ 5 files changed, 192 insertions(+), 76 deletions(-) diff --git a/apps/sn/app/(map-layout)/map/components/agedPipeStatusByCtpv/AgedPipeStatusByCtpvPopupPage.tsx b/apps/sn/app/(map-layout)/map/components/agedPipeStatusByCtpv/AgedPipeStatusByCtpvPopupPage.tsx index 293ae3fe3..05dd3447c 100644 --- a/apps/sn/app/(map-layout)/map/components/agedPipeStatusByCtpv/AgedPipeStatusByCtpvPopupPage.tsx +++ b/apps/sn/app/(map-layout)/map/components/agedPipeStatusByCtpv/AgedPipeStatusByCtpvPopupPage.tsx @@ -2,14 +2,23 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { Button, Input } from "@common/components"; -import { StandardPopupLayout } from "@common/business_components"; +import { + StandardDataTable, + StandardPopupLayout, +} from "@common/business_components"; +import { + getCoreRowModel, + getPaginationRowModel, + useReactTable, + type ColumnDef, + type PaginationState, +} from "@tanstack/react-table"; import { getRawJson } from "@/components/lib/api"; import LoadingOverlay from "@/components/ui/LoadingBar"; import { useAlertStore } from "@/shared/lib"; import { windowPopupDefinitions } from "@/features/windowPopup/model/popupDefinitions"; import { AGED_PIPE_STATUS_BY_CTPV_DEFAULT_ELAPSED_YEARS, - buildAgedPipeStatusByCtpvHeadList, buildAgedPipeStatusYearOptions, getAgedPipeStatusByCtpvValidationMessage, normalizeAgedPipeStatusByCtpvResponse, @@ -20,7 +29,6 @@ import { type AgedPipeStatusByCtpvRow, } from "./agedPipeStatusByCtpvUtils"; import { downloadAgedPipeStatusByCtpvExcel } from "./agedPipeStatusByCtpvExport"; -import MapPopupDataTable from "@/features/windowPopup/ui/MapPopupDataTable"; import PopupSearchPanel from "@/features/windowPopup/ui/PopupSearchPanel"; // CS 목록과 동일하게 한 페이지에는 최대 10개 시도만 표시한다. @@ -52,21 +60,48 @@ export default function AgedPipeStatusByCtpvPopupPage() { const [currentPage, setCurrentPage] = useState(1); const yearOptions = useMemo(() => buildAgedPipeStatusYearOptions(), []); - const headList = useMemo( + const columns = useMemo[]>( () => [ - { id: "rowNumber", title: "순번", widthPercent: 7 }, - ...buildAgedPipeStatusByCtpvHeadList(years), + { accessorKey: "rowNumber", header: "순번" }, + { accessorKey: "ctpvNm", header: "시도" }, + ...years.map((year) => ({ + id: `year_${year}`, + header: `${year}년`, + columns: [ + { + accessorKey: `year${year}TotalLengthKm`, + header: "전체관로연장(km)", + }, + { + accessorKey: `year${year}AgedLengthKm`, + header: "노후관로연장(km)", + }, + { + accessorKey: `year${year}AgedRate`, + header: "노후화율(%)", + }, + ], + })), ], [years], ); - const pageRows = useMemo( - () => - rows.slice( - (currentPage - 1) * AGED_PIPE_STATUS_PAGE_SIZE, - currentPage * AGED_PIPE_STATUS_PAGE_SIZE, - ), - [currentPage, rows], - ); + + const pagination: PaginationState = { + pageIndex: currentPage - 1, + pageSize: AGED_PIPE_STATUS_PAGE_SIZE, + }; + const table = useReactTable({ + data: rows, + columns, + state: { pagination }, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + onPaginationChange: (updater) => { + const next = + typeof updater === "function" ? updater(pagination) : updater; + setCurrentPage(next.pageIndex + 1); + }, + }); const loadRows = useCallback( async (nextFilters: AgedPipeStatusByCtpvFilters) => { @@ -249,18 +284,12 @@ export default function AgedPipeStatusByCtpvPopupPage() { - > - } - headlist={headList} + 2 ? "horizontal" : "none"} - minTableWidth={years.length > 2 ? "120rem" : "100%"} + scrollMode="horizontal" + minTableWidth={years.length > 0 ? "120rem" : "100%"} actions={