@object-ui/plugin-view 0.5.0 → 3.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.
package/src/index.tsx CHANGED
@@ -6,24 +6,166 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
 
9
- import React from 'react';
9
+ import React, { useContext } from 'react';
10
10
  import { ComponentRegistry } from '@object-ui/core';
11
11
  import { ObjectView } from './ObjectView';
12
+ import { ViewSwitcher } from './ViewSwitcher';
13
+ import { FilterUI } from './FilterUI';
14
+ import { SortUI } from './SortUI';
12
15
 
13
- export { ObjectView };
16
+ export { ObjectView, ViewSwitcher, FilterUI, SortUI };
14
17
  export type { ObjectViewProps } from './ObjectView';
18
+ export type { ViewSwitcherProps } from './ViewSwitcher';
19
+ export type { FilterUIProps } from './FilterUI';
20
+ export type { SortUIProps } from './SortUI';
21
+
22
+ /**
23
+ * SchemaRendererContext is created by @object-ui/react.
24
+ * We import it dynamically to avoid a circular dependency.
25
+ * The context value provides { dataSource }.
26
+ * A fallback context is created so hooks are never called conditionally.
27
+ */
28
+ const FallbackContext = React.createContext<any>(null);
29
+ let SchemaRendererContext: React.Context<any> = FallbackContext;
30
+ try {
31
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
32
+ const mod = require('@object-ui/react');
33
+ // The context is re-exported from @object-ui/react
34
+ if (mod.SchemaRendererContext) {
35
+ SchemaRendererContext = mod.SchemaRendererContext;
36
+ }
37
+ } catch {
38
+ // @object-ui/react not available — registry-based dataSource only
39
+ }
15
40
 
16
41
  // Register object-view component
17
42
  const ObjectViewRenderer: React.FC<{ schema: any }> = ({ schema }) => {
18
- return <ObjectView schema={schema} dataSource={null as any} />;
43
+ // Resolve dataSource from SchemaRendererProvider context
44
+ const ctx = useContext(SchemaRendererContext);
45
+ const dataSource = ctx?.dataSource ?? null;
46
+
47
+ return <ObjectView schema={schema} dataSource={dataSource} />;
19
48
  };
20
49
 
