From 3a7cadf5c20d1bf44e9357c4152d44b78b316341 Mon Sep 17 00:00:00 2001 From: Darin Kelkhoff Date: Fri, 19 May 2023 11:51:20 -0500 Subject: [PATCH] Clean csv values; Update qfc - for audit count fix --- package.json | 2 +- src/qqq/components/widgets/tables/TableWidget.tsx | 2 +- src/qqq/pages/records/query/ColumnStats.tsx | 12 ++++-------- src/qqq/utils/qqq/ValueUtils.tsx | 13 +++++++++++++ 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 1797de4..65b58a2 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "@auth0/auth0-react": "1.10.2", "@emotion/react": "11.7.1", "@emotion/styled": "11.6.0", - "@kingsrook/qqq-frontend-core": "1.0.65", + "@kingsrook/qqq-frontend-core": "1.0.66", "@mui/icons-material": "5.4.1", "@mui/material": "5.11.1", "@mui/styles": "5.11.1", diff --git a/src/qqq/components/widgets/tables/TableWidget.tsx b/src/qqq/components/widgets/tables/TableWidget.tsx index 2aad023..0f66067 100644 --- a/src/qqq/components/widgets/tables/TableWidget.tsx +++ b/src/qqq/components/widgets/tables/TableWidget.tsx @@ -107,7 +107,7 @@ function TableWidget(props: Props): JSX.Element {selector: ".button", format: "skip"} ] }); - csv += `"${text}"`; + csv += `"${ValueUtils.cleanForCsv(text)}"`; } csv += "\n"; } diff --git a/src/qqq/pages/records/query/ColumnStats.tsx b/src/qqq/pages/records/query/ColumnStats.tsx index 6e48eaa..65d6077 100644 --- a/src/qqq/pages/records/query/ColumnStats.tsx +++ b/src/qqq/pages/records/query/ColumnStats.tsx @@ -193,16 +193,12 @@ function ColumnStats({tableMetaData, fieldMetaData, fieldTableName, filter}: Pro const doExport = () => { - let csv = `"${fieldMetaData.label}","Count"\n`; + let csv = `"${ValueUtils.cleanForCsv(fieldMetaData.label)}","Count"\n`; for (let i = 0; i < valueCounts.length; i++) { - let fieldValue = valueCounts[i].displayValues.get(fieldMetaData.name); - if(fieldValue === undefined) - { - fieldValue = ""; - } - - csv += `"${fieldValue}",${valueCounts[i].values.get("count")}\n`; + const fieldValue = valueCounts[i].displayValues.get(fieldMetaData.name); + const count = valueCounts[i].values.get("count"); + csv += `"${ValueUtils.cleanForCsv(fieldValue)}",${count}\n`; } const fileName = tableMetaData.label + " - " + fieldMetaData.label + " Column Stats " + ValueUtils.formatDateTimeForFileName(new Date()) + ".csv"; diff --git a/src/qqq/utils/qqq/ValueUtils.tsx b/src/qqq/utils/qqq/ValueUtils.tsx index ccb68d0..d8c1332 100644 --- a/src/qqq/utils/qqq/ValueUtils.tsx +++ b/src/qqq/utils/qqq/ValueUtils.tsx @@ -418,6 +418,19 @@ class ValueUtils return toPush; } + + /******************************************************************************* + ** for building CSV in frontends, cleanse null & undefined, and escape "'s + *******************************************************************************/ + public static cleanForCsv(param: any): string + { + if(param === undefined || param === null) + { + return (""); + } + + return (String(param).replaceAll(/"/g, "\"\"")); + } } ////////////////////////////////////////////////////////////////////////////////////////////////