@object-ui/plugin-dashboard 0.1.1 → 0.5.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.
Files changed (36) hide show
  1. package/.turbo/turbo-build.log +20 -0
  2. package/dist/index.css +1 -0
  3. package/dist/index.js +5797 -266
  4. package/dist/index.umd.cjs +5 -2
  5. package/dist/src/DashboardGridLayout.d.ts +11 -0
  6. package/dist/src/DashboardGridLayout.d.ts.map +1 -0
  7. package/dist/src/DashboardRenderer.d.ts +1 -1
  8. package/dist/src/DashboardRenderer.d.ts.map +1 -1
  9. package/dist/src/MetricCard.d.ts +16 -0
  10. package/dist/src/MetricCard.d.ts.map +1 -0
  11. package/dist/src/MetricWidget.d.ts +1 -1
  12. package/dist/src/MetricWidget.d.ts.map +1 -1
  13. package/dist/src/ReportBuilder.d.ts +11 -0
  14. package/dist/src/ReportBuilder.d.ts.map +1 -0
  15. package/dist/src/ReportRenderer.d.ts +15 -0
  16. package/dist/src/ReportRenderer.d.ts.map +1 -0
  17. package/dist/src/ReportViewer.d.ts +11 -0
  18. package/dist/src/ReportViewer.d.ts.map +1 -0
  19. package/dist/src/index.d.ts +19 -1
  20. package/dist/src/index.d.ts.map +1 -1
  21. package/package.json +10 -8
  22. package/src/DashboardGridLayout.tsx +210 -0
  23. package/src/DashboardRenderer.tsx +108 -20
  24. package/src/MetricCard.tsx +75 -0
  25. package/src/MetricWidget.tsx +13 -3
  26. package/src/ReportBuilder.tsx +625 -0
  27. package/src/ReportRenderer.tsx +89 -0
  28. package/src/ReportViewer.tsx +232 -0
  29. package/src/__tests__/DashboardGridLayout.test.tsx +199 -0
  30. package/src/__tests__/MetricCard.test.tsx +59 -0
  31. package/src/__tests__/ReportBuilder.test.tsx +115 -0
  32. package/src/__tests__/ReportViewer.test.tsx +107 -0
  33. package/src/index.tsx +122 -3
  34. package/vite.config.ts +19 -0
  35. package/vitest.config.ts +9 -0
  36. package/vitest.setup.tsx +18 -0
@@ -0,0 +1,107 @@
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 } from 'vitest';
10
+ import { render, screen } from '@testing-library/react';
11
+ import '@testing-library/jest-dom';
12
+ import { ReportViewer } from '../ReportViewer';
13
+ import type { ReportViewerSchema } from '@object-ui/types';
14
+
15
+ describe('ReportViewer', () => {
16
+ it('should render empty state when no report is provided', () => {
17
+ const schema: ReportViewerSchema = {
18
+ type: 'report-viewer',
19
+ };
20
+
21
+ render(<ReportViewer schema={schema} />);
22
+
23
+ expect(screen.getByText('No report to display')).toBeInTheDocument();
24
+ });
25
+
26
+ it('should render report with title and description', () => {
27
+ const schema: ReportViewerSchema = {
28
+ type: 'report-viewer',
29
+ report: {
30
+ type: 'report',
31
+ title: 'Sales Report',
32
+ description: 'Monthly sales analysis',
33
+ fields: [],
34
+ sections: [],
35
+ },
36
+ showToolbar: true,
37
+ };
38
+
39
+ render(<ReportViewer schema={schema} />);
40
+
41
+ expect(screen.getByText('Sales Report')).toBeInTheDocument();
42
+ expect(screen.getByText('Monthly sales analysis')).toBeInTheDocument();
43
+ });
44
+
45
+ it('should render export and print buttons when enabled', () => {
46
+ const schema: ReportViewerSchema = {
47
+ type: 'report-viewer',
48
+ report: {
49
+ type: 'report',
50
+ title: 'Test Report',
51
+ showExportButtons: true,
52
+ fields: [],
53
+ sections: [],
54
+ },
55
+ showToolbar: true,
56
+ allowExport: true,
57
+ allowPrint: true,
58
+ };
59
+
60
+ render(<ReportViewer schema={schema} />);
61
+
62
+ expect(screen.getByText('Export')).toBeInTheDocument();
63
+ expect(screen.getByText('Print')).toBeInTheDocument();
64
+ });
65
+
66
+ it('should render loading state', () => {
67
+ const schema: ReportViewerSchema = {
68
+ type: 'report-viewer',
69
+ report: {
70
+ type: 'report',
71
+ title: 'Test Report',
72
+ fields: [],
73
+ sections: [],
74
+ },
75
+ loading: true,
76
+ };
77
+
78
+ render(<ReportViewer schema={schema} />);
79
+
80
+ expect(screen.getByText('Loading report data...')).toBeInTheDocument();
81
+ });
82
+
83
+ it('should render report data in table when no sections defined', () => {
84
+ const schema: ReportViewerSchema = {
85
+ type: 'report-viewer',
86
+ report: {
87
+ type: 'report',
88
+ title: 'User Report',
89
+ fields: [
90
+ { name: 'name', label: 'Name' },
91
+ { name: 'email', label: 'Email' },
92
+ ],
93
+ },
94
+ data: [
95
+ { name: 'John Doe', email: 'john@example.com' },
96
+ { name: 'Jane Smith', email: 'jane@example.com' },
97
+ ],
98
+ };
99
+
100
+ render(<ReportViewer schema={schema} />);
101
+
102
+ expect(screen.getByText('Name')).toBeInTheDocument();
103
+ expect(screen.getByText('Email')).toBeInTheDocument();
104
+ expect(screen.getByText('John Doe')).toBeInTheDocument();
105
+ expect(screen.getByText('jane@example.com')).toBeInTheDocument();
106
+ });
107
+ });
package/src/index.tsx CHANGED
@@ -8,15 +8,21 @@
8
8
 
