From a2d610197f0ed946b0329de20c85f923b8cba5c9 Mon Sep 17 00:00:00 2001 From: arianber7 Date: Wed, 15 Oct 2025 11:06:45 +0200 Subject: [PATCH 1/2] perf: [10196] build a dict of the colums metadata before the main parsing loop --- src/FileUtils/AgGridUtils.js | 53 ++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 24 deletions(-) diff --git a/src/FileUtils/AgGridUtils.js b/src/FileUtils/AgGridUtils.js index 5c56a39..bb199d2 100644 --- a/src/FileUtils/AgGridUtils.js +++ b/src/FileUtils/AgGridUtils.js @@ -90,34 +90,39 @@ const _validateFormat = (rows, hasHeader, cols, options) => { const errors = []; const knownColsCount = colsData.length; const startIndex = hasHeader ? 1 : 0; + + const colMeta = cols.map((col) => ({ + field: col.field, + type: _getColTypeFromTypeArray(col.type), + acceptsEmptyFields: col.acceptsEmptyFields ?? col.cellEditorParams?.acceptsEmptyFields ?? false, + colOptions: { + ...options, + enumValues: col.enumValues ?? col.cellEditorParams?.enumValues, + minValue: col.minValue, + maxValue: col.maxValue, + }, + })); + for (let rowIndex = startIndex; rowIndex < rows.length; rowIndex++) { const row = rows[rowIndex]; while (row[row.length - 1] === undefined && row.length > knownColsCount) row.pop(); - if (row.length !== knownColsCount || row.includes(undefined)) - _forgeColumnsCountError(row, rowIndex + 1, colsData, errors); - row.forEach((rowCell, colIndex) => { - if (colIndex < knownColsCount) { - const colType = colsData[colIndex].type; - if (colType && rowCell !== undefined) { - // use of cellEditorParams is deprecated - const colOptions = { - ...options, - enumValues: colsData[colIndex]?.enumValues ?? colsData[colIndex]?.cellEditorParams?.enumValues, - minValue: colsData[colIndex]?.minValue, - maxValue: colsData[colIndex]?.maxValue, - }; - const acceptsEmptyFields = - // use of cellEditorParams is deprecated - colsData[colIndex].acceptsEmptyFields ?? colsData[colIndex].cellEditorParams?.acceptsEmptyFields ?? false; - const validationResult = ValidationUtils.isValid(rowCell, colType, colOptions, acceptsEmptyFields); - if (validationResult !== true) { - const { summary: errorSummary, context: errorContext } = validationResult; - const errorLoc = `Line ${rowIndex + 1}, Column ${colIndex + 1} ("${colsData[colIndex].field}")`; - errors.push(new PanelError(errorSummary, errorLoc, errorContext)); - } - } + if (row.length !== knownColsCount || row.includes(undefined)) { + _forgeColumnsCountError(row, rowIndex + 1, cols, errors); + continue; + } + + for (let colIndex = 0; colIndex < knownColsCount; colIndex++) { + const { type, colOptions, acceptsEmptyFields, field } = colMeta[colIndex]; + const value = row[colIndex]; + if (value === undefined) continue; + + const validationResult = ValidationUtils.isValid(value, type, colOptions, acceptsEmptyFields); + if (validationResult !== true) { + const { summary: errorSummary, context: errorContext } = validationResult; + const errorLoc = `Line ${rowIndex + 1}, Column ${colIndex + 1} ("${field}")`; + errors.push(new PanelError(errorSummary, errorLoc, errorContext)); } - }); + } } return errors; From 630ca9537c2e86eeace9793ab5fd9497579f211e Mon Sep 17 00:00:00 2001 From: arianber7 Date: Wed, 15 Oct 2025 11:07:50 +0200 Subject: [PATCH 2/2] perf: [10196] add custom function to parse dates --- src/FileUtils/AgGridUtils.js | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/FileUtils/AgGridUtils.js b/src/FileUtils/AgGridUtils.js index bb199d2..cd8ea4c 100644 --- a/src/FileUtils/AgGridUtils.js +++ b/src/FileUtils/AgGridUtils.js @@ -85,6 +85,21 @@ const _getColTypeFromTypeArray = (typeArray) => { return 'string'; // Fall back to default type }; +const validateDateFormat = (value, options = {}) => { + if (typeof value !== 'string') return false; + const { dateFormat = 'yyyy-MM-dd' } = options; + + const formatRegex = dateFormat + .replace(/yyyy/, '\\d{4}') + .replace(/MM/, '(0[1-9]|1[0-2])') + .replace(/dd/, '(0[1-9]|[12]\\d|3[01])') + .replace(/\//g, '\\/') + .replace(/-/g, '-'); + + const regex = new RegExp(`^${formatRegex}$`); + return regex.test(value); +}; + const _validateFormat = (rows, hasHeader, cols, options) => { const colsData = cols.map((col) => ({ ...col, type: _getColTypeFromTypeArray(col.type) })); const errors = []; @@ -116,6 +131,15 @@ const _validateFormat = (rows, hasHeader, cols, options) => { const value = row[colIndex]; if (value === undefined) continue; + if (type === 'date' && !validateDateFormat(value, colOptions)) { + const expectedFormat = colOptions.dateFormat || 'dd/MM/yyyy'; + const errorSummary = 'Incorrect date value'; + const errorContext = `Incorrect value: "${value}" for type date\nExpected format: ${expectedFormat}`; + const errorLoc = `Line ${rowIndex + 1}, Column ${colIndex + 1} ("${field}")`; + errors.push(new PanelError(errorSummary, errorLoc, errorContext)); + continue; + } + const validationResult = ValidationUtils.isValid(value, type, colOptions, acceptsEmptyFields); if (validationResult !== true) { const { summary: errorSummary, context: errorContext } = validationResult;