From d065fe669bd53a176d119167e7043c4d35a5f0cb Mon Sep 17 00:00:00 2001 From: rsone001 Date: Wed, 31 Dec 2025 13:17:32 +0900 Subject: [PATCH] =?UTF-8?q?st:=20refactor:=20-=20data=20state=20=EC=84=A0?= =?UTF-8?q?=EC=96=B8=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD=20-=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=ED=95=84=EB=93=9C=20=ED=83=80?= =?UTF-8?q?=EC=9E=85=20=EB=B0=8F=20format=20=EC=84=A4=EC=A0=95=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/st/src/components/module/DataGrid.tsx | 59 ++++++++++++++++- apps/st/src/components/module/TabDataGrid.tsx | 63 +++++++++++++++++-- .../management/PrivateSewageFacilityMng.tsx | 4 +- .../management/SewagePipeMaintainMng.tsx | 4 +- .../statistics/management/SewagePipeMng.tsx | 4 +- .../management/SewageReservoirPumpMng.tsx | 5 +- .../management/SewerageFinanceMng.tsx | 4 +- .../review/PrivateSewageFacilityRvw.tsx | 4 +- .../review/SewageExcretaRelatedRvw.tsx | 5 +- .../review/SewageExcretaSlurgeRvw.tsx | 4 +- .../review/SewagePipeMaintainRvw.tsx | 4 +- .../statistics/review/SewagePipeRvw.tsx | 4 +- .../review/SewageReservoirPumpRvw.tsx | 4 +- .../statistics/review/SewerageFinanceRvw.tsx | 4 +- .../review/SeweragePenetrationRateRvw.tsx | 6 +- .../review/SewerageServiceLevelRvw.tsx | 4 +- .../statistics/review/WaterReuseRvw.tsx | 5 +- apps/st/src/components/type/DataGrid.type.ts | 9 ++- .../SeweragePenetrationRateMngColumn.ts | 6 +- 19 files changed, 173 insertions(+), 29 deletions(-) diff --git a/apps/st/src/components/module/DataGrid.tsx b/apps/st/src/components/module/DataGrid.tsx index 1e518c1f8..d433573b8 100644 --- a/apps/st/src/components/module/DataGrid.tsx +++ b/apps/st/src/components/module/DataGrid.tsx @@ -1,4 +1,5 @@ import { useRef, useEffect } from "react" +import { ValueType } from "realgrid" import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" @@ -35,7 +36,7 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); -const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, onRowsChange, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { +const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, showHeaderCheckbox = false, rowData, setRowData }: DataGridProps) => { const { columns, columnLayout } = columnInfo; const gridRef = useRef(null); const fileInputRef = useRef(null); @@ -174,6 +175,7 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, dataRows.push(rowData); } } + setRowData(dataRows); } catch (error) { console.error('엑셀 파일 파싱 오류:', error); @@ -203,9 +205,60 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, }; useEffect(() => { - if (!gridRef.current?.gridView) return; + if (!gridRef.current?.gridView || !gridRef.current?.dataProvider) return; const gridView = gridRef.current.gridView; + const dataProvider = gridRef.current.dataProvider; + + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } (gridView.displayOptions as DisplayOptions).fitStyle = GridFitStyle.EVEN; gridView.header.height = 60; @@ -297,6 +350,8 @@ const DataGrid = ({ columnInfo, rowStartNum, isExcelImport = true, fixedColumns, key={column.name} name={column.name} fieldName={column.fieldName} + valueType={column.valueType ? column.valueType : ValueType.TEXT} + {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.000' })} header={column.header} editable={column.editable} footer={column.footer ? { diff --git a/apps/st/src/components/module/TabDataGrid.tsx b/apps/st/src/components/module/TabDataGrid.tsx index 071d32c87..9de1fe297 100644 --- a/apps/st/src/components/module/TabDataGrid.tsx +++ b/apps/st/src/components/module/TabDataGrid.tsx @@ -1,4 +1,5 @@ import { useRef, useEffect, useState } from "react" +import { ValueType } from "realgrid" import RealGrid, { GridFitStyle, type DisplayOptions } from "realgrid" import { RealGridReact, RGDataColumn } from "realgrid-react" @@ -36,16 +37,13 @@ if (typeof window !== "undefined") { RealGrid.setLicenseKey(process.env.NEXT_PUBLIC_ST_REALGRID_KEY || ''); -const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCheckbox = false }: TabDataGridProps) => { +const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCheckbox = false, rowDataMap, setRowDataMap }: TabDataGridProps) => { // 각 탭별로 그리드 ref와 데이터를 관리 const gridRefs = useRef>(new Map()); const fileInputRefs = useRef>(new Map()); const { setMessage: alert } = useAlertStore((state) => state); const activeTabId = useTabStore((state) => state.activeTabId); const menuList = useTabStore((state) => state.menuList); - - // 각 탭별로 데이터를 관리 (key: tabKey) - const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const [activeTab, setActiveTab] = useState(() => { // 초기 활성 탭을 첫 번째 tabKey로 설정 const firstTab = columnInfo[0]; @@ -391,6 +389,61 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCh colCount: currentInfo.fixedColumns, }); } + + // valueType이 설정된 컬럼에 대해 필드의 dataType을 명시적으로 설정 + // autoGenerateField={true}일 때 valueType prop만으로는 필드의 dataType이 설정되지 않을 수 있음 + if (el.dataProvider) { + const dataProvider = el.dataProvider; + const fieldsToSet: Array<{ fieldName: string; dataType: string }> = []; + const fieldMap = new Map(); + + currentInfo.columns.forEach(col => { + if (col.valueType && col.fieldName && !fieldMap.has(col.fieldName)) { + fieldMap.set(col.fieldName, col.valueType); + fieldsToSet.push({ + fieldName: col.fieldName, + dataType: col.valueType + }); + } + }); + + // 필드가 이미 존재하는지 확인하고, valueType이 설정된 필드만 업데이트 + if (fieldsToSet.length > 0) { + try { + // 기존 필드 정보 가져오기 + const existingFields = (dataProvider as { getFields?: () => Array<{ fieldName: string; dataType?: string }> }).getFields?.() || []; + const existingFieldMap = new Map(existingFields.map(f => [f.fieldName, f.dataType || 'text'])); + + // valueType이 설정된 필드 중 dataType이 다른 필드만 업데이트 + const fieldsToUpdate = fieldsToSet.filter(field => { + const existingDataType = existingFieldMap.get(field.fieldName); + return existingDataType !== field.dataType; + }); + + if (fieldsToUpdate.length > 0) { + // 기존 필드 정보를 유지하면서 dataType만 업데이트 + // 컬럼 정의에 valueType이 있으면 그것을 우선 사용, 없으면 기존 필드의 dataType 사용 + const allFields = existingFields.map(f => ({ + fieldName: f.fieldName, + dataType: fieldMap.get(f.fieldName) || f.dataType || 'text' + })); + + // 새로 추가할 필드가 있으면 추가 + fieldsToSet.forEach(field => { + if (!existingFieldMap.has(field.fieldName)) { + allFields.push({ fieldName: field.fieldName, dataType: field.dataType }); + } + }); + + // setFields를 호출하여 필드의 dataType 업데이트 + (dataProvider as { setFields: (fields: Array<{ fieldName: string; dataType: string }>) => void }) + .setFields(allFields); + } + } catch (error) { + console.warn('Failed to set field dataType:', error); + } + } + } }, 0); } } else { @@ -406,6 +459,8 @@ const TabDataGrid = ({ columnInfo, isExcelImport = true, rows = [], showHeaderCh key={column.name} name={column.name} fieldName={column.fieldName} + valueType={column.valueType ? column.valueType : ValueType.TEXT} + {...(column.valueType === ValueType.NUMBER && { numberFormat: column.dataFormat ? column.dataFormat : '#,##0.00' })} header={column.header} editable={column.editable} footer={column.footer ? { diff --git a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx b/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx index 76587ad8a..04aa41ebb 100644 --- a/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx +++ b/apps/st/src/components/statistics/management/PrivateSewageFacilityMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -9,6 +10,7 @@ import { PrivateSewageFacilityMngColumnInfoList } from "@/components/util/column // 하수도 통계 관리 > 08. 개인하수처리시설 const PrivateSewageFacilityMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const submitFunc = () => { // TODO: 제출 로직 구현 @@ -43,7 +45,7 @@ const PrivateSewageFacilityMng = () => { - + ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx index 66022298e..43f32fd7b 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMaintainMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -9,6 +10,7 @@ import { SewagePipeMaintainMngColumnInfoList } from "@/components/util/column/ma // 하수도 통계 관리 > 03. 하수관로 유지관리 const SewagePipeMaintainMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const submitFunc = () => { console.log('제출 로직 실행'); @@ -39,7 +41,7 @@ const SewagePipeMaintainMng = () => { - + ); }; diff --git a/apps/st/src/components/statistics/management/SewagePipeMng.tsx b/apps/st/src/components/statistics/management/SewagePipeMng.tsx index 18c912702..f236114e3 100644 --- a/apps/st/src/components/statistics/management/SewagePipeMng.tsx +++ b/apps/st/src/components/statistics/management/SewagePipeMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -17,6 +18,7 @@ import { // 하수도 통계 관리 > 02. 하수관로 const SewagePipeMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); // tab List const SewagePipeMngColumnInfoList = [ @@ -59,7 +61,7 @@ const SewagePipeMng = () => { - + ); }; diff --git a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx index fc0764f22..6ace6af10 100644 --- a/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx +++ b/apps/st/src/components/statistics/management/SewageReservoirPumpMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -9,6 +10,8 @@ import { SewageReservoirPumpMngColumnInfoList } from "@/components/util/column/m // 하수도 통계 관리 > 04. 하수저류 시설 및 빗물 펌프장 const SewageReservoirPumpMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); + const submitFunc = () => { console.log('submit'); // 제출 로직 @@ -38,7 +41,7 @@ const SewageReservoirPumpMng = () => { - + ); }; diff --git a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx b/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx index 221456318..a44c278ef 100644 --- a/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx +++ b/apps/st/src/components/statistics/management/SewerageFinanceMng.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SubmitButton from "@/components/button/SumitButton"; @@ -9,6 +10,7 @@ import { SewerageFinanceMngInfoList } from "@/components/util/column/management/ // 하수도 통계 관리 > 09. 하수도재정 const SewerageFinanceMng = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const submitFunc = () => { // TODO: 제출 로직 구현 @@ -41,7 +43,7 @@ const SewerageFinanceMng = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx index 31654806b..eeaf7c0a1 100644 --- a/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx +++ b/apps/st/src/components/statistics/review/PrivateSewageFacilityRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { PrivateSewageFacilityInfoListRvw } from "@/components/util/column/revie const PrivateSewageFacilityRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const PrivateSewageFacilityRvw = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx index 40f24137e..c16320006 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaRelatedRvw.tsx @@ -1,4 +1,4 @@ - +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -10,6 +10,7 @@ import { SewageExcretaRelatedInfoListRvw } from "@/components/util/column/review const SewageExcretaRelatedRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -42,7 +43,7 @@ const SewageExcretaRelatedRvw = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx index 2433ba89f..868585c19 100644 --- a/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageExcretaSlurgeRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewageExcretaSlurgeInfoList } from "@/components/util/column/review/Sew const SewageExcretaSlurgeRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewageExcretaSlurgeRvw = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx index 74c2f6f7c..23ce6be2c 100644 --- a/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeMaintainRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewagePipeMaintainColumnInfoListRvw } from "@/components/util/column/re const SewagePipeMaintainRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewagePipeMaintainRvw = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx index 634a21285..4dad5c699 100644 --- a/apps/st/src/components/statistics/review/SewagePipeRvw.tsx +++ b/apps/st/src/components/statistics/review/SewagePipeRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewagePipeColumnInfoListRvw } from "@/components/util/column/review/Sew const SewagePipeRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewagePipeRvw = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx index 9c7fc0c2e..60879519a 100644 --- a/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx +++ b/apps/st/src/components/statistics/review/SewageReservoirPumpRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewageReservoirPumpInfoListRvw } from "@/components/util/column/review/ const SewageReservoirPumpRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewageReservoirPumpRvw = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx index a91f0ee7a..eeae5b98a 100644 --- a/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageFinanceRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewerageFinanceInfoListRvw } from "@/components/util/column/review/Sewe const SewerageFinanceRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewerageFinanceRvw = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx index 37b2e0d24..a4c1bf5bc 100644 --- a/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx +++ b/apps/st/src/components/statistics/review/SeweragePenetrationRateRvw.tsx @@ -1,3 +1,5 @@ +import { ValueType } from "realgrid"; + import SearchForm from "@/components/module/SearchForm"; import DataGrid from "@/components/module/DataGrid"; @@ -21,12 +23,12 @@ const SeweragePenetrationRateRvw = () => { { name: 'lgbsn', fieldName: '중권역', header: { text: '중권역' } }, { name: 'mdmbsn', fieldName: '소권역', header: { text: '소권역' } }, { name: 'specl_cntrpln_ar', fieldName: '특별대책지역', header: { text: '특별대책지역' } }, - { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' } }, + { name: 'total_popl', fieldName: '총인구', header: { text: '총인구' }, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, { name: 'popl_sm', fieldName: '내국인', header: { text: '내국인' } }, { name: 'frgnr_popl_sm', fieldName: '외국인', header: { text: '외국인' } }, { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' } }, { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' } }, - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' } }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, valueType: ValueType.NUMBER }, { name: '계', fieldName: '계', header: { text: '계' } }, //공공하수처리인구 { name: '합계', fieldName: '합계', header: { text: '합계' } }, diff --git a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx index e128aa766..b55269ed3 100644 --- a/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx +++ b/apps/st/src/components/statistics/review/SewerageServiceLevelRvw.tsx @@ -1,3 +1,4 @@ +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -9,6 +10,7 @@ import { SewerageServiceLevelInfoListRvw } from "@/components/util/column/review const SewerageServiceLevelRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -41,7 +43,7 @@ const SewerageServiceLevelRvw = () => { - + ); }; diff --git a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx index ee7cc5f50..3dcc94d34 100644 --- a/apps/st/src/components/statistics/review/WaterReuseRvw.tsx +++ b/apps/st/src/components/statistics/review/WaterReuseRvw.tsx @@ -1,4 +1,4 @@ - +import { useState } from "react"; import SearchForm from "@/components/module/SearchForm"; import TabDataGrid from "@/components/module/TabDataGrid"; import SaveButton from "@/components/button/SaveButton"; @@ -10,6 +10,7 @@ import { WaterReuseInfoList } from "@/components/util/column/review/WaterReuseCo const WaterReuseRvw = () => { + const [rowDataMap, setRowDataMap] = useState[]>>(new Map()); const approveFunc = () => { console.log('approveFunc'); @@ -42,7 +43,7 @@ const WaterReuseRvw = () => { - + ); }; diff --git a/apps/st/src/components/type/DataGrid.type.ts b/apps/st/src/components/type/DataGrid.type.ts index c46a574c5..9877734a7 100644 --- a/apps/st/src/components/type/DataGrid.type.ts +++ b/apps/st/src/components/type/DataGrid.type.ts @@ -1,4 +1,5 @@ import React from "react"; +import { ValueType } from "realgrid"; // RealGrid 타입 정의 export type GridView = { @@ -30,6 +31,8 @@ export type ColumnConfig = { header: { text: string }; editable?: boolean; // 셀 편집 가능 여부 mergeCells?: boolean; // 같은 값이 연속될 때 셀 병합 여부 + valueType?: ValueType; + dataFormat?: string; footer?: { text?: string; expression?: 'sum' | 'avg' | 'count' | 'max' | 'min'; @@ -72,8 +75,10 @@ export type DataGridProps = { export type TabDataGridProps = { columnInfo: ColumnInfoList[]; - rows?: Record[]; + rows?: Record[]; isExcelImport?: boolean; // 엑셀 가져오기 유무 - onRowsChange?: (rows: Record[]) => void; + onRowsChange?: (rows: Record[]) => void; showHeaderCheckbox?: boolean; // 헤더 체크박스 표시 여부 (기본값: true) + rowDataMap: Map[]>; + setRowDataMap: React.Dispatch[]>>>; }; \ No newline at end of file diff --git a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts index b8d2c5684..4d0cc36d3 100644 --- a/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts +++ b/apps/st/src/components/util/column/management/SeweragePenetrationRateMngColumn.ts @@ -1,5 +1,5 @@ import { footerInt, footerDecimal1, footerDecimal3 } from "@/components/util/grid/footerSummary"; - +import { ValueType } from "realgrid"; /** * 하수도 통계 관리 > 01. 하수도 보급률 * 단일 Tab @@ -37,10 +37,10 @@ export const SeweragePenetrationRateMngColumnInfo = { { name: 'area', fieldName: '행정참고자료면적(㎢)', header: { text: '행정참고자료면적(㎢)' }, footer: footerDecimal3, editable: false }, // [자동계산] 총인구 (Nexacro: expr 존재) - 수정 불가 - { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' }, footer: footerInt, editable: false }, + { name: 'popltn_sm', fieldName: '총인구(명)', header: { text: '총인구(명)' }, footer: footerInt, editable: false, valueType: ValueType.NUMBER, dataFormat: '#,##0' }, // [입력필드] 총면적 (Nexacro: 입력 가능) - 수정 가능 - { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3 }, + { name: 'ar_sm', fieldName: '총면적(㎢)', header: { text: '총면적(㎢)' }, footer: footerDecimal3, valueType: ValueType.NUMBER }, // [자동계산] 하수처리구역 내 합계 - 수정 불가 { name: 'swge_proc_zone_inner_sm', fieldName: '합계', header: { text: '합계' }, footer: footerInt, editable: false },