@object-ui/plugin-dashboard 3.0.3 → 3.1.0
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 +40 -7
- package/dist/index.js +3848 -2635
- package/dist/index.umd.cjs +5 -5
- package/dist/src/DashboardConfigPanel.d.ts +28 -0
- package/dist/src/DashboardConfigPanel.d.ts.map +1 -0
- package/dist/src/DashboardConfigPanel.stories.d.ts +14 -0
- package/dist/src/DashboardConfigPanel.stories.d.ts.map +1 -0
- package/dist/src/DashboardGridLayout.d.ts.map +1 -1
- package/dist/src/DashboardRenderer.d.ts +14 -0
- package/dist/src/DashboardRenderer.d.ts.map +1 -1
- package/dist/src/DashboardWithConfig.d.ts +32 -0
- package/dist/src/DashboardWithConfig.d.ts.map +1 -0
- package/dist/src/MetricCard.d.ts +8 -2
- package/dist/src/MetricCard.d.ts.map +1 -1
- package/dist/src/MetricWidget.d.ts +12 -3
- package/dist/src/MetricWidget.d.ts.map +1 -1
- package/dist/src/ObjectDataTable.d.ts +39 -0
- package/dist/src/ObjectDataTable.d.ts.map +1 -0
- package/dist/src/ObjectPivotTable.d.ts +29 -0
- package/dist/src/ObjectPivotTable.d.ts.map +1 -0
- package/dist/src/PivotTable.d.ts +14 -0
- package/dist/src/PivotTable.d.ts.map +1 -0
- package/dist/src/WidgetConfigPanel.d.ts +43 -0
- package/dist/src/WidgetConfigPanel.d.ts.map +1 -0
- package/dist/src/index.d.ts +13 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/utils.d.ts +14 -0
- package/dist/src/utils.d.ts.map +1 -0
- package/package.json +7 -7
- package/src/DashboardConfigPanel.stories.tsx +164 -0
- package/src/DashboardConfigPanel.tsx +158 -0
- package/src/DashboardGridLayout.tsx +101 -3
- package/src/DashboardRenderer.tsx +269 -28
- package/src/DashboardWithConfig.tsx +211 -0
- package/src/MetricCard.tsx +11 -4
- package/src/MetricWidget.tsx +18 -11
- package/src/ObjectDataTable.tsx +191 -0
- package/src/ObjectPivotTable.tsx +160 -0
- package/src/PivotTable.tsx +262 -0
- package/src/WidgetConfigPanel.tsx +540 -0
- package/src/__tests__/DashboardConfigPanel.test.tsx +206 -0
- package/src/__tests__/DashboardRenderer.designMode.test.tsx +386 -0
- package/src/__tests__/DashboardRenderer.header.test.tsx +114 -0
- package/src/__tests__/DashboardRenderer.mobile.test.tsx +214 -0
- package/src/__tests__/DashboardRenderer.widgetData.test.tsx +1022 -0
- package/src/__tests__/DashboardWithConfig.test.tsx +276 -0
- package/src/__tests__/MetricCard.test.tsx +23 -0
- package/src/__tests__/ObjectDataTable.test.tsx +122 -0
- package/src/__tests__/ObjectPivotTable.test.tsx +192 -0
- package/src/__tests__/PivotTable.test.tsx +162 -0
- package/src/__tests__/WidgetConfigPanel.test.tsx +492 -0
- package/src/__tests__/ensureWidgetIds.test.tsx +103 -0
- package/src/index.tsx +107 -1
- package/src/utils.ts +17 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ObjectUI
|
|
3
|
+
* Copyright (c) 2024-present ObjectStack Inc.
|
|
4
|
+
*
|
|
5
|
+
* This source code is licensed under the MIT license found in the
|
|
6
|
+
* LICENSE file in the root directory of this source tree.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
|
|
10
|
+
import { render } from '@testing-library/react';
|
|
11
|
+
import { DashboardRenderer } from '../DashboardRenderer';
|
|
12
|
+
import type { DashboardSchema } from '@object-ui/types';
|
|
13
|
+
|
|
14
|
+
describe('DashboardRenderer mobile layout', () => {
|
|
15
|
+
let originalInnerWidth: number;
|
|
16
|
+
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
originalInnerWidth = window.innerWidth;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(() => {
|
|
22
|
+
// Restore original window size
|
|
23
|
+
Object.defineProperty(window, 'innerWidth', {
|
|
24
|
+
writable: true,
|
|
25
|
+
configurable: true,
|
|
26
|
+
value: originalInnerWidth,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const setWindowWidth = (width: number) => {
|
|
31
|
+
Object.defineProperty(window, 'innerWidth', {
|
|
32
|
+
writable: true,
|
|
33
|
+
configurable: true,
|
|
34
|
+
value: width,
|
|
35
|
+
});
|
|
36
|
+
window.dispatchEvent(new Event('resize'));
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
it('should use mobile layout when window width is less than 768px', () => {
|
|
40
|
+
const schema: DashboardSchema = {
|
|
41
|
+
type: 'dashboard',
|
|
42
|
+
name: 'test',
|
|
43
|
+
title: 'Test Dashboard',
|
|
44
|
+
widgets: [
|
|
45
|
+
{
|
|
46
|
+
type: 'metric',
|
|
47
|
+
title: 'Revenue',
|
|
48
|
+
options: { value: '$100k', label: 'Total Revenue' },
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
type: 'metric',
|
|
52
|
+
title: 'Users',
|
|
53
|
+
options: { value: '1,234', label: 'Active Users' },
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Set mobile viewport width
|
|
59
|
+
setWindowWidth(375);
|
|
60
|
+
|
|
61
|
+
const { container } = render(<DashboardRenderer schema={schema} />);
|
|
62
|
+
|
|
63
|
+
// Mobile layout should have px-4 class and grid grid-cols-2 for metrics
|
|
64
|
+
const mobileContainer = container.querySelector('.px-4');
|
|
65
|
+
expect(mobileContainer).toBeTruthy();
|
|
66
|
+
|
|
67
|
+
const metricGrid = container.querySelector('.grid.grid-cols-2');
|
|
68
|
+
expect(metricGrid).toBeTruthy();
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should use desktop layout when window width is 768px or more', () => {
|
|
72
|
+
const schema: DashboardSchema = {
|
|
73
|
+
type: 'dashboard',
|
|
74
|
+
name: 'test',
|
|
75
|
+
title: 'Test Dashboard',
|
|
76
|
+
widgets: [
|
|
77
|
+
{
|
|
78
|
+
type: 'metric',
|
|
79
|
+
title: 'Revenue',
|
|
80
|
+
options: { value: '$100k', label: 'Total Revenue' },
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
// Set desktop viewport width
|
|
86
|
+
setWindowWidth(1024);
|
|
87
|
+
|
|
88
|
+
const { container } = render(<DashboardRenderer schema={schema} />);
|
|
89
|
+
|
|
90
|
+
// Desktop layout should have grid class but not px-4 or grid-cols-2
|
|
91
|
+
const desktopGrid = container.querySelector('.grid.auto-rows-min');
|
|
92
|
+
expect(desktopGrid).toBeTruthy();
|
|
93
|
+
|
|
94
|
+
const mobileContainer = container.querySelector('.px-4');
|
|
95
|
+
expect(mobileContainer).toBeFalsy();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it('should separate metric and non-metric widgets in mobile layout', () => {
|
|
99
|
+
const schema: DashboardSchema = {
|
|
100
|
+
type: 'dashboard',
|
|
101
|
+
name: 'test',
|
|
102
|
+
title: 'Test Dashboard',
|
|
103
|
+
widgets: [
|
|
104
|
+
{
|
|
105
|
+
type: 'metric',
|
|
106
|
+
title: 'Metric 1',
|
|
107
|
+
options: { value: '100', label: 'Count' },
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
type: 'metric',
|
|
111
|
+
title: 'Metric 2',
|
|
112
|
+
options: { value: '200', label: 'Total' },
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: 'bar',
|
|
116
|
+
title: 'Chart',
|
|
117
|
+
options: {
|
|
118
|
+
data: { items: [{ name: 'A', value: 10 }] },
|
|
119
|
+
xField: 'name',
|
|
120
|
+
yField: 'value',
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
// Set mobile viewport width
|
|
127
|
+
setWindowWidth(375);
|
|
128
|
+
|
|
129
|
+
const { container } = render(<DashboardRenderer schema={schema} />);
|
|
130
|
+
|
|
131
|
+
// Should have a 2-column grid for metrics
|
|
132
|
+
const metricGrid = container.querySelector('.grid.grid-cols-2');
|
|
133
|
+
expect(metricGrid).toBeTruthy();
|
|
134
|
+
|
|
135
|
+
// Should have metric widgets in the grid
|
|
136
|
+
const metricWidgets = metricGrid?.children;
|
|
137
|
+
expect(metricWidgets?.length).toBe(2);
|
|
138
|
+
|
|
139
|
+
// Should have a flex-col container for other widgets
|
|
140
|
+
const otherWidgetsContainer = container.querySelector('.flex.flex-col.gap-4');
|
|
141
|
+
expect(otherWidgetsContainer).toBeTruthy();
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
it('should handle mobile layout with only metric widgets', () => {
|
|
145
|
+
const schema: DashboardSchema = {
|
|
146
|
+
type: 'dashboard',
|
|
147
|
+
name: 'test',
|
|
148
|
+
title: 'Test Dashboard',
|
|
149
|
+
widgets: [
|
|
150
|
+
{
|
|
151
|
+
type: 'metric',
|
|
152
|
+
title: 'Metric 1',
|
|
153
|
+
options: { value: '100' },
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
type: 'metric',
|
|
157
|
+
title: 'Metric 2',
|
|
158
|
+
options: { value: '200' },
|
|
159
|
+
},
|
|
160
|
+
],
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// Set mobile viewport width
|
|
164
|
+
setWindowWidth(375);
|
|
165
|
+
|
|
166
|
+
const { container } = render(<DashboardRenderer schema={schema} />);
|
|
167
|
+
|
|
168
|
+
// Should have a 2-column grid for metrics
|
|
169
|
+
const metricGrid = container.querySelector('.grid.grid-cols-2');
|
|
170
|
+
expect(metricGrid).toBeTruthy();
|
|
171
|
+
expect(metricGrid?.children.length).toBe(2);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
it('should handle mobile layout with only non-metric widgets', () => {
|
|
175
|
+
const schema: DashboardSchema = {
|
|
176
|
+
type: 'dashboard',
|
|
177
|
+
name: 'test',
|
|
178
|
+
title: 'Test Dashboard',
|
|
179
|
+
widgets: [
|
|
180
|
+
{
|
|
181
|
+
type: 'bar',
|
|
182
|
+
title: 'Chart 1',
|
|
183
|
+
options: {
|
|
184
|
+
data: { items: [{ name: 'A', value: 10 }] },
|
|
185
|
+
xField: 'name',
|
|
186
|
+
yField: 'value',
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
type: 'line',
|
|
191
|
+
title: 'Chart 2',
|
|
192
|
+
options: {
|
|
193
|
+
data: { items: [{ name: 'B', value: 20 }] },
|
|
194
|
+
xField: 'name',
|
|
195
|
+
yField: 'value',
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
],
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// Set mobile viewport width
|
|
202
|
+
setWindowWidth(375);
|
|
203
|
+
|
|
204
|
+
const { container } = render(<DashboardRenderer schema={schema} />);
|
|
205
|
+
|
|
206
|
+
// Should not have a metric grid
|
|
207
|
+
const metricGrid = container.querySelector('.grid.grid-cols-2');
|
|
208
|
+
expect(metricGrid).toBeFalsy();
|
|
209
|
+
|
|
210
|
+
// Should have a flex-col container for other widgets
|
|
211
|
+
const otherWidgetsContainer = container.querySelector('.flex.flex-col.gap-4');
|
|
212
|
+
expect(otherWidgetsContainer).toBeTruthy();
|
|
213
|
+
});
|
|
214
|
+
});
|