From 4d251d4ddc04820e80eb11612fd323b555817c12 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 6c50f43d5fae80a93a62e9f805ee90d1f8d74a3d 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 abd7f1cfb2..58c880f92f 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -65,6 +65,14 @@ export function getProperties( 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.advanced && platform === "web") { hideNestedPropertiesIn(defaultProperties, values, "columns", index, [ "columnClass", @@ -214,7 +222,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 afb1d00ec4..e4097d6cf7 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -127,6 +127,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 513d2d6282..9027169878 100644 --- a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts +++ b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts @@ -17,6 +17,8 @@ export type LoadingTypeEnum = "spinner" | "skeleton"; 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"; @@ -31,6 +33,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 df7b562af0557c0b1f22447018d78cfaab3c74f1 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 e4097d6cf7..3538f51957 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -137,7 +137,7 @@ Boolean - + Export number format Optional Excel number format string to apply when exporting numeric values. @@ -145,14 +145,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 7b710f18afec1b725b4369542cd87e4483715562 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 58c880f92f..5c8c916ed7 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -224,7 +224,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 6086784e80..18af94e60a 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx @@ -55,7 +55,10 @@ const initColumns: ColumnsPreviewType[] = [ minWidth: "auto", minWidthLimit: 100, allowEventPropagation: true, - exportValue: "" + exportValue: "", + exportDateFormat: "", + exportNumberFormat: "", + exportType: "text" } ]; 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 ac4bbe74eb36ec3ec722a6f9075c9447c8902500 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 ca74ebc1f7259d523e928264edd8baf2d173dcdb 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 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md index fbe7db8aa7..676ac9f7ab 100644 --- a/packages/pluggableWidgets/datagrid-web/CHANGELOG.md +++ b/packages/pluggableWidgets/datagrid-web/CHANGELOG.md @@ -12,6 +12,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), - We fixed an issue where missing consistency checks for the captions were causing runtime errors instead of in Studio Pro +- 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.6.1] - 2025-10-14 ### Fixed From 0f5c3ba78a8ff0967fab0a9dffee95e8fbac0b84 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 3538f51957..806d9393e3 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -139,21 +139,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 6482ca3e20257c47bc6e354eb0e8885d4afa3d14 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 5c8c916ed7..100229c5e9 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts @@ -223,7 +223,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 18af94e60a..b41aa58393 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.editorPreview.tsx @@ -58,7 +58,7 @@ const initColumns: ColumnsPreviewType[] = [ exportValue: "", exportDateFormat: "", exportNumberFormat: "", - exportType: "text" + exportType: "default" } ]; diff --git a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml index 806d9393e3..1a404dd6f9 100644 --- a/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml +++ b/packages/pluggableWidgets/datagrid-web/src/Datagrid.xml @@ -127,11 +127,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 9027169878..2682962226 100644 --- a/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts +++ b/packages/pluggableWidgets/datagrid-web/typings/DatagridProps.d.ts @@ -17,7 +17,7 @@ export type LoadingTypeEnum = "spinner" | "skeleton"; 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 2d43b0084c1d0e467116a2cf832a443837371677 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 44baec46c948f49cab5bf15c5bf3d651457035cc 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 }; }