9
9
  import { ComponentRegistry } from '@object-ui/core';
10
10
  import { DashboardRenderer } from './DashboardRenderer';
11
+ import { DashboardGridLayout } from './DashboardGridLayout';
11
12
  import { MetricWidget } from './MetricWidget';
13
+ import { MetricCard } from './MetricCard';
14
+ import { ReportRenderer } from './ReportRenderer';
15
+ import { ReportViewer } from './ReportViewer';
16
+ import { ReportBuilder } from './ReportBuilder';
12
17
 
13
- export { DashboardRenderer, MetricWidget };
18
+ export { DashboardRenderer, DashboardGridLayout, MetricWidget, MetricCard, ReportRenderer, ReportViewer, ReportBuilder };
14
19
 
15
20
  // Register dashboard component
16
21
  ComponentRegistry.register(
17
22
  'dashboard',
18
23
  DashboardRenderer,
19
24
  {
25
+ namespace: 'plugin-dashboard',
20
26
  label: 'Dashboard',
21
27
  category: 'Complex',
22
28
  icon: 'layout-dashboard',
@@ -32,12 +38,13 @@ ComponentRegistry.register(
32
38
  }
33
39
  );
34
40
 
35
- // Register metric component
41
+ // Register metric widget (legacy)
36
42
  ComponentRegistry.register(
37
43
  'metric',
38
44
  MetricWidget,
39
45
  {
40
- label: 'Metric Card',
46
+ namespace: 'plugin-dashboard',
47
+ label: 'Metric Widget',
41
48
  category: 'Dashboard',
42
49
  inputs: [
43
50
  { name: 'label', type: 'string', label: 'Label' },
@@ -45,3 +52,115 @@ ComponentRegistry.register(
45
52
  ]
46
53
  }
47
54
  );
55
+
56
+ // Register metric card (new standalone component)
57
+ ComponentRegistry.register(
58
+ 'metric-card',
59
+ MetricCard,
60
+ {
61
+ namespace: 'plugin-dashboard',
62
+ label: 'Metric Card',
63
+ category: 'Dashboard',
64
+ inputs: [
65
+ { name: 'title', type: 'string', label: 'Title' },
66
+ { name: 'value', type: 'string', label: 'Value', required: true },
67
+ { name: 'icon', type: 'string', label: 'Icon (Lucide name)' },
68
+ { name: 'trend', type: 'enum', label: 'Trend', enum: [
69
+ { label: 'Up', value: 'up' },
70
+ { label: 'Down', value: 'down' },
71
+ { label: 'Neutral', value: 'neutral' }
72
+ ]},
73
+ { name: 'trendValue', type: 'string', label: 'Trend Value (e.g., +12%)' },
74
+ { name: 'description', type: 'string', label: 'Description' },
75
+ ],
76
+ defaultProps: {
77
+ title: 'Metric',
78
+ value: '0'
79
+ }
80
+ }
81
+ );
82
+
83
+ // Register report component (legacy)
84
+ ComponentRegistry.register(
85
+ 'report',
86
+ ReportRenderer,
87
+ {
88
+ namespace: 'plugin-dashboard',
89
+ label: 'Report',
90
+ category: 'Dashboard',
91
+ inputs: [
92
+ { name: 'title', type: 'string', label: 'Title' },
93
+ { name: 'description', type: 'string', label: 'Description' },
94
+ { name: 'chart', type: 'code', label: 'Chart Configuration' },
95
+ ]
96
+ }
97
+ );
98
+
99
+ // Register report viewer component
100
+ ComponentRegistry.register(
101
+ 'report-viewer',
102
+ ReportViewer,
103
+ {
104
+ namespace: 'plugin-dashboard',
105
+ label: 'Report Viewer',
106
+ category: 'Reports',
107
+ inputs: [
108
+ { name: 'report', type: 'code', label: 'Report Configuration', required: true },
109
+ { name: 'data', type: 'code', label: 'Report Data' },
110
+ { name: 'showToolbar', type: 'boolean', label: 'Show Toolbar', defaultValue: true },
111
+ { name: 'allowExport', type: 'boolean', label: 'Allow Export', defaultValue: true },
112
+ { name: 'allowPrint', type: 'boolean', label: 'Allow Print', defaultValue: true },
113
+ ]
114
+ }
115
+ );
116
+
117
+ // Register report builder component
118
+ ComponentRegistry.register(
119
+ 'report-builder',
120
+ ReportBuilder,
121
+ {
122
+ namespace: 'plugin-dashboard',
123
+ label: 'Report Builder',
124
+ category: 'Reports',
125
+ inputs: [
126
+ { name: 'report', type: 'code', label: 'Initial Report Config' },
127
+ { name: 'dataSources', type: 'code', label: 'Available Data Sources' },
128
+ { name: 'availableFields', type: 'code', label: 'Available Fields' },
129
+ { name: 'showPreview', type: 'boolean', label: 'Show Preview', defaultValue: true },
130
+ ]
131
+ }
132
+ );
133
+
134
+ // Register dashboard grid layout component
135
+ ComponentRegistry.register(
136
+ 'dashboard-grid',
137
+ DashboardGridLayout,
138
+ {
139
+ namespace: 'plugin-dashboard',
140
+ label: 'Dashboard Grid (Editable)',
141
+ category: 'Complex',
142
+ icon: 'layout-grid',
143
+ inputs: [
144
+ { name: 'title', type: 'string', label: 'Title' },
145
+ { name: 'persistLayoutKey', type: 'string', label: 'Layout Storage Key', defaultValue: 'dashboard-layout' },
146
+ { name: 'className', type: 'string', label: 'CSS Class' }
147
+ ],
148
+ defaultProps: {
149
+ title: 'Dashboard',
150
+ widgets: [],
151
+ persistLayoutKey: 'dashboard-layout',
152
+ }
153
+ }
154
+ );
155
+
156
+ // Standard Export Protocol - for manual integration
157
+ export const dashboardComponents = {
158
+ DashboardRenderer,
159
+ DashboardGridLayout,
160
+ MetricWidget,
161
+ MetricCard,
162
+ ReportRenderer,
163
+ ReportViewer,
164
+ ReportBuilder,
165
+ };
166
+
package/vite.config.ts CHANGED
@@ -9,8 +9,21 @@ export default defineConfig({
9
9
  dts({
10
10
  insertTypesEntry: true,
11
11
  include: ['src'],
12
+ exclude: ['**/*.test.ts', '**/*.test.tsx', 'node_modules'],
13
+ skipDiagnostics: true,
12
14
  }),
13
15
  ],
16
+ resolve: {
17
+ alias: {
18
+ '@': resolve(__dirname, './src'),
19
+ '@object-ui/core': resolve(__dirname, '../core/src'),
20
+ '@object-ui/types': resolve(__dirname, '../types/src'),
21
+ '@object-ui/react': resolve(__dirname, '../react/src'),
22
+ '@object-ui/components': resolve(__dirname, '../components/src'),
23
+ '@object-ui/fields': resolve(__dirname, '../fields/src'),
24
+ '@object-ui/plugin-grid': resolve(__dirname, '../plugin-grid/src'),
25
+ },
26
+ },
14
27
  build: {
15
28
  lib: {
16
29
  entry: resolve(__dirname, 'src/index.tsx'),
@@ -41,4 +54,10 @@ export default defineConfig({
41
54
  },
42
55
  },
43
56
  },
57
+ test: {
58
+ globals: true,
59
+ environment: 'happy-dom',
60
+ setupFiles: ['./vitest.setup.tsx'],
61
+ passWithNoTests: true,
62
+ },
44
63
  });
@@ -0,0 +1,9 @@
1
+ import { mergeConfig } from 'vitest/config';
2
+ import rootConfig from '../../vitest.config.mts';
3
+ import viteConfig from './vite.config';
4
+
5
+ export default mergeConfig(rootConfig, mergeConfig(viteConfig, {
6
+ test: {
7
+ environment: 'jsdom',
8
+ },
9
+ }));
@@ -0,0 +1,18 @@
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 { expect, afterEach } from 'vitest';
10
+ import { cleanup } from '@testing-library/react';
11
+ import * as matchers from '@testing-library/jest-dom/matchers';
12
+ import '@testing-library/jest-dom';
13
+
14
+ expect.extend(matchers);
15
+
16
+ afterEach(() => {
17
+ cleanup();
18
+ });