st: refactor:

- data state 선언 위치 변경
- 데이터 필드 타입 및 format 설정 로직 추가
This commit is contained in:
2025-12-31 13:17:32 +09:00
parent 55b3752f49
commit d065fe669b
19 changed files with 173 additions and 29 deletions
+57 -2
View File
@@ -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<RealGridReact>(null);
const fileInputRef = useRef<HTMLInputElement>(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<string, string>();
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 ? {
+59 -4
View File
@@ -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<Map<string, RealGridReact>>(new Map());
const fileInputRefs = useRef<Map<string, HTMLInputElement>>(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<Map<string, Record<string, string | number>[]>>(new Map());
const [activeTab, setActiveTab] = useState<string>(() => {
// 초기 활성 탭을 첫 번째 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<string, string>();
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 ? {