From 71e412d030f8084ba4cf46d6503015786f88e994 Mon Sep 17 00:00:00 2001 From: rsone001 Date: Tue, 13 Jan 2026 11:46:28 +0900 Subject: [PATCH] =?UTF-8?q?st:=20feat:=20-=20compact=20grid(1/2=20?= =?UTF-8?q?=EB=84=93=EC=9D=B4)=20&=20split=20grid(1/2=20=EB=84=93=EC=9D=B4?= =?UTF-8?q?=202=EA=B0=9C)=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20-=20=EC=8B=9C=EC=84=A4=EB=B3=84=20?= =?UTF-8?q?=EC=84=A4=EC=B9=98=20=ED=98=84=ED=99=A9=20=EA=B4=80=EB=A6=AC=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80=20-=20=ED=86=B5?= =?UTF-8?q?=EA=B3=84=EC=9E=85=EB=A0=A5=ED=98=84=ED=99=A9(=EA=B2=80?= =?UTF-8?q?=ED=86=A0)=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20&=20?= =?UTF-8?q?=EC=BB=AC=EB=9F=BC=20=ED=8C=8C=EC=9D=BC=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../button/InstallationStatusButton.tsx | 16 +++++ apps/st/src/components/module/TabDataGrid.tsx | 60 ++++++++++++++++++- .../statistics/input/SewagePipeInp.tsx | 13 ++-- ...utSatusRvw.tsx => StatsInputStatusRvw.tsx} | 8 +-- apps/st/src/components/type/DataGrid.type.ts | 8 ++- .../sewagePipe/ConnectionStatusInpColumn.ts | 10 +++- ...umnRvw.ts => StatsInputStatusColumnRvw.ts} | 2 +- 7 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 apps/st/src/components/button/InstallationStatusButton.tsx rename apps/st/src/components/statistics/review/{StatsInputSatusRvw.tsx => StatsInputStatusRvw.tsx} (78%) rename apps/st/src/components/util/column/review/{StatsInputSatusColumnRvw.ts => StatsInputStatusColumnRvw.ts} (98%) diff --git a/apps/st/src/components/button/InstallationStatusButton.tsx b/apps/st/src/components/button/InstallationStatusButton.tsx new file mode 100644 index 000000000..fffe4bb9c --- /dev/null +++ b/apps/st/src/components/button/InstallationStatusButton.tsx @@ -0,0 +1,16 @@ +import { Button } from "@common/components"; + +interface InstallationStatusButtonProps { + installationStatusFunc: () => void; +} + +const InstallationStatusButton = ({ installationStatusFunc }: InstallationStatusButtonProps) => { + return ( + + ); +}; + +export default InstallationStatusButton; \ No newline at end of file diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index bda80c2c6..9fe1d4fe1 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -3,7 +3,7 @@ import { ValueType } from "realgrid" import RealGrid, { GridFitStyle } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" -import type { TabDataGridProps } from "../type/DataGrid.type" +import type { TabDataGridProps, ColumnInfo } from "../type/DataGrid.type" import JSZip from "jszip" import * as XLSX from "xlsx" import { useAlertStore } from "@/shared/lib"; @@ -11,6 +11,7 @@ import { useTabStore } from "@/store/tab-store" import { Tabs, TabsList, TabsTrigger, TabsContent } from "@common/components"; import { Button } from "@common/components"; +import SplitDataGrid from "./SplitDataGrid"; // RealGrid 타입 확장 declare module "realgrid" { @@ -281,6 +282,61 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r {columnInfo.map((info) => { const tabKey = info.tabKey; + + // isSplitGrid가 true이고 left, right가 있으면 SplitDataGrid 사용 + if (info.isSplitGrid && info.left && info.right) { + const leftRowData = rowDataMap.get(info.left.tabKey || `${tabKey}_left`) || []; + const rightRowData = rowDataMap.get(info.right.tabKey || `${tabKey}_right`) || []; + + // ColumnInfoList를 ColumnInfo로 변환 + const leftColumnInfo: ColumnInfo = { + columns: info.left.columns || [], + columnLayout: info.left.columnLayout || [] + }; + const rightColumnInfo: ColumnInfo = { + columns: info.right.columns || [], + columnLayout: info.right.columnLayout || [] + }; + + return ( + + { + setRowDataMap(prev => { + const newMap = new Map(prev); + const leftTabKey = info.left?.tabKey || `${tabKey}_left`; + const currentData = newMap.get(leftTabKey) || []; + const newData = typeof updater === 'function' ? updater(currentData) : updater; + newMap.set(leftTabKey, newData); + return newMap; + }); + }} + setRightRowData={(updater) => { + setRowDataMap(prev => { + const newMap = new Map(prev); + const rightTabKey = info.right?.tabKey || `${tabKey}_right`; + const currentData = newMap.get(rightTabKey) || []; + const newData = typeof updater === 'function' ? updater(currentData) : updater; + newMap.set(rightTabKey, newData); + return newMap; + }); + }} + /> + + ); + } + + // 일반 그리드 사용 + if (!info.columns || !info.columnLayout) { + return null; + } const { columns, columnLayout } = info; const currentRowData = rowDataMap.get(tabKey) || []; @@ -334,7 +390,7 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, isExcelExport = true, r if (!gridView) return; const currentInfo = columnInfo.find(info => info.tabKey === tabKey); - if (!currentInfo) return; + if (!currentInfo || !currentInfo.columns) return; gridView.setDisplayOptions({ fitStyle: GridFitStyle.EVEN diff --git a/apps/st/src/components/statistics/input/SewagePipeInp.tsx b/apps/st/src/components/statistics/input/SewagePipeInp.tsx index c1a0cd79d..7fc54d56c 100644 --- a/apps/st/src/components/statistics/input/SewagePipeInp.tsx +++ b/apps/st/src/components/statistics/input/SewagePipeInp.tsx @@ -1,21 +1,18 @@ import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; -import { TabDataGrid } from '@rsone/components'; +// import { TabDataGrid } from '@rsone/components'; +import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; import SaveButton from "@/components/button/SaveButton"; import LastYearDataButton from "@/components/button/LastYearDataButton"; import SubmitExceptionButton from "@/components/button/SubmitExceptionButton"; -import OperateDateButton from "@/components/button/OperateDataButton"; import { RegionalFacilityStatusInpColumn } from "@/components/util/column/input/sewagePipe/RegionalFacilityStatusInpColumn"; import { FacilityInstallStatusInpColumn } from "@/components/util/column/input/sewagePipe/FacilityInstallStatusInpColumn"; import { PipeTypeStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeTypeStatusInpColumn"; import { PipeDiameterStatusInpColumn } from "@/components/util/column/input/sewagePipe/PipeDiameterStatusInpColumn"; import { ManholeStatusInpColumn } from "@/components/util/column/input/sewagePipe/ManholeStatusInpColumn"; -import { - AdminAreaConnectionInpColumn, - TreatmentPlantConnectionInpColumn -} from "@/components/util/column/input/sewagePipe/ConnectionStatusInpColumn"; +import { ConnectionStatusInpColumn } from "@/components/util/column/input/sewagePipe/ConnectionStatusInpColumn"; // 하수도 통계 관리 > 02. 하수관로 const SewagePipeInp = () => { @@ -27,9 +24,7 @@ const SewagePipeInp = () => { PipeTypeStatusInpColumn, PipeDiameterStatusInpColumn, ManholeStatusInpColumn, - // 일단 각 tab으로 구현 - AdminAreaConnectionInpColumn, - TreatmentPlantConnectionInpColumn + ConnectionStatusInpColumn, ]; const SubmitExceptionFunc = () => { diff --git a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx similarity index 78% rename from apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx rename to apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx index 1073d5eb6..66ccd3507 100644 --- a/apps/st/src/components/statistics/review/StatsInputSatusRvw.tsx +++ b/apps/st/src/components/statistics/review/StatsInputStatusRvw.tsx @@ -6,9 +6,9 @@ import ReviewOpinionButton from "@/components/button/ReviewOpinionButton"; import ReturnButton from "@/components/button/ReturnButton"; import { useState } from "react"; -import { StatsInputSatusInfoList } from "@/components/util/column/review/StatsInputSatusColumnRvw"; +import { StatsInputStatusInfoList } from "@/components/util/column/review/StatsInputStatusColumnRvw"; -const StatsInputSatusRvw = () => { +const StatsInputStatusRvw = () => { const approveFunc = () => { console.log('approveFunc'); @@ -37,9 +37,9 @@ const StatsInputSatusRvw = () => { - + ); } -export default StatsInputSatusRvw; \ No newline at end of file +export default StatsInputStatusRvw; \ No newline at end of file diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index d89159ff3..2717f4ff8 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -56,11 +56,14 @@ export type ColumnInfo = { export type ColumnInfoList = { tabKey: string; // 탭을 식별하는 고유 키 (필수), server(api)에 전송할 변수 값 - columns: ColumnConfig[]; - columnLayout: ColumnLayoutItem[]; + columns?: ColumnConfig[]; // 일반 그리드용 (isSplitGrid가 false일 때) + columnLayout?: ColumnLayoutItem[]; // 일반 그리드용 (isSplitGrid가 false일 때) rowStartNum?: number; fixedColumns?: number; tabLabel?: string; // 탭에 표시될 레이블 + isSplitGrid?: boolean; // 5:5 분리형 그리드 유무 + left?: ColumnInfoList; // SplitDataGrid용 왼쪽 그리드 정보 + right?: ColumnInfoList; // SplitDataGrid용 오른쪽 그리드 정보 } export type DataGridProps = { @@ -84,6 +87,7 @@ export type TabDataGridProps = { showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) rowDataMap: Map[]>; setRowDataMap: React.Dispatch[]>>>; + isSplitGrid?: boolean; // 5:5 분리형 그리드 유무 }; export type SplitDataGridProps = { diff --git a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts index 39229f1dc..03a3157da 100644 --- a/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts +++ b/apps/st/src/components/util/column/input/sewagePipe/ConnectionStatusInpColumn.ts @@ -30,7 +30,7 @@ export const AdminAreaConnectionInpColumn = { }; // Tab 6-2: 하수처리장별 연결 현황 (왼쪽 그리드) -export const TreatmentPlantConnectionInpColumn = { +export const TreatPlantConnectionInpColumn = { columns: [ // 하수처리장 정보 { name: 'bscFctNm', fieldName: '하수처리장명', header: { text: '하수처리장명' } }, @@ -52,4 +52,12 @@ export const TreatmentPlantConnectionInpColumn = { fixedColumns: 1, tabKey: 'treatmentPlantConnectionInp', tabLabel: '하수처리장별 연결 현황' +}; + +export const ConnectionStatusInpColumn = { + tabKey: 'treatmentPlantConnectionInp', + tabLabel: '시설별 현황 관리', + isSplitGrid: true, + left: AdminAreaConnectionInpColumn, + right: TreatPlantConnectionInpColumn, }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts b/apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts similarity index 98% rename from apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts rename to apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts index 45a824503..a51fb9401 100644 --- a/apps/st/src/components/util/column/review/StatsInputSatusColumnRvw.ts +++ b/apps/st/src/components/util/column/review/StatsInputStatusColumnRvw.ts @@ -34,7 +34,7 @@ const rawStatsInputStatusList = { ] }; -export const StatsInputSatusInfoList = { +export const StatsInputStatusInfoList = { ...rawStatsInputStatusList, columns: rawStatsInputStatusList.columns.map(col => ({ ...col,