21
50
  ComponentRegistry.register('object-view', ObjectViewRenderer, {
22
- namespace: 'plugin-view'
51
+ namespace: 'plugin-view',
52
+ label: 'Object View',
53
+ category: 'view',
54
+ icon: 'LayoutDashboard',
55
+ inputs: [
56
+ { name: 'objectName', type: 'string', label: 'Object Name', required: true },
57
+ { name: 'title', type: 'string', label: 'Title' },
58
+ { name: 'description', type: 'string', label: 'Description' },
59
+ { name: 'layout', type: 'enum', label: 'Form Layout', enum: ['drawer', 'modal', 'page'] },
60
+ { name: 'defaultViewType', type: 'enum', label: 'Default View Type', enum: ['grid', 'kanban', 'gallery', 'calendar', 'timeline', 'gantt', 'map'] },
61
+ { name: 'defaultListView', type: 'string', label: 'Default Named View' },
62
+ { name: 'showSearch', type: 'boolean', label: 'Show Search' },
63
+ { name: 'showFilters', type: 'boolean', label: 'Show Filters' },
64
+ { name: 'showCreate', type: 'boolean', label: 'Show Create Button' },
65
+ { name: 'showRefresh', type: 'boolean', label: 'Show Refresh Button' },
66
+ { name: 'showViewSwitcher', type: 'boolean', label: 'Show View Switcher' },
67
+ { name: 'listViews', type: 'object', label: 'Named List Views' },
68
+ { name: 'navigation', type: 'object', label: 'Navigation Config' },
69
+ { name: 'searchableFields', type: 'array', label: 'Searchable Fields' },
70
+ { name: 'filterableFields', type: 'array', label: 'Filterable Fields' },
71
+ ],
72
+ defaultProps: {
73
+ layout: 'drawer',
74
+ defaultViewType: 'grid',
75
+ showSearch: true,
76
+ showFilters: true,
77
+ showCreate: true,
78
+ showRefresh: true,
79
+ showViewSwitcher: true,
80
+ },
81
+ });
82
+
83
+ // Register alias 'view' → same renderer
84
+ ComponentRegistry.register('view', ObjectViewRenderer, {
85
+ namespace: 'plugin-view',
86
+ label: 'View',
87
+ category: 'view',
88
+ });
89
+
90
+ ComponentRegistry.register('view-switcher', ViewSwitcher, {
91
+ namespace: 'view',
92
+ label: 'View Switcher',
93
+ category: 'view',
94
+ icon: 'LayoutGrid',
95
+ inputs: [
96
+ { name: 'views', type: 'array', label: 'Views', required: true },
97
+ { name: 'defaultView', type: 'string', label: 'Default View' },
98
+ { name: 'activeView', type: 'string', label: 'Active View' },
99
+ { name: 'variant', type: 'enum', label: 'Variant', enum: ['tabs', 'buttons', 'dropdown'] },
100
+ { name: 'position', type: 'enum', label: 'Position', enum: ['top', 'bottom', 'left', 'right'] },
101
+ { name: 'persistPreference', type: 'boolean', label: 'Persist Preference' },
102
+ { name: 'storageKey', type: 'string', label: 'Storage Key' },
103
+ { name: 'onViewChange', type: 'string', label: 'On View Change Event' },
104
+ ],
105
+ defaultProps: {
106
+ variant: 'tabs',
107
+ position: 'top',
108
+ defaultView: 'grid',
109
+ views: [
110
+ { type: 'grid', label: 'Grid', schema: { type: 'text', content: 'Grid view' } },
111
+ { type: 'list', label: 'List', schema: { type: 'text', content: 'List view' } },
112
+ ],
113
+ },
114
+ });
115
+
116
+ ComponentRegistry.register('filter-ui', FilterUI, {
117
+ namespace: 'view',
118
+ label: 'Filter UI',
119
+ category: 'view',
120
+ icon: 'SlidersHorizontal',
121
+ inputs: [
122
+ { name: 'filters', type: 'array', label: 'Filters', required: true },
123
+ { name: 'values', type: 'object', label: 'Values' },
124
+ { name: 'onChange', type: 'string', label: 'On Change Event' },
125
+ { name: 'showClear', type: 'boolean', label: 'Show Clear Button' },
126
+ { name: 'showApply', type: 'boolean', label: 'Show Apply Button' },
127
+ { name: 'layout', type: 'enum', label: 'Layout', enum: ['inline', 'popover', 'drawer'] },
128
+ ],
129
+ defaultProps: {
130
+ layout: 'inline',
131
+ showApply: false,
132
+ showClear: true,
133
+ filters: [
134
+ { field: 'name', label: 'Name', type: 'text', placeholder: 'Search name' },
135
+ { field: 'status', label: 'Status', type: 'select', options: [
136
+ { label: 'Open', value: 'open' },
137
+ { label: 'Closed', value: 'closed' },
138
+ ] },
139
+ { field: 'created_at', label: 'Created', type: 'date' },
140
+ ],
141
+ },
142
+ });
143
+
144
+ ComponentRegistry.register('sort-ui', SortUI, {
145
+ namespace: 'view',
146
+ label: 'Sort UI',
147
+ category: 'view',
148
+ icon: 'ArrowUpDown',
149
+ inputs: [
150
+ { name: 'fields', type: 'array', label: 'Fields', required: true },
151
+ { name: 'sort', type: 'array', label: 'Sort' },
152
+ { name: 'onChange', type: 'string', label: 'On Change Event' },
153
+ { name: 'multiple', type: 'boolean', label: 'Allow Multiple' },
154
+ { name: 'variant', type: 'enum', label: 'Variant', enum: ['dropdown', 'buttons'] },
155
+ ],
156
+ defaultProps: {
157
+ variant: 'dropdown',
158
+ multiple: true,
159
+ fields: [
160
+ { field: 'name', label: 'Name' },
161
+ { field: 'created_at', label: 'Created At' },
162
+ ],
163
+ sort: [{ field: 'name', direction: 'asc' }],
164
+ },
23
165
  });
24
166
 
25
167
  // Simple View Renderer (Container)
26
- const SimpleViewRenderer: React.FC<any> = ({ schema, className, children, ...props }) => {
168
+ const SimpleViewRenderer: React.FC<any> = ({ schema, className, children, dataSource, ...props }) => {
27
169
  // If columns prop is present, use grid layout
28
170
  const style = schema.props?.columns
29
171
  ? { display: 'grid', gridTemplateColumns: `repeat(${schema.props.columns}, 1fr)`, gap: '1rem' }
package/vite.config.ts CHANGED
@@ -9,6 +9,7 @@ export default defineConfig({
9
9
  dts({
10
10
  insertTypesEntry: true,
11
11
  include: ['src'],
12
+ exclude: ['**/*.test.ts', '**/*.test.tsx'],
12
13
  }),
13
14
  ],
14
15
  build: {
@@ -0,0 +1,12 @@
1
+ /// <reference types="vitest" />
2
+ import { defineConfig } from 'vite';
3
+ import react from '@vitejs/plugin-react';
4
+
5
+ export default defineConfig({
6
+ plugins: [react()],
7
+ test: {
8
+ environment: 'happy-dom',
9
+ globals: true,
10
+ setupFiles: ['./vitest.setup.ts'],
11
+ },
12
+ });
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';