Skip to content

Commit 39c37d2

Browse files
committed
feat(datagrid-web): use attribute formatter for default Excel export type
1 parent e769b71 commit 39c37d2

4 files changed

Lines changed: 107 additions & 12 deletions

File tree

packages/pluggableWidgets/datagrid-web/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66

77
## [Unreleased]
88

9+
### Added
10+
11+
- We added support for using the attribute's own formatting when exporting to Excel with the "Default" export type. Numbers and dates now export with their configured precision and pattern instead of raw values.
12+
13+
### Fixed
14+
15+
- We fixed an issue where export type and format properties were visible in Studio Pro for dynamic text columns, even though they have no effect.
16+
917
## [3.11.1] - 2026-06-18
1018

1119
### Fixed

packages/pluggableWidgets/datagrid-web/src/Datagrid.editorConfig.ts

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,19 @@ export function getProperties(values: DatagridPreviewProps, defaultProperties: P
5757
if (column.minWidth !== "manual") {
5858
hidePropertyIn(defaultProperties, values, "columns", index, "minWidthLimit");
5959
}
60-
// Hide exportNumberFormat if exportType is not 'number'
61-
if (column.exportType !== "number") {
62-
hidePropertyIn(defaultProperties, values, "columns", index, "exportNumberFormat" as any);
63-
}
64-
// Hide exportDateFormat if exportType is not 'date'
65-
if (column.exportType !== "date") {
66-
hidePropertyIn(defaultProperties, values, "columns", index, "exportDateFormat" as any);
60+
if (column.showContentAs === "dynamicText") {
61+
hideNestedPropertiesIn(defaultProperties, values, "columns", index, [
62+
"exportType",
63+
"exportNumberFormat",
64+
"exportDateFormat"
65+
] as any);
66+
} else {
67+
if (column.exportType !== "number") {
68+
hidePropertyIn(defaultProperties, values, "columns", index, "exportNumberFormat" as any);
69+
}
70+
if (column.exportType !== "date") {
71+
hidePropertyIn(defaultProperties, values, "columns", index, "exportDateFormat" as any);
72+
}
6773
}
6874
});
6975

packages/pluggableWidgets/datagrid-web/src/features/data-export/__tests__/cell-readers.spec.ts

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,63 @@ describe("cell-readers", () => {
6868
expect(cell.v).toBe(false);
6969
});
7070

71+
it("uses attribute number formatter when exportType is default", () => {
72+
const attr = listAttribute(() => new Big("1234.56")) as any;
73+
attr.formatter = { type: "number", config: { groupDigits: true, decimalPrecision: 2 } };
74+
const col = column("Amount", c => {
75+
c.showContentAs = "attribute";
76+
c.attribute = attr;
77+
c.exportType = "default";
78+
});
79+
const cell = readSingleCell(col);
80+
expect(cell.t).toBe("n");
81+
expect(cell.v).toBe(1234.56);
82+
expect(cell.z).toBe("#,##0.00");
83+
});
84+
85+
it("uses attribute date formatter when exportType is default", () => {
86+
const testDate = new Date("2024-06-15T10:30:00Z");
87+
const attr = listAttribute(() => testDate) as any;
88+
attr.formatter = { type: "datetime", config: { type: "custom", pattern: "dd/MM/yyyy" } };
89+
const col = column("Created", c => {
90+
c.showContentAs = "attribute";
91+
c.attribute = attr;
92+
c.exportType = "default";
93+
});
94+
const cell = readSingleCell(col);
95+
expect(cell.t).toBe("d");
96+
expect(cell.v).toEqual(new Date(Date.UTC(2024, 5, 15)));
97+
expect(cell.z).toBe("dd/mm/yyyy");
98+
});
99+
100+
it("returns no format for default datetime with non-custom config", () => {
101+
const testDate = new Date("2024-06-15T10:30:00Z");
102+
const attr = listAttribute(() => testDate) as any;
103+
attr.formatter = { type: "datetime", config: { type: "date" } };
104+
const col = column("Created", c => {
105+
c.showContentAs = "attribute";
106+
c.attribute = attr;
107+
c.exportType = "default";
108+
});
109+
const cell = readSingleCell(col);
110+
expect(cell.t).toBe("d");
111+
expect(cell.z).toBe("dd-mm-yyyy");
112+
});
113+
114+
it("uses attribute number formatter without decimals", () => {
115+
const attr = listAttribute(() => new Big("42")) as any;
116+
attr.formatter = { type: "number", config: { groupDigits: false, decimalPrecision: 0 } };
117+
const col = column("Count", c => {
118+
c.showContentAs = "attribute";
119+
c.attribute = attr;
120+
c.exportType = "default";
121+
});
122+
const cell = readSingleCell(col);
123+
expect(cell.t).toBe("n");
124+
expect(cell.v).toBe(42);
125+
expect(cell.z).toBe("0");
126+
});
127+
71128
it("exports date attribute with format as date cell", () => {
72129
const testDate = new Date("2024-06-15T10:30:00Z");
73130
const col = column("Created", c => {

packages/pluggableWidgets/datagrid-web/src/features/data-export/cell-readers.ts

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,27 @@ function countSignificantDigits(value: Big): number {
113113
return stripped.length || 1;
114114
}
115115

116+
function getAttributeDefaultFormat(props: ColumnsType): string | undefined {
117+
const formatter = props.attribute?.formatter;
118+
if (!formatter) {
119+
return undefined;
120+
}
121+
122+
if (formatter.type === "datetime") {
123+
const cfg = formatter.config;
124+
return cfg.type === "custom" ? cfg.pattern.replace(/M/g, "m") : undefined;
125+
}
126+
127+
if (formatter.type === "number") {
128+
const cfg = formatter.config;
129+
const decimals = cfg.decimalPrecision ?? 0;
130+
const base = cfg.groupDigits ? "#,##0" : "0";
131+
return decimals > 0 ? `${base}.${"0".repeat(decimals)}` : base;
132+
}
133+
134+
return undefined;
135+
}
136+
116137
const readers: ReadersByType = {
117138
attribute(item, props) {
118139
const data = props.attribute?.get(item);
@@ -122,11 +143,14 @@ const readers: ReadersByType = {
122143
}
123144

124145
const value = data.value;
125-
const format = getCellFormat({
126-
exportType: props.exportType,
127-
exportDateFormat: props.exportDateFormat,
128-
exportNumberFormat: props.exportNumberFormat
129-
});
146+
const format =
147+
props.exportType === "default"
148+
? getAttributeDefaultFormat(props)
149+
: getCellFormat({
150+
exportType: props.exportType,
151+
exportDateFormat: props.exportDateFormat,
152+
exportNumberFormat: props.exportNumberFormat
153+
});
130154

131155
if (value instanceof Date) {
132156
const dateValue = format && hasTimeComponent(format) ? value : stripTime(value);

0 commit comments

Comments
 (0)