@object-ui/plugin-dashboard 0.5.0 → 2.0.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.
@@ -1,4 +1,4 @@
1
- import { Layout as RGLLayout } from 'react-grid-layout';
1
+ import { LayoutItem as RGLLayout } from 'react-grid-layout';
2
2
  import { DashboardSchema } from '../../types/src';
3
3
  import * as React from 'react';
4
4
  export interface DashboardGridLayoutProps {
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardGridLayout.d.ts","sourceRoot":"","sources":["../../src/DashboardGridLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAA6B,MAAM,IAAI,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnF,OAAO,kCAAkC,CAAC;AAI1C,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,kBAAkB,CAAC;AAY/E,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAwLlE,CAAC"}
1
+ {"version":3,"file":"DashboardGridLayout.d.ts","sourceRoot":"","sources":["../../src/DashboardGridLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAA2C,KAAK,UAAU,IAAI,SAAS,EAAuC,MAAM,mBAAmB,CAAC;AAC/I,OAAO,kCAAkC,CAAC;AAI1C,OAAO,KAAK,EAAE,eAAe,EAAyB,MAAM,kBAAkB,CAAC;AAU/E,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,eAAe,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAC/C,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA2LlE,CAAC"}
@@ -2,10 +2,7 @@ import { DashboardRenderer } from './DashboardRenderer';
2
2
  import { DashboardGridLayout } from './DashboardGridLayout';
3
3
  import { MetricWidget } from './MetricWidget';
4
4
  import { MetricCard } from './MetricCard';
5
- import { ReportRenderer } from './ReportRenderer';
6
- import { ReportViewer } from './ReportViewer';
7
- import { ReportBuilder } from './ReportBuilder';
8
- export { DashboardRenderer, DashboardGridLayout, MetricWidget, MetricCard, ReportRenderer, ReportViewer, ReportBuilder };
5
+ export { DashboardRenderer, DashboardGridLayout, MetricWidget, MetricCard };
9
6
  export declare const dashboardComponents: {
10
7
  DashboardRenderer: import('react').ForwardRefExoticComponent<Omit<{
11
8
  [key: string]: any;
@@ -15,8 +12,5 @@ export declare const dashboardComponents: {
15
12
  DashboardGridLayout: import('react').FC<import('./DashboardGridLayout').DashboardGridLayoutProps>;
16
13
  MetricWidget: ({ label, value, trend, icon, className, description, ...props }: import('./MetricWidget').MetricWidgetProps) => import("react/jsx-runtime").JSX.Element;
17
14
  MetricCard: import('react').FC<import('./MetricCard').MetricCardProps>;
18
- ReportRenderer: import('react').FC<import('./ReportRenderer').ReportRendererProps>;
19
- ReportViewer: import('react').FC<import('./ReportViewer').ReportViewerProps>;
20
- ReportBuilder: import('react').FC<import('./ReportBuilder').ReportBuilderProps>;
21
15
  };
22
16
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,YAAY,EAAE,UAAU,EAAE,cAAc,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC;AA2IzH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;CAQ/B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AAwF5E,eAAO,MAAM,mBAAmB;;;;;;;;;CAK/B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/plugin-dashboard",
3
- "version": "0.5.0",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Dashboard plugin for Object UI",
@@ -19,19 +19,19 @@
19
19
  "lucide-react": "^0.563.0",
20
20
  "react": "^19.2.4",
21
21
  "react-dom": "^19.2.4",
22
- "react-grid-layout": "^1.4.4",
22
+ "react-grid-layout": "^2.2.2",
23
23
  "tailwind-merge": "^2.2.1",
24
- "@object-ui/components": "0.5.0",
25
- "@object-ui/core": "0.5.0",
26
- "@object-ui/react": "0.5.0",
27
- "@object-ui/types": "0.5.0"
24
+ "@object-ui/components": "2.0.0",
25
+ "@object-ui/core": "2.0.0",
26
+ "@object-ui/react": "2.0.0",
27
+ "@object-ui/types": "2.0.0"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "react": "^18.0.0",
31
31
  "react-dom": "^18.0.0"
32
32
  },
33
33
  "devDependencies": {
34
- "@types/react-grid-layout": "^1.3.5",
34
+ "@types/react-grid-layout": "^2.1.0",
35
35
  "@vitejs/plugin-react": "^5.1.3",
36
36
  "typescript": "^5.9.3",
37
37
  "vite": "^7.3.1",
@@ -1,13 +1,11 @@
1
1
  import * as React from 'react';
2
- import { Responsive, WidthProvider, Layout as RGLLayout } from 'react-grid-layout';
2
+ import { ResponsiveGridLayout, useContainerWidth, type LayoutItem as RGLLayout, type Layout, type ResponsiveLayouts } from 'react-grid-layout';
3
3
  import 'react-grid-layout/css/styles.css';
4
4
  import { cn, Card, CardHeader, CardTitle, CardContent, Button } from '@object-ui/components';
5
5
  import { Edit, GripVertical, Save, X } from 'lucide-react';
6
6
  import { SchemaRenderer } from '@object-ui/react';
7
7
  import type { DashboardSchema, DashboardWidgetSchema } from '@object-ui/types';
8
8
 
9
- const ResponsiveGridLayout = WidthProvider(Responsive);
10
-
11
9
  const CHART_COLORS = [
12
10
  'hsl(var(--chart-1))',
13
11
  'hsl(var(--chart-2))',
@@ -29,6 +27,7 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
29
27
  onLayoutChange,
30
28
  persistLayoutKey = 'dashboard-layout',
31
29
  }) => {
30
+ const { width, containerRef, mounted } = useContainerWidth();
32
31
  const [editMode, setEditMode] = React.useState(false);
33
32
  const [layouts, setLayouts] = React.useState<{ lg: RGLLayout[] }>(() => {
34
33
  // Try to load saved layout
@@ -56,9 +55,9 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
56
55
  });
57
56
 
58
57
  const handleLayoutChange = React.useCallback(
59
- (layout: RGLLayout[], allLayouts: { lg: RGLLayout[] }) => {
60
- setLayouts(allLayouts);
61
- onLayoutChange?.(layout);
58
+ (layout: Layout, allLayouts: ResponsiveLayouts) => {
59
+ setLayouts(allLayouts as { lg: RGLLayout[] });
60
+ onLayoutChange?.(layout as RGLLayout[]);
62
61
  },
63
62
  [onLayoutChange]
64
63
  );
@@ -122,7 +121,7 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
122
121
  }, []);
123
122
 
124
123
  return (
125
- <div className={cn("w-full", className)} data-testid="grid-layout">
124
+ <div ref={containerRef} className={cn("w-full", className)} data-testid="grid-layout">
126
125
  <div className="mb-4 flex items-center justify-between">
127
126
  <h2 className="text-2xl font-bold">{schema.title || 'Dashboard'}</h2>
128
127
  <div className="flex gap-2">
@@ -149,62 +148,64 @@ export const DashboardGridLayout: React.FC<DashboardGridLayoutProps> = ({
149
148
  </div>
150
149
  </div>
151
150
 
152
- <ResponsiveGridLayout
153
- className="layout"
154
- layouts={layouts}
155
- breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
156
- cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
157
- rowHeight={60}
158
- isDraggable={editMode}
159
- isResizable={editMode}
160
- onLayoutChange={handleLayoutChange}
161
- draggableHandle=".drag-handle"
162
- >
163
- {schema.widgets?.map((widget, index) => {
164
- const widgetId = widget.id || `widget-${index}`;
165
- const componentSchema = getComponentSchema(widget);
166
- const isSelfContained = (widget as any).type === 'metric';
151
+ {mounted && (
152
+ <ResponsiveGridLayout
153
+ className="layout"
154
+ width={width}
155
+ layouts={layouts}
156
+ breakpoints={{ lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }}
157
+ cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
158
+ rowHeight={60}
159
+ dragConfig={{ enabled: editMode, handle: ".drag-handle" }}
160
+ resizeConfig={{ enabled: editMode }}
161
+ onLayoutChange={handleLayoutChange}
162
+ >
163
+ {schema.widgets?.map((widget, index) => {
164
+ const widgetId = widget.id || `widget-${index}`;
165
+ const componentSchema = getComponentSchema(widget);
166
+ const isSelfContained = (widget as any).type === 'metric';
167
167
 
168
- return (
169
- <div key={widgetId} className="h-full">
170
- {isSelfContained ? (
171
- <div className="h-full w-full relative">
172
- {editMode && (
173
- <div className="drag-handle absolute top-2 right-2 z-10 cursor-move p-1 bg-background/80 rounded border border-border">
174
- <GripVertical className="h-4 w-4" />
175
- </div>
176
- )}
177
- <SchemaRenderer schema={componentSchema} className="h-full w-full" />
178
- </div>
179
- ) : (
180
- <Card className={cn(
181
- "h-full overflow-hidden border-border/50 shadow-sm transition-all",
182
- "bg-card/50 backdrop-blur-sm",
183
- editMode && "ring-2 ring-primary/20"
184
- )}>
185
- {widget.title && (
186
- <CardHeader className="pb-2 border-b border-border/40 bg-muted/20 flex flex-row items-center justify-between">
187
- <CardTitle className="text-base font-medium tracking-tight truncate" title={widget.title}>
188
- {widget.title}
189
- </CardTitle>
190
- {editMode && (
191
- <div className="drag-handle cursor-move p-1 hover:bg-muted/40 rounded">
192
- <GripVertical className="h-4 w-4" />
193
- </div>
194
- )}
195
- </CardHeader>
196
- )}
197
- <CardContent className="p-0 h-full">
198
- <div className={cn("h-full w-full overflow-auto", !widget.title ? "p-4" : "p-4")}>
199
- <SchemaRenderer schema={componentSchema} />
200
- </div>
201
- </CardContent>
202
- </Card>
203
- )}
204
- </div>
205
- );
206
- })}
207
- </ResponsiveGridLayout>
168
+ return (
169
+ <div key={widgetId} className="h-full">
170
+ {isSelfContained ? (
171
+ <div className="h-full w-full relative">
172
+ {editMode && (
173
+ <div className="drag-handle absolute top-2 right-2 z-10 cursor-move p-1 bg-background/80 rounded border border-border">
174
+ <GripVertical className="h-4 w-4" />
175
+ </div>
176
+ )}
177
+ <SchemaRenderer schema={componentSchema} className="h-full w-full" />
178
+ </div>
179
+ ) : (
180
+ <Card className={cn(
181
+ "h-full overflow-hidden border-border/50 shadow-sm transition-all",
182
+ "bg-card/50 backdrop-blur-sm",
183
+ editMode && "ring-2 ring-primary/20"
184
+ )}>
185
+ {widget.title && (
186
+ <CardHeader className="pb-2 border-b border-border/40 bg-muted/20 flex flex-row items-center justify-between">
187
+ <CardTitle className="text-base font-medium tracking-tight truncate" title={widget.title}>
188
+ {widget.title}
189
+ </CardTitle>
190
+ {editMode && (
191
+ <div className="drag-handle cursor-move p-1 hover:bg-muted/40 rounded">
192
+ <GripVertical className="h-4 w-4" />
193
+ </div>
194
+ )}
195
+ </CardHeader>
196
+ )}
197
+ <CardContent className="p-0 h-full">
198
+ <div className={cn("h-full w-full overflow-auto p-4")}>
199
+ <SchemaRenderer schema={componentSchema} />
200
+ </div>
201
+ </CardContent>
202
+ </Card>
203
+ )}
204
+ </div>
205
+ );
206
+ })}
207
+ </ResponsiveGridLayout>
208
+ )}
208
209
  </div>
209
210
  );
210
211
  };
@@ -21,14 +21,14 @@ const CHART_COLORS = [
21
21
  ];
22
22
 
23
23
  export const DashboardRenderer = forwardRef<HTMLDivElement, { schema: DashboardSchema; className?: string; [key: string]: any }>(
24
- ({ schema, className, ...props }, ref) => {
24
+ ({ schema, className, dataSource, ...props }, ref) => {
25
25
  const columns = schema.columns || 4; // Default to 4 columns for better density
26
26
  const gap = schema.gap || 4;
27
27
 
28
28
  return (
29
- <div
30
- ref={ref}
31
- className={cn("grid auto-rows-min", className)}
29
+ <div
30
+ ref={ref}
31
+ className={cn("grid auto-rows-min", className)}
32
32
  style={{
33
33
  gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))`,
34
34
  gap: `${gap * 0.25}rem`
package/src/index.tsx CHANGED
@@ -11,18 +11,15 @@ import { DashboardRenderer } from './DashboardRenderer';
11
11
  import { DashboardGridLayout } from './DashboardGridLayout';
12
12
  import { MetricWidget } from './MetricWidget';
13
13
  import { MetricCard } from './MetricCard';
14
- import { ReportRenderer } from './ReportRenderer';
15
- import { ReportViewer } from './ReportViewer';
16
- import { ReportBuilder } from './ReportBuilder';
17
14
 
18
- export { DashboardRenderer, DashboardGridLayout, MetricWidget, MetricCard, ReportRenderer, ReportViewer, ReportBuilder };
15
+ export { DashboardRenderer, DashboardGridLayout, MetricWidget, MetricCard };
19
16
 
20
17
  // Register dashboard component
21
18
  ComponentRegistry.register(
22
19
  'dashboard',
23
20
  DashboardRenderer,
24
21
  {
25
- namespace: 'plugin-dashboard',
22
+ namespace: 'view',
26
23
  label: 'Dashboard',
27
24
  category: 'Complex',
28
25
  icon: 'layout-dashboard',
@@ -80,57 +77,6 @@ ComponentRegistry.register(
80
77
  }
81
78
  );
82
79
 
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
80
  // Register dashboard grid layout component
135
81
  ComponentRegistry.register(
136
82
  'dashboard-grid',
@@ -159,8 +105,4 @@ export const dashboardComponents = {
159
105
  DashboardGridLayout,
160
106
  MetricWidget,
161
107
  MetricCard,
162
- ReportRenderer,
163
- ReportViewer,
164
- ReportBuilder,
165
108
  };
166
-
@@ -1,11 +0,0 @@
1
- import { default as React } from 'react';
2
- import { ReportBuilderSchema } from '../../types/src';
3
- export interface ReportBuilderProps {
4
- schema: ReportBuilderSchema;
5
- }
6
- /**
7
- * ReportBuilder - Interactive report builder component
8
- * Allows users to configure report fields, filters, grouping, sections, and export settings
9
- */
10
- export declare const ReportBuilder: React.FC<ReportBuilderProps>;
11
- //# sourceMappingURL=ReportBuilder.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportBuilder.d.ts","sourceRoot":"","sources":["../../src/ReportBuilder.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAmB,MAAM,OAAO,CAAC;AAExC,OAAO,KAAK,EAAE,mBAAmB,EAAyE,MAAM,kBAAkB,CAAC;AAInI,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,mBAAmB,CAAC;CAC7B;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA0lBtD,CAAC"}
@@ -1,15 +0,0 @@
1
- import { default as React } from 'react';
2
- export interface ReportRendererProps {
3
- schema: {
4
- type: string;
5
- id?: string;
6
- title?: string;
7
- description?: string;
8
- chart?: any;
9
- data?: any[];
10
- columns?: any[];
11
- className?: string;
12
- };
13
- }
14
- export declare const ReportRenderer: React.FC<ReportRendererProps>;
15
- //# sourceMappingURL=ReportRenderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportRenderer.d.ts","sourceRoot":"","sources":["../../src/ReportRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE,GAAG,CAAC;QACZ,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAuExD,CAAC"}
@@ -1,11 +0,0 @@
1
- import { default as React } from 'react';
2
- import { ReportViewerSchema } from '../../types/src';
3
- export interface ReportViewerProps {
4
- schema: ReportViewerSchema;
5
- }
6
- /**
7
- * ReportViewer - Display a generated report with optional toolbar
8
- * Supports rendering report sections, charts, tables, and export functionality
9
- */
10
- export declare const ReportViewer: React.FC<ReportViewerProps>;
11
- //# sourceMappingURL=ReportViewer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ReportViewer.d.ts","sourceRoot":"","sources":["../../src/ReportViewer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,kBAAkB,EAAiB,MAAM,kBAAkB,CAAC;AAG1E,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAgNpD,CAAC"}