@object-ui/plugin-dashboard 3.1.3 → 3.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +29 -12
- package/CHANGELOG.md +9 -0
- package/dist/index.css +2 -1
- package/dist/index.js +5408 -5890
- package/dist/index.umd.cjs +6 -5
- package/dist/src/ObjectDataTable.d.ts +15 -0
- package/dist/src/ObjectDataTable.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/ObjectDataTable.tsx +36 -1
- package/src/__tests__/ObjectDataTable.test.tsx +90 -1
|
@@ -19,6 +19,20 @@ export interface ObjectDataTableProps {
|
|
|
19
19
|
dataSource?: any;
|
|
20
20
|
className?: string;
|
|
21
21
|
}
|
|
22
|
+
/** A column definition after normalization, with header and accessor key. */
|
|
23
|
+
interface NormalizedColumn {
|
|
24
|
+
header: string;
|
|
25
|
+
accessorKey: string;
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Normalize columns to support both string[] shorthand and object[] formats.
|
|
30
|
+
*
|
|
31
|
+
* - `string[]` entries are converted to `{ header, accessorKey }` objects,
|
|
32
|
+
* handling both snake_case and camelCase for header generation.
|
|
33
|
+
* - Object entries are returned as-is.
|
|
34
|
+
*/
|
|
35
|
+
export declare function normalizeColumns(columns: (string | Record<string, any>)[]): NormalizedColumn[];
|
|
22
36
|
/**
|
|
23
37
|
* ObjectDataTable — Async-aware wrapper for data-table.
|
|
24
38
|
*
|
|
@@ -36,4 +50,5 @@ export interface ObjectDataTableProps {
|
|
|
36
50
|
* - **Data** → data-table with fetched rows
|
|
37
51
|
*/
|
|
38
52
|
export declare const ObjectDataTable: React.FC<ObjectDataTableProps>;
|
|
53
|
+
export {};
|
|
39
54
|
//# sourceMappingURL=ObjectDataTable.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectDataTable.d.ts","sourceRoot":"","sources":["../../src/ObjectDataTable.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACrD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,GAAG,CAAC;QACb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;QAChB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;IACF,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,
|
|
1
|
+
{"version":3,"file":"ObjectDataTable.d.ts","sourceRoot":"","sources":["../../src/ObjectDataTable.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,YAAY,CAAC,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACrD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,GAAG,CAAC;QACb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;QAChB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;IACF,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,6EAA6E;AAC7E,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,gBAAgB,EAAE,CAiB9F;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAiJ1D,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/plugin-dashboard",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"description": "Dashboard plugin for Object UI",
|
|
@@ -21,10 +21,10 @@
|
|
|
21
21
|
"react-dom": "19.2.4",
|
|
22
22
|
"react-grid-layout": "^2.2.2",
|
|
23
23
|
"tailwind-merge": "^3.5.0",
|
|
24
|
-
"@object-ui/components": "3.1.
|
|
25
|
-
"@object-ui/core": "3.1.
|
|
26
|
-
"@object-ui/react": "3.1.
|
|
27
|
-
"@object-ui/types": "3.1.
|
|
24
|
+
"@object-ui/components": "3.1.4",
|
|
25
|
+
"@object-ui/core": "3.1.4",
|
|
26
|
+
"@object-ui/react": "3.1.4",
|
|
27
|
+
"@object-ui/types": "3.1.4"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
30
|
"react": "^18.0.0",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/react-grid-layout": "^2.1.0",
|
|
35
|
-
"@vitejs/plugin-react": "^
|
|
35
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
36
36
|
"typescript": "^5.9.3",
|
|
37
|
-
"vite": "^
|
|
37
|
+
"vite": "^8.0.1",
|
|
38
38
|
"vite-plugin-dts": "^4.5.4"
|
|
39
39
|
},
|
|
40
40
|
"scripts": {
|
package/src/ObjectDataTable.tsx
CHANGED
|
@@ -29,6 +29,39 @@ export interface ObjectDataTableProps {
|
|
|
29
29
|
className?: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
/** A column definition after normalization, with header and accessor key. */
|
|
33
|
+
interface NormalizedColumn {
|
|
34
|
+
header: string;
|
|
35
|
+
accessorKey: string;
|
|
36
|
+
[key: string]: any;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Normalize columns to support both string[] shorthand and object[] formats.
|
|
41
|
+
*
|
|
42
|
+
* - `string[]` entries are converted to `{ header, accessorKey }` objects,
|
|
43
|
+
* handling both snake_case and camelCase for header generation.
|
|
44
|
+
* - Object entries are returned as-is.
|
|
45
|
+
*/
|
|
46
|
+
export function normalizeColumns(columns: (string | Record<string, any>)[]): NormalizedColumn[] {
|
|
47
|
+
return columns.map((col) => {
|
|
48
|
+
if (typeof col === 'string') {
|
|
49
|
+
return {
|
|
50
|
+
header: col
|
|
51
|
+
// snake_case → spaces
|
|
52
|
+
.replace(/_/g, ' ')
|
|
53
|
+
// camelCase → spaces before uppercase letters
|
|
54
|
+
.replace(/([A-Z])/g, ' $1')
|
|
55
|
+
.trim()
|
|
56
|
+
// Title Case each word
|
|
57
|
+
.replace(/\b\w/g, (c: string) => c.toUpperCase()),
|
|
58
|
+
accessorKey: col,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return col;
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
32
65
|
/**
|
|
33
66
|
* ObjectDataTable — Async-aware wrapper for data-table.
|
|
34
67
|
*
|
|
@@ -101,7 +134,9 @@ export const ObjectDataTable: React.FC<ObjectDataTableProps> = ({ schema, dataSo
|
|
|
101
134
|
|
|
102
135
|
// Auto-derive columns from data keys when none are provided
|
|
103
136
|
const derivedColumns = useMemo(() => {
|
|
104
|
-
if (schema.columns && schema.columns.length > 0)
|
|
137
|
+
if (schema.columns && schema.columns.length > 0) {
|
|
138
|
+
return normalizeColumns(schema.columns);
|
|
139
|
+
}
|
|
105
140
|
if (finalData.length === 0) return [];
|
|
106
141
|
// Exclude internal/private fields (prefixed with '_') from auto-derived columns
|
|
107
142
|
const keys = Object.keys(finalData[0]).filter(k => !k.startsWith('_'));
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { describe, it, expect, vi } from 'vitest';
|
|
10
10
|
import { render, screen, waitFor } from '@testing-library/react';
|
|
11
11
|
import React from 'react';
|
|
12
|
-
import { ObjectDataTable } from '../ObjectDataTable';
|
|
12
|
+
import { ObjectDataTable, normalizeColumns } from '../ObjectDataTable';
|
|
13
13
|
import { SchemaRendererProvider } from '@object-ui/react';
|
|
14
14
|
|
|
15
15
|
describe('ObjectDataTable', () => {
|
|
@@ -119,4 +119,93 @@ describe('ObjectDataTable', () => {
|
|
|
119
119
|
|
|
120
120
|
expect(dataSource.find).not.toHaveBeenCalled();
|
|
121
121
|
});
|
|
122
|
+
|
|
123
|
+
it('should normalize string[] columns without crashing', () => {
|
|
124
|
+
const schema = {
|
|
125
|
+
...baseSchema,
|
|
126
|
+
columns: ['name', 'amount', 'close_date'],
|
|
127
|
+
data: [
|
|
128
|
+
{ name: 'Deal A', amount: 1000, close_date: '2025-01-01' },
|
|
129
|
+
{ name: 'Deal B', amount: 2000, close_date: '2025-06-01' },
|
|
130
|
+
],
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// Should not crash when columns are strings
|
|
134
|
+
const { container } = render(
|
|
135
|
+
<SchemaRendererProvider>
|
|
136
|
+
<ObjectDataTable schema={schema} />
|
|
137
|
+
</SchemaRendererProvider>,
|
|
138
|
+
);
|
|
139
|
+
|
|
140
|
+
expect(container).toBeDefined();
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('should pass through object[] columns unchanged', () => {
|
|
144
|
+
const schema = {
|
|
145
|
+
...baseSchema,
|
|
146
|
+
columns: [
|
|
147
|
+
{ header: 'Name', accessorKey: 'name' },
|
|
148
|
+
{ header: 'Amount', accessorKey: 'amount' },
|
|
149
|
+
],
|
|
150
|
+
data: [
|
|
151
|
+
{ name: 'Deal A', amount: 1000 },
|
|
152
|
+
],
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
const { container } = render(
|
|
156
|
+
<SchemaRendererProvider>
|
|
157
|
+
<ObjectDataTable schema={schema} />
|
|
158
|
+
</SchemaRendererProvider>,
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
expect(container).toBeDefined();
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
describe('normalizeColumns', () => {
|
|
166
|
+
it('should convert snake_case string to title-cased header', () => {
|
|
167
|
+
const result = normalizeColumns(['close_date']);
|
|
168
|
+
expect(result).toEqual([{ header: 'Close Date', accessorKey: 'close_date' }]);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should convert camelCase string to title-cased header', () => {
|
|
172
|
+
const result = normalizeColumns(['firstName']);
|
|
173
|
+
expect(result).toEqual([{ header: 'First Name', accessorKey: 'firstName' }]);
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('should convert simple string to capitalized header', () => {
|
|
177
|
+
const result = normalizeColumns(['name']);
|
|
178
|
+
expect(result).toEqual([{ header: 'Name', accessorKey: 'name' }]);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('should handle multiple string columns', () => {
|
|
182
|
+
const result = normalizeColumns(['name', 'total_amount', 'createdAt']);
|
|
183
|
+
expect(result).toEqual([
|
|
184
|
+
{ header: 'Name', accessorKey: 'name' },
|
|
185
|
+
{ header: 'Total Amount', accessorKey: 'total_amount' },
|
|
186
|
+
{ header: 'Created At', accessorKey: 'createdAt' },
|
|
187
|
+
]);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should pass through object columns unchanged', () => {
|
|
191
|
+
const cols = [
|
|
192
|
+
{ header: 'Custom Name', accessorKey: 'name' },
|
|
193
|
+
{ header: 'Amount ($)', accessorKey: 'amount' },
|
|
194
|
+
];
|
|
195
|
+
const result = normalizeColumns(cols);
|
|
196
|
+
expect(result).toEqual(cols);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('should handle mixed string and object columns', () => {
|
|
200
|
+
const result = normalizeColumns([
|
|
201
|
+
'name',
|
|
202
|
+
{ header: 'Custom Amount', accessorKey: 'amount' },
|
|
203
|
+
'close_date',
|
|
204
|
+
]);
|
|
205
|
+
expect(result).toEqual([
|
|
206
|
+
{ header: 'Name', accessorKey: 'name' },
|
|
207
|
+
{ header: 'Custom Amount', accessorKey: 'amount' },
|
|
208
|
+
{ header: 'Close Date', accessorKey: 'close_date' },
|
|
209
|
+
]);
|
|
210
|
+
});
|
|
122
211
|
});
|