From c254e7fd520f2a822beababc34ef47b0dcc4c38a Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Tue, 14 Oct 2025 15:08:33 +0200 Subject: [PATCH 01/10] feat(datagrid-web): send formatted cells instead of plain data to excel export --- .../features/data-export/DSExportRequest.ts | 73 +++++++++++++++---- 1 file changed, 59 insertions(+), 14 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts index 7898b5a76e..57fedd09a9 100644 --- a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts +++ b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts @@ -4,14 +4,26 @@ import { ListValue, ObjectItem, ValueStatus } from "mendix"; import { createNanoEvents, Emitter, Unsubscribe } from "nanoevents"; import { ColumnsType, ShowContentAsEnum } from "../../../typings/DatagridProps"; -type RowData = Array; +/** Represents a single Excel cell (SheetJS compatible, simplified) */ +interface ExcelCell { + /** Cell type: 's' = string, 'n' = number, 'b' = boolean, 'd' = date */ + t: "s" | "n" | "b" | "d"; + /** Underlying value */ + v: string | number | boolean | Date; + /** Optional Excel number/date format, e.g. "yyyy-mm-dd" or "$0.00" */ + z?: string; + /** Optional pre-formatted display text */ + w?: string; +} + +type RowData = ExcelCell[]; type HeaderDefinition = { name: string; type: string; }; -type ValueReader = (item: ObjectItem, props: ColumnsType) => string | boolean | number; +type ValueReader = (item: ObjectItem, props: ColumnsType) => ExcelCell; type ReadersByType = Record; @@ -253,48 +265,81 @@ export class DSExportRequest { const readers: ReadersByType = { attribute(item, props) { if (props.attribute === undefined) { - return ""; + return makeEmptyCell(); } const data = props.attribute.get(item); if (data.status !== "available") { - return ""; + return makeEmptyCell(); + } + + const value = data.value; + + if (value instanceof Date) { + return { + t: "d", // date cell + v: value, + z: "dd/mm/yyyy hh:mm", // Excel date format + w: value.toISOString().split("T")[0] // human-readable fallback + }; } - if (typeof data.value === "boolean") { - return data.value; + if (typeof value === "boolean") { + return { + t: "b", + v: value, + w: value ? "TRUE" : "FALSE" + }; } - if (data.value instanceof Big) { - return data.value.toNumber(); + // Number (Big or JS number) + if (value instanceof Big || typeof value === "number") { + const num = value instanceof Big ? value.toNumber() : value; + return { + t: "n", + v: num, + z: '"$"#,##0.00_);\\("$"#,##0.00\\)', + w: num.toLocaleString(undefined, { minimumFractionDigits: 2 }) + }; } - return data.displayValue; + // Default: string (ensure fallback is a string) + return { + t: "s", + v: data.displayValue ?? "", + w: data.displayValue ?? "" + }; }, dynamicText(item, props) { if (props.dynamicText === undefined) { - return ""; + return makeEmptyCell(); } const data = props.dynamicText.get(item); switch (data.status) { case "available": - return data.value; + return { t: "s", v: data.value ?? "", w: data.value ?? "" }; case "unavailable": - return "n/a"; + return { t: "s", v: "n/a", w: "n/a" }; default: - return ""; + return makeEmptyCell(); } }, customContent(item, props) { - return props.exportValue?.get(item).value ?? ""; + const value = props.exportValue?.get(item).value ?? ""; + return { t: "s", v: value, w: value }; } }; +// Helper for empty cells +function makeEmptyCell(): ExcelCell { + return { t: "s", v: "", w: "" }; +} + function createRowReader(columns: ColumnsType[]): RowReader { return item => columns.map(col => { From 094babea0fd42fc1017a084785961cfae1e4425f Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Wed, 15 Oct 2025 14:46:19 +0200 Subject: [PATCH 02/10] feat(datagrid-web): add type and format properties on columns --- .../datagrid-web/src/Datagrid.editorConfig.ts | 12 ++++++++- .../datagrid-web/src/Datagrid.xml | 27 +++++++++++++++++++ .../datagrid-web/typings/DatagridProps.d.ts | 8 ++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts index 5cc80ac52e..8ddeb16ee4 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -60,6 +60,14 @@ export function getProperties(values: DatagridPreviewProps, defaultProperties: P if (column.minWidth !== "manual") { hidePropertyIn(defaultProperties, values, "columns", index, "minWidthLimit"); } + // Hide exportNumberFormat if exportType is not 'number' + if (column.exportType !== "number") { + hidePropertyIn(defaultProperties, values, "columns", index, "exportNumberFormat" as any); + } + // Hide exportDateFormat if exportType is not 'date' + if (column.exportType !== "date") { + hidePropertyIn(defaultProperties, values, "columns", index, "exportDateFormat" as any); + } }); if (values.pagination === "buttons") { @@ -179,7 +187,9 @@ export const getPreview = ( minWidth: "auto", minWidthLimit: 100, allowEventPropagation: true, - exportValue: "" + exportValue: "", + exportType: "text", + exportFormat: "" } ]; const columns = rowLayout({ diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index 9ccf6b8d2a..16299d9c96 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -62,6 +62,33 @@ Export value + + Export type + + + Text + Number + Date + Boolean + + + + Export number format + + Optional Excel number format string to apply when exporting numeric values. + You can use any valid SheetJS number format, including currency, percentage, or custom patterns + (e.g. "#,##0.00", "$0.00", "0.00%"). + See full syntax reference here: https://docs.sheetjs.com/docs/csf/features/nf/ + + + + Export date format + + Optional Excel date format string to apply when exporting Date or DateTime values. + Follows JavaScript date format conventions supported by SheetJS + (e.g. "yyyy-mm-dd", "dd/mm/yyyy hh:mm", "mmm d, yyyy"). + + Caption diff --git a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts index 460fb68e33..ecd534988e 100644 --- a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts +++ b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts @@ -9,6 +9,8 @@ import { Big } from "big.js"; export type ShowContentAsEnum = "attribute" | "dynamicText" | "customContent"; +export type ExportTypeEnum = "text" | "number" | "date" | "boolean"; + export type HidableEnum = "yes" | "hidden" | "no"; export type WidthEnum = "autoFill" | "autoFit" | "manual"; @@ -23,6 +25,9 @@ export interface ColumnsType { content?: ListWidgetValue; dynamicText?: ListExpressionValue; exportValue?: ListExpressionValue; + exportType: ExportTypeEnum; + exportNumberFormat?: DynamicValue; + exportDateFormat?: DynamicValue; header?: DynamicValue; tooltip?: ListExpressionValue; filter?: ReactNode; @@ -67,6 +72,9 @@ export interface ColumnsPreviewType { content: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> }; dynamicText: string; exportValue: string; + exportType: ExportTypeEnum; + exportNumberFormat: string; + exportDateFormat: string; header: string; tooltip: string; filter: { widgetCount: number; renderer: ComponentType<{ children: ReactNode; caption?: string }> }; From bc4f69fa0e332d5c6a815a752401d4f5a27cf992 Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Fri, 17 Oct 2025 13:38:04 +0200 Subject: [PATCH 03/10] feat(datagrid-web): add type and format to ds export request --- .../datagrid-web/src/Datagrid.xml | 6 +- .../features/data-export/DSExportRequest.ts | 58 ++++++++++++++----- 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index 16299d9c96..241b36313d 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -72,7 +72,7 @@ Boolean - + Export number format Optional Excel number format string to apply when exporting numeric values. @@ -80,14 +80,16 @@ (e.g. "#,##0.00", "$0.00", "0.00%"). See full syntax reference here: https://docs.sheetjs.com/docs/csf/features/nf/ + - + Export date format Optional Excel date format string to apply when exporting Date or DateTime values. Follows JavaScript date format conventions supported by SheetJS (e.g. "yyyy-mm-dd", "dd/mm/yyyy hh:mm", "mmm d, yyyy"). + Caption diff --git a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts index 57fedd09a9..d26107f8c1 100644 --- a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts +++ b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts @@ -1,10 +1,10 @@ import { isAvailable } from "@mendix/widget-plugin-platform/framework/is-available"; import Big from "big.js"; -import { ListValue, ObjectItem, ValueStatus } from "mendix"; +import { DynamicValue, ListValue, ObjectItem, ValueStatus } from "mendix"; import { createNanoEvents, Emitter, Unsubscribe } from "nanoevents"; import { ColumnsType, ShowContentAsEnum } from "../../../typings/DatagridProps"; -/** Represents a single Excel cell (SheetJS compatible, simplified) */ +/** Represents a single Excel cell (SheetJS compatible) */ interface ExcelCell { /** Cell type: 's' = string, 'n' = number, 'b' = boolean, 'd' = date */ t: "s" | "n" | "b" | "d"; @@ -275,13 +275,17 @@ const readers: ReadersByType = { } const value = data.value; + const format = getCellFormat({ + exportType: props.exportType, + exportDateFormat: props.exportDateFormat, + exportNumberFormat: props.exportNumberFormat + }); if (value instanceof Date) { return { - t: "d", // date cell + t: "d", v: value, - z: "dd/mm/yyyy hh:mm", // Excel date format - w: value.toISOString().split("T")[0] // human-readable fallback + z: format }; } @@ -293,22 +297,18 @@ const readers: ReadersByType = { }; } - // Number (Big or JS number) if (value instanceof Big || typeof value === "number") { const num = value instanceof Big ? value.toNumber() : value; return { t: "n", v: num, - z: '"$"#,##0.00_);\\("$"#,##0.00\\)', - w: num.toLocaleString(undefined, { minimumFractionDigits: 2 }) + z: format }; } - // Default: string (ensure fallback is a string) return { t: "s", - v: data.displayValue ?? "", - w: data.displayValue ?? "" + v: data.displayValue ?? "" }; }, @@ -321,9 +321,14 @@ const readers: ReadersByType = { switch (data.status) { case "available": - return { t: "s", v: data.value ?? "", w: data.value ?? "" }; + const format = getCellFormat({ + exportType: props.exportType, + exportDateFormat: props.exportDateFormat, + exportNumberFormat: props.exportNumberFormat + }); + return { t: "s", v: data.value ?? "", z: format }; case "unavailable": - return { t: "s", v: "n/a", w: "n/a" }; + return { t: "s", v: "n/a" }; default: return makeEmptyCell(); } @@ -331,13 +336,34 @@ const readers: ReadersByType = { customContent(item, props) { const value = props.exportValue?.get(item).value ?? ""; - return { t: "s", v: value, w: value }; + const format = getCellFormat({ + exportType: props.exportType, + exportDateFormat: props.exportDateFormat, + exportNumberFormat: props.exportNumberFormat + }); + return { t: "s", v: value, z: format }; } }; -// Helper for empty cells function makeEmptyCell(): ExcelCell { - return { t: "s", v: "", w: "" }; + return { t: "s", v: "" }; +} + +interface DataExportProps { + exportType: "text" | "number" | "date" | "boolean"; + exportDateFormat?: DynamicValue; + exportNumberFormat?: DynamicValue; +} + +function getCellFormat({ exportType, exportDateFormat, exportNumberFormat }: DataExportProps): string | undefined { + switch (exportType) { + case "date": + return exportDateFormat?.status === "available" ? exportDateFormat.value : "mm/dd/yyyy"; + case "number": + return exportNumberFormat?.status === "available" ? exportNumberFormat.value : undefined; + default: + return undefined; + } } function createRowReader(columns: ColumnsType[]): RowReader { From 0882cac3a03f13ceb667475d2dc50e1101dd7d28 Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Fri, 17 Oct 2025 15:32:04 +0200 Subject: [PATCH 04/10] fix(datagrid-web): fix lint, test and build errors --- .../datagrid-web/src/Datagrid.editorConfig.ts | 3 ++- .../datagrid-web/src/Datagrid.editorPreview.tsx | 5 ++++- .../pluggableWidgets/datagrid-web/src/utils/test-utils.tsx | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts index 8ddeb16ee4..d927ad714f 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -189,7 +189,8 @@ export const getPreview = ( allowEventPropagation: true, exportValue: "", exportType: "text", - exportFormat: "" + exportDateFormat: "", + exportNumberFormat: "" } ]; const columns = rowLayout({ diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx index d38bf5c50b..fa9096d333 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx @@ -38,7 +38,10 @@ const defaultColumn: ColumnsPreviewType = { minWidth: "auto", minWidthLimit: 100, allowEventPropagation: true, - exportValue: "" + exportValue: "", + exportDateFormat: "", + exportNumberFormat: "", + exportType: "text" }; const initColumns: ColumnsPreviewType[] = [defaultColumn]; diff --git a/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx b/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx index bd16125514..d4901fc2f2 100644 --- a/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx @@ -28,7 +28,8 @@ export const column = (header = "Test", patch?: (col: ColumnsType) => void): Col visible: dynamicValue(true), minWidth: "auto", minWidthLimit: 100, - allowEventPropagation: true + allowEventPropagation: true, + exportType: "text" }; if (patch) { From 46b2e0645d091b5fcca3f06ca5df3c66909b8ad0 Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Mon, 20 Oct 2025 11:17:19 +0200 Subject: [PATCH 05/10] fix(datagrid-web): send displayValue when no format is provided --- .../src/features/data-export/DSExportRequest.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts index d26107f8c1..6178f551bf 100644 --- a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts +++ b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts @@ -283,8 +283,8 @@ const readers: ReadersByType = { if (value instanceof Date) { return { - t: "d", - v: value, + t: format === undefined ? "s" : "d", + v: format === undefined ? data.displayValue : value, z: format }; } @@ -358,7 +358,7 @@ interface DataExportProps { function getCellFormat({ exportType, exportDateFormat, exportNumberFormat }: DataExportProps): string | undefined { switch (exportType) { case "date": - return exportDateFormat?.status === "available" ? exportDateFormat.value : "mm/dd/yyyy"; + return exportDateFormat?.status === "available" ? exportDateFormat.value : undefined; case "number": return exportNumberFormat?.status === "available" ? exportNumberFormat.value : undefined; default: From 0d018319756ea1d0666e68729e82bb0de296d1e0 Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Mon, 20 Oct 2025 12:25:36 +0200 Subject: [PATCH 06/10] chore(datagrid-web): update changelog --- packages/pluggableWidgets/datagrid-web/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md index e766b412b9..a90fe19952 100644 --- a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md +++ b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## [Unreleased] +### Added + +- We added a new property for export to excel. The new property allows to set the cell export type and also the format for type number and date. + ## [3.7.0] - 2025-11-11 ### Added From 4669ffbae695189254e16cb5881fbd5f61416b72 Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Mon, 20 Oct 2025 15:46:41 +0200 Subject: [PATCH 07/10] chore(datagrid-web): make smaller descriptions for export number and date formats --- .../pluggableWidgets/datagrid-web/src/Datagrid.xml | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index 241b36313d..cf8fa87865 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -74,21 +74,12 @@ Export number format - - Optional Excel number format string to apply when exporting numeric values. - You can use any valid SheetJS number format, including currency, percentage, or custom patterns - (e.g. "#,##0.00", "$0.00", "0.00%"). - See full syntax reference here: https://docs.sheetjs.com/docs/csf/features/nf/ - + Optional Excel number format for exported numeric values (e.g. "#,##0.00", "$0.00", "0.00%"). See all formats https://docs.sheetjs.com/docs/csf/features/nf/ Export date format - - Optional Excel date format string to apply when exporting Date or DateTime values. - Follows JavaScript date format conventions supported by SheetJS - (e.g. "yyyy-mm-dd", "dd/mm/yyyy hh:mm", "mmm d, yyyy"). - + Excel date format for exported Date/DateTime values (e.g. "yyyy-mm-dd", "dd/mm/yyyy hh mm"). From 44a4806da9e5dc1db713f7b9209c99266501373a Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Wed, 5 Nov 2025 15:57:06 +0100 Subject: [PATCH 08/10] fix(datagrid-web): change exportType value from "text" to "default" --- .../datagrid-web/src/Datagrid.editorConfig.ts | 2 +- .../datagrid-web/src/Datagrid.editorPreview.tsx | 2 +- packages/pluggableWidgets/datagrid-web/src/Datagrid.xml | 4 ++-- .../pluggableWidgets/datagrid-web/src/utils/test-utils.tsx | 2 +- .../pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts index d927ad714f..f242a39ef3 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -188,7 +188,7 @@ export const getPreview = ( minWidthLimit: 100, allowEventPropagation: true, exportValue: "", - exportType: "text", + exportType: "default", exportDateFormat: "", exportNumberFormat: "" } diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx index fa9096d333..7d666397a3 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx @@ -41,7 +41,7 @@ const defaultColumn: ColumnsPreviewType = { exportValue: "", exportDateFormat: "", exportNumberFormat: "", - exportType: "text" + exportType: "default" }; const initColumns: ColumnsPreviewType[] = [defaultColumn]; diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index cf8fa87865..1366fbe612 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -62,11 +62,11 @@ Export value - + Export type - Text + Default Number Date Boolean diff --git a/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx b/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx index d4901fc2f2..9fe9f153d5 100644 --- a/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/utils/test-utils.tsx @@ -29,7 +29,7 @@ export const column = (header = "Test", patch?: (col: ColumnsType) => void): Col minWidth: "auto", minWidthLimit: 100, allowEventPropagation: true, - exportType: "text" + exportType: "default" }; if (patch) { diff --git a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts index ecd534988e..056c487def 100644 --- a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts +++ b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts @@ -9,7 +9,7 @@ import { Big } from "big.js"; export type ShowContentAsEnum = "attribute" | "dynamicText" | "customContent"; -export type ExportTypeEnum = "text" | "number" | "date" | "boolean"; +export type ExportTypeEnum = "default" | "number" | "date" | "boolean"; export type HidableEnum = "yes" | "hidden" | "no"; From 1ff6593c7bae37d3cac3640db3a1826d5b66cfa3 Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Wed, 5 Nov 2025 15:57:51 +0100 Subject: [PATCH 09/10] fix(datagrid-web): update readers to handle optional attributes and create cell formatting functions --- .../features/data-export/DSExportRequest.ts | 88 +++++++++++-------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts index 6178f551bf..8c96a48e4e 100644 --- a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts +++ b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts @@ -264,13 +264,9 @@ export class DSExportRequest { const readers: ReadersByType = { attribute(item, props) { - if (props.attribute === undefined) { - return makeEmptyCell(); - } + const data = props.attribute?.get(item); - const data = props.attribute.get(item); - - if (data.status !== "available") { + if (data?.status !== "available") { return makeEmptyCell(); } @@ -282,53 +278,35 @@ const readers: ReadersByType = { }); if (value instanceof Date) { - return { - t: format === undefined ? "s" : "d", - v: format === undefined ? data.displayValue : value, - z: format - }; + return excelDate(format === undefined ? data.displayValue : value, format); } if (typeof value === "boolean") { - return { - t: "b", - v: value, - w: value ? "TRUE" : "FALSE" - }; + return excelBoolean(value); } if (value instanceof Big || typeof value === "number") { const num = value instanceof Big ? value.toNumber() : value; - return { - t: "n", - v: num, - z: format - }; + return excelNumber(num, format); } - return { - t: "s", - v: data.displayValue ?? "" - }; + return excelString(data.displayValue ?? ""); }, dynamicText(item, props) { - if (props.dynamicText === undefined) { - return makeEmptyCell(); - } - - const data = props.dynamicText.get(item); + const data = props.dynamicText?.get(item); - switch (data.status) { + switch (data?.status) { case "available": const format = getCellFormat({ exportType: props.exportType, exportDateFormat: props.exportDateFormat, exportNumberFormat: props.exportNumberFormat }); - return { t: "s", v: data.value ?? "", z: format }; + + return excelStringFormat(data.value ?? "", format); case "unavailable": - return { t: "s", v: "n/a" }; + return excelString("n/a"); default: return makeEmptyCell(); } @@ -341,7 +319,8 @@ const readers: ReadersByType = { exportDateFormat: props.exportDateFormat, exportNumberFormat: props.exportNumberFormat }); - return { t: "s", v: value, z: format }; + + return excelStringFormat(value, format); } }; @@ -349,8 +328,47 @@ function makeEmptyCell(): ExcelCell { return { t: "s", v: "" }; } +function excelNumber(value: number, format?: string): ExcelCell { + return { + t: "n", + v: value, + z: format + }; +} + +function excelString(value: string): ExcelCell { + return { + t: "s", + v: value + }; +} + +function excelStringFormat(value: string, format?: string): ExcelCell { + return { + t: "s", + v: value, + z: format + }; +} + +function excelDate(value: string | Date, format?: string): ExcelCell { + return { + t: format === undefined ? "s" : "d", + v: value, + z: format + }; +} + +function excelBoolean(value: boolean): ExcelCell { + return { + t: "b", + v: value, + w: value ? "TRUE" : "FALSE" + }; +} + interface DataExportProps { - exportType: "text" | "number" | "date" | "boolean"; + exportType: "default" | "number" | "date" | "boolean"; exportDateFormat?: DynamicValue; exportNumberFormat?: DynamicValue; } From 012a99f5ff84984ef37a7e6e60e1ced4f6661c70 Mon Sep 17 00:00:00 2001 From: Samuel Reichert Date: Thu, 6 Nov 2025 10:43:59 +0100 Subject: [PATCH 10/10] fix(datagrid-web): replace excelStringFormat with excelString for consistency in cell formatting --- .../src/features/data-export/DSExportRequest.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts index 8c96a48e4e..47bb3f51a4 100644 --- a/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts +++ b/packages/pluggableWidgets/datagrid-web/src/features/data-export/DSExportRequest.ts @@ -304,7 +304,7 @@ const readers: ReadersByType = { exportNumberFormat: props.exportNumberFormat }); - return excelStringFormat(data.value ?? "", format); + return excelString(data.value ?? "", format); case "unavailable": return excelString("n/a"); default: @@ -320,7 +320,7 @@ const readers: ReadersByType = { exportNumberFormat: props.exportNumberFormat }); - return excelStringFormat(value, format); + return excelString(value, format); } }; @@ -336,18 +336,11 @@ function excelNumber(value: number, format?: string): ExcelCell { }; } -function excelString(value: string): ExcelCell { - return { - t: "s", - v: value - }; -} - -function excelStringFormat(value: string, format?: string): ExcelCell { +function excelString(value: string, format?: string): ExcelCell { return { t: "s", v: value, - z: format + z: format ?? undefined }; }