@object-ui/plugin-gantt 3.3.0 → 3.3.1
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/CHANGELOG.md +11 -0
- package/README.md +21 -1
- package/dist/index.js +1 -1
- package/dist/index.umd.cjs +1 -1
- package/package.json +34 -11
- package/.turbo/turbo-build.log +0 -22
- package/src/GanttView.tsx +0 -428
- package/src/ObjectGantt.stories.tsx +0 -112
- package/src/ObjectGantt.test.tsx +0 -88
- package/src/ObjectGantt.tsx +0 -324
- package/src/__tests__/GanttView.test.tsx +0 -69
- package/src/index.test.tsx +0 -25
- package/src/index.tsx +0 -45
- package/tsconfig.json +0 -18
- package/vite.config.ts +0 -54
- package/vitest.config.ts +0 -13
- package/vitest.setup.ts +0 -1
package/src/ObjectGantt.tsx
DELETED
|
@@ -1,324 +0,0 @@
|
|
|
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
|
-
/**
|
|
10
|
-
* ObjectGantt Component
|
|
11
|
-
*
|
|
12
|
-
* A specialized Gantt chart component that works with ObjectQL data sources.
|
|
13
|
-
* Displays tasks with date ranges, progress, and dependencies.
|
|
14
|
-
* Implements the gantt view type from @objectstack/spec view.zod ListView schema.
|
|
15
|
-
*
|
|
16
|
-
* Features:
|
|
17
|
-
* - Gantt chart timeline visualization
|
|
18
|
-
* - Task progress tracking (0-100%)
|
|
19
|
-
* - Task dependencies visualization
|
|
20
|
-
* - Date range display
|
|
21
|
-
* - Auto-scrolling timeline
|
|
22
|
-
* - Works with object/api/value data providers
|
|
23
|
-
*/
|
|
24
|
-
|
|
25
|
-
import React, { useEffect, useState, useMemo } from 'react';
|
|
26
|
-
import type { ObjectGridSchema, DataSource, ViewData, GanttConfig } from '@object-ui/types';
|
|
27
|
-
import { GanttConfigSchema } from '@objectstack/spec/ui';
|
|
28
|
-
import { useNavigationOverlay } from '@object-ui/react';
|
|
29
|
-
import { NavigationOverlay } from '@object-ui/components';
|
|
30
|
-
import { extractRecords, buildExpandFields } from '@object-ui/core';
|
|
31
|
-
import { GanttView, type GanttTask } from './GanttView';
|
|
32
|
-
|
|
33
|
-
export interface ObjectGanttProps {
|
|
34
|
-
schema: ObjectGridSchema;
|
|
35
|
-
dataSource?: DataSource;
|
|
36
|
-
className?: string;
|
|
37
|
-
onTaskClick?: (record: any) => void;
|
|
38
|
-
onRowClick?: (record: any) => void;
|
|
39
|
-
onEdit?: (record: any) => void;
|
|
40
|
-
onDelete?: (record: any) => void;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Helper to get data configuration from schema
|
|
45
|
-
*/
|
|
46
|
-
function getDataConfig(schema: ObjectGridSchema): ViewData | null {
|
|
47
|
-
if (schema.data) {
|
|
48
|
-
return schema.data;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (schema.staticData) {
|
|
52
|
-
return {
|
|
53
|
-
provider: 'value',
|
|
54
|
-
items: schema.staticData,
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if (schema.objectName) {
|
|
59
|
-
return {
|
|
60
|
-
provider: 'object',
|
|
61
|
-
object: schema.objectName,
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return null;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Helper to convert sort config to QueryParams format
|
|
70
|
-
*/
|
|
71
|
-
function convertSortToQueryParams(sort: string | any[] | undefined): Record<string, 'asc' | 'desc'> | undefined {
|
|
72
|
-
if (!sort) return undefined;
|
|
73
|
-
|
|
74
|
-
// If it's a string like "name desc"
|
|
75
|
-
if (typeof sort === 'string') {
|
|
76
|
-
const parts = sort.split(' ');
|
|
77
|
-
const field = parts[0];
|
|
78
|
-
const order = (parts[1]?.toLowerCase() === 'desc' ? 'desc' : 'asc') as 'asc' | 'desc';
|
|
79
|
-
return { [field]: order };
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// If it's an array of SortConfig objects
|
|
83
|
-
if (Array.isArray(sort)) {
|
|
84
|
-
return sort.reduce((acc, item) => {
|
|
85
|
-
if (item.field && item.order) {
|
|
86
|
-
acc[item.field] = item.order;
|
|
87
|
-
}
|
|
88
|
-
return acc;
|
|
89
|
-
}, {} as Record<string, 'asc' | 'desc'>);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
return undefined;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Helper to get gantt configuration from schema
|
|
97
|
-
*/
|
|
98
|
-
function getGanttConfig(schema: ObjectGridSchema | any): GanttConfig | null {
|
|
99
|
-
let config: GanttConfig | null = null;
|
|
100
|
-
|
|
101
|
-
// 1. Check top-level properties (ObjectGanttSchema style)
|
|
102
|
-
if (schema.startDateField && schema.endDateField) {
|
|
103
|
-
config = {
|
|
104
|
-
startDateField: schema.startDateField,
|
|
105
|
-
endDateField: schema.endDateField,
|
|
106
|
-
titleField: schema.titleField || 'name',
|
|
107
|
-
progressField: schema.progressField,
|
|
108
|
-
dependenciesField: schema.dependenciesField || schema.dependencyField,
|
|
109
|
-
colorField: schema.colorField
|
|
110
|
-
};
|
|
111
|
-
return config;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// 2. Check schema.gantt (ObjectGridSchema style)
|
|
115
|
-
if (schema.gantt) {
|
|
116
|
-
config = schema.gantt as GanttConfig;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (config) {
|
|
120
|
-
const result = GanttConfigSchema.safeParse(config);
|
|
121
|
-
if (!result.success) {
|
|
122
|
-
console.warn(`[ObjectGantt] Invalid gantt configuration:`, result.error.format());
|
|
123
|
-
}
|
|
124
|
-
return config;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
return null;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
export const ObjectGantt: React.FC<ObjectGanttProps> = ({
|
|
131
|
-
schema,
|
|
132
|
-
dataSource,
|
|
133
|
-
className,
|
|
134
|
-
onTaskClick,
|
|
135
|
-
onRowClick,
|
|
136
|
-
...rest
|
|
137
|
-
}) => {
|
|
138
|
-
const [data, setData] = useState<any[]>([]);
|
|
139
|
-
const [loading, setLoading] = useState(true);
|
|
140
|
-
const [error, setError] = useState<Error | null>(null);
|
|
141
|
-
const [objectSchema, setObjectSchema] = useState<any>(null);
|
|
142
|
-
|
|
143
|
-
const rawDataConfig = getDataConfig(schema);
|
|
144
|
-
// Memoize dataConfig using deep comparison to prevent infinite loops
|
|
145
|
-
const dataConfig = useMemo(() => {
|
|
146
|
-
return rawDataConfig;
|
|
147
|
-
}, [JSON.stringify(rawDataConfig)]);
|
|
148
|
-
|
|
149
|
-
const ganttConfig = getGanttConfig(schema);
|
|
150
|
-
const hasInlineData = dataConfig?.provider === 'value';
|
|
151
|
-
|
|
152
|
-
// Fetch data based on provider
|
|
153
|
-
useEffect(() => {
|
|
154
|
-
const fetchData = async () => {
|
|
155
|
-
try {
|
|
156
|
-
setLoading(true);
|
|
157
|
-
// 1. Check for data prop (Unified ListView)
|
|
158
|
-
if ((rest as any).data && Array.isArray((rest as any).data)) {
|
|
159
|
-
setData((rest as any).data);
|
|
160
|
-
setLoading(false);
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (hasInlineData && dataConfig?.provider === 'value') {
|
|
166
|
-
setData(dataConfig.items as any[]);
|
|
167
|
-
setLoading(false);
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
if (!dataSource || typeof dataSource.find !== 'function') {
|
|
172
|
-
throw new Error('DataSource required for object/api providers');
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (dataConfig?.provider === 'object') {
|
|
176
|
-
const objectName = dataConfig.object;
|
|
177
|
-
// Auto-inject $expand for lookup/master_detail fields
|
|
178
|
-
const expand = buildExpandFields(objectSchema?.fields);
|
|
179
|
-
const result = await dataSource.find(objectName, {
|
|
180
|
-
$filter: schema.filter,
|
|
181
|
-
$orderby: convertSortToQueryParams(schema.sort),
|
|
182
|
-
...(expand.length > 0 ? { $expand: expand } : {}),
|
|
183
|
-
});
|
|
184
|
-
let items: any[] = extractRecords(result);
|
|
185
|
-
setData(items);
|
|
186
|
-
} else if (dataConfig?.provider === 'api') {
|
|
187
|
-
console.warn('API provider not yet implemented for ObjectGantt');
|
|
188
|
-
setData([]);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
setLoading(false);
|
|
192
|
-
} catch (err) {
|
|
193
|
-
setError(err as Error);
|
|
194
|
-
setLoading(false);
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
|
|
198
|
-
fetchData();
|
|
199
|
-
}, [dataConfig, dataSource, hasInlineData, schema.filter, schema.sort, objectSchema]);
|
|
200
|
-
|
|
201
|
-
// Fetch object schema for field metadata
|
|
202
|
-
useEffect(() => {
|
|
203
|
-
const fetchObjectSchema = async () => {
|
|
204
|
-
try {
|
|
205
|
-
if (!dataSource) return;
|
|
206
|
-
|
|
207
|
-
const objectName = dataConfig?.provider === 'object'
|
|
208
|
-
? dataConfig.object
|
|
209
|
-
: schema.objectName;
|
|
210
|
-
|
|
211
|
-
if (!objectName) return;
|
|
212
|
-
|
|
213
|
-
const schemaData = await dataSource.getObjectSchema(objectName);
|
|
214
|
-
setObjectSchema(schemaData);
|
|
215
|
-
} catch (err) {
|
|
216
|
-
console.error('Failed to fetch object schema:', err);
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
if (!hasInlineData && dataSource) {
|
|
221
|
-
fetchObjectSchema();
|
|
222
|
-
}
|
|
223
|
-
}, [schema.objectName, dataSource, hasInlineData, dataConfig]);
|
|
224
|
-
|
|
225
|
-
// Transform data to gantt tasks
|
|
226
|
-
const tasks = useMemo(() => {
|
|
227
|
-
if (!ganttConfig || !data.length) {
|
|
228
|
-
return [];
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
const { startDateField, endDateField, titleField, progressField, dependenciesField, colorField } = ganttConfig;
|
|
232
|
-
|
|
233
|
-
return data.map((record, index) => {
|
|
234
|
-
const startDate = record[startDateField];
|
|
235
|
-
const endDate = record[endDateField];
|
|
236
|
-
const title = record[titleField] || 'Untitled Task';
|
|
237
|
-
const progress = progressField ? record[progressField] : 0;
|
|
238
|
-
const dependencies = dependenciesField ? record[dependenciesField] : [];
|
|
239
|
-
const color = colorField ? record[colorField] : undefined;
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
id: record.id || record._id || `task-${index}`,
|
|
243
|
-
title,
|
|
244
|
-
start: startDate ? new Date(startDate) : new Date(),
|
|
245
|
-
end: endDate ? new Date(endDate) : new Date(),
|
|
246
|
-
progress: Math.min(100, Math.max(0, progress || 0)), // Clamp between 0-100
|
|
247
|
-
dependencies: Array.isArray(dependencies) ? dependencies : [],
|
|
248
|
-
color,
|
|
249
|
-
data: record,
|
|
250
|
-
};
|
|
251
|
-
}).filter(task => !isNaN(task.start.getTime()) && !isNaN(task.end.getTime()));
|
|
252
|
-
}, [data, ganttConfig]);
|
|
253
|
-
|
|
254
|
-
const navigation = useNavigationOverlay({
|
|
255
|
-
navigation: (schema as any).navigation,
|
|
256
|
-
objectName: schema.objectName,
|
|
257
|
-
onRowClick,
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
if (loading) {
|
|
261
|
-
return (
|
|
262
|
-
<div className={className}>
|
|
263
|
-
<div className="flex items-center justify-center h-96">
|
|
264
|
-
<div className="text-muted-foreground">Loading Gantt chart...</div>
|
|
265
|
-
</div>
|
|
266
|
-
</div>
|
|
267
|
-
);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if (error) {
|
|
271
|
-
return (
|
|
272
|
-
<div className={className}>
|
|
273
|
-
<div className="flex items-center justify-center h-96">
|
|
274
|
-
<div className="text-destructive">Error: {error.message}</div>
|
|
275
|
-
</div>
|
|
276
|
-
</div>
|
|
277
|
-
);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (!ganttConfig) {
|
|
281
|
-
return (
|
|
282
|
-
<div className={className}>
|
|
283
|
-
<div className="flex items-center justify-center h-96">
|
|
284
|
-
<div className="text-muted-foreground">
|
|
285
|
-
Gantt configuration required. Please specify startDateField, endDateField, and titleField.
|
|
286
|
-
</div>
|
|
287
|
-
</div>
|
|
288
|
-
</div>
|
|
289
|
-
);
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
return (
|
|
293
|
-
<div className={className}>
|
|
294
|
-
<div className="h-[calc(100vh-200px)] min-h-[600px]">
|
|
295
|
-
<GanttView
|
|
296
|
-
tasks={tasks}
|
|
297
|
-
onTaskClick={(task) => {
|
|
298
|
-
navigation.handleClick(task.data);
|
|
299
|
-
onTaskClick?.(task.data);
|
|
300
|
-
}}
|
|
301
|
-
onAddClick={() => {
|
|
302
|
-
// Placeholder for add action
|
|
303
|
-
}}
|
|
304
|
-
/>
|
|
305
|
-
</div>
|
|
306
|
-
{navigation.isOverlay && (
|
|
307
|
-
<NavigationOverlay {...navigation} title="Task Details">
|
|
308
|
-
{(record) => (
|
|
309
|
-
<div className="space-y-3">
|
|
310
|
-
{Object.entries(record).map(([key, value]) => (
|
|
311
|
-
<div key={key} className="flex flex-col">
|
|
312
|
-
<span className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
|
|
313
|
-
{key.replace(/_/g, ' ')}
|
|
314
|
-
</span>
|
|
315
|
-
<span className="text-sm">{String(value ?? '—')}</span>
|
|
316
|
-
</div>
|
|
317
|
-
))}
|
|
318
|
-
</div>
|
|
319
|
-
)}
|
|
320
|
-
</NavigationOverlay>
|
|
321
|
-
)}
|
|
322
|
-
</div>
|
|
323
|
-
);
|
|
324
|
-
};
|
|
@@ -1,69 +0,0 @@
|
|
|
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 React from 'react';
|
|
10
|
-
import { describe, it, expect } from 'vitest';
|
|
11
|
-
import { render, screen } from '@testing-library/react';
|
|
12
|
-
import '@testing-library/jest-dom';
|
|
13
|
-
import { GanttView, type GanttTask } from '../GanttView';
|
|
14
|
-
|
|
15
|
-
const mockTasks: GanttTask[] = [
|
|
16
|
-
{
|
|
17
|
-
id: '1',
|
|
18
|
-
title: 'Design Phase',
|
|
19
|
-
start: new Date('2024-01-15'),
|
|
20
|
-
end: new Date('2024-02-15'),
|
|
21
|
-
progress: 75,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
id: '2',
|
|
25
|
-
title: 'Development',
|
|
26
|
-
start: new Date('2024-02-01'),
|
|
27
|
-
end: new Date('2024-03-15'),
|
|
28
|
-
progress: 30,
|
|
29
|
-
},
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
describe('GanttView accessibility', () => {
|
|
33
|
-
it('renders aria-label on navigation buttons', () => {
|
|
34
|
-
render(<GanttView tasks={mockTasks} />);
|
|
35
|
-
expect(screen.getByLabelText('Previous period')).toBeInTheDocument();
|
|
36
|
-
expect(screen.getByLabelText('Next period')).toBeInTheDocument();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('renders aria-label on zoom buttons', () => {
|
|
40
|
-
render(<GanttView tasks={mockTasks} />);
|
|
41
|
-
expect(screen.getByLabelText('Zoom out')).toBeInTheDocument();
|
|
42
|
-
expect(screen.getByLabelText('Zoom in')).toBeInTheDocument();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('renders aria-label on create button', () => {
|
|
46
|
-
render(<GanttView tasks={mockTasks} />);
|
|
47
|
-
expect(screen.getByLabelText('Create new task')).toBeInTheDocument();
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
describe('GanttView mobile date badge', () => {
|
|
52
|
-
it('renders date range text below task title', () => {
|
|
53
|
-
render(<GanttView tasks={mockTasks} />);
|
|
54
|
-
// The mobile date badge shows start → end dates
|
|
55
|
-
const startDate = mockTasks[0].start.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' });
|
|
56
|
-
const endDate = mockTasks[0].end.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' });
|
|
57
|
-
const dateText = `${startDate} → ${endDate}`;
|
|
58
|
-
expect(screen.getByText(dateText)).toBeInTheDocument();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('renders mobile date badge with sm:hidden class', () => {
|
|
62
|
-
render(<GanttView tasks={mockTasks} />);
|
|
63
|
-
const startDate = mockTasks[0].start.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' });
|
|
64
|
-
const endDate = mockTasks[0].end.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' });
|
|
65
|
-
const dateText = `${startDate} → ${endDate}`;
|
|
66
|
-
const badge = screen.getByText(dateText);
|
|
67
|
-
expect(badge.className).toContain('sm:hidden');
|
|
68
|
-
});
|
|
69
|
-
});
|
package/src/index.test.tsx
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
-
import { render, screen } from '@testing-library/react';
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import { ObjectGanttRenderer } from './index';
|
|
5
|
-
|
|
6
|
-
// Mock dependencies
|
|
7
|
-
vi.mock('@object-ui/react', () => ({
|
|
8
|
-
useSchemaContext: vi.fn(() => ({ dataSource: { type: 'mock-datasource' } })),
|
|
9
|
-
}));
|
|
10
|
-
|
|
11
|
-
vi.mock('./ObjectGantt', () => ({
|
|
12
|
-
ObjectGantt: ({ dataSource }: any) => (
|
|
13
|
-
<div data-testid="gantt-mock">
|
|
14
|
-
{dataSource ? `DataSource: ${dataSource.type}` : 'No DataSource'}
|
|
15
|
-
</div>
|
|
16
|
-
)
|
|
17
|
-
}));
|
|
18
|
-
|
|
19
|
-
describe('Plugin Gantt Registration', () => {
|
|
20
|
-
it('renderer passes dataSource from context', () => {
|
|
21
|
-
// Note: We test the renderer directly to avoid singleton issues with ComponentRegistry in tests
|
|
22
|
-
render(<ObjectGanttRenderer schema={{}} />);
|
|
23
|
-
expect(screen.getByTestId('gantt-mock')).toHaveTextContent('DataSource: mock-datasource');
|
|
24
|
-
});
|
|
25
|
-
});
|
package/src/index.tsx
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
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 React from 'react';
|
|
10
|
-
import { ComponentRegistry } from '@object-ui/core';
|
|
11
|
-
import { useSchemaContext } from '@object-ui/react';
|
|
12
|
-
import { ObjectGantt } from './ObjectGantt';
|
|
13
|
-
import type { ObjectGanttProps } from './ObjectGantt';
|
|
14
|
-
|
|
15
|
-
export { ObjectGantt };
|
|
16
|
-
export type { ObjectGanttProps };
|
|
17
|
-
|
|
18
|
-
export { GanttView } from './GanttView';
|
|
19
|
-
export type { GanttViewProps, GanttTask, GanttViewMode } from './GanttView';
|
|
20
|
-
|
|
21
|
-
// Register component
|
|
22
|
-
export const ObjectGanttRenderer: React.FC<{ schema: any }> = ({ schema }) => {
|
|
23
|
-
const { dataSource } = useSchemaContext() || {};
|
|
24
|
-
return <ObjectGantt schema={schema} dataSource={dataSource} />;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
ComponentRegistry.register('object-gantt', ObjectGanttRenderer, {
|
|
28
|
-
namespace: 'plugin-gantt',
|
|
29
|
-
label: 'Object Gantt',
|
|
30
|
-
category: 'view',
|
|
31
|
-
inputs: [
|
|
32
|
-
{ name: 'objectName', type: 'string', label: 'Object Name', required: true },
|
|
33
|
-
{ name: 'gantt', type: 'object', label: 'Gantt Config', description: 'startDateField, endDateField, titleField, progressField, percentageField, colorField, dependenciesField' },
|
|
34
|
-
],
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
ComponentRegistry.register('gantt', ObjectGanttRenderer, {
|
|
38
|
-
namespace: 'view',
|
|
39
|
-
label: 'Gantt View',
|
|
40
|
-
category: 'view',
|
|
41
|
-
inputs: [
|
|
42
|
-
{ name: 'objectName', type: 'string', label: 'Object Name', required: true },
|
|
43
|
-
{ name: 'gantt', type: 'object', label: 'Gantt Config', description: 'startDateField, endDateField, titleField, progressField, percentageField, colorField, dependenciesField' },
|
|
44
|
-
],
|
|
45
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "../../tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"outDir": "dist",
|
|
5
|
-
"jsx": "react-jsx",
|
|
6
|
-
"baseUrl": ".",
|
|
7
|
-
"paths": {
|
|
8
|
-
"@/*": ["src/*"]
|
|
9
|
-
},
|
|
10
|
-
"noEmit": false,
|
|
11
|
-
"declaration": true,
|
|
12
|
-
"composite": true,
|
|
13
|
-
"declarationMap": true,
|
|
14
|
-
"skipLibCheck": true
|
|
15
|
-
},
|
|
16
|
-
"include": ["src"],
|
|
17
|
-
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx", "**/*.stories.tsx"]
|
|
18
|
-
}
|
package/vite.config.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
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 { defineConfig } from 'vite';
|
|
10
|
-
import react from '@vitejs/plugin-react';
|
|
11
|
-
import dts from 'vite-plugin-dts';
|
|
12
|
-
import { resolve } from 'path';
|
|
13
|
-
|
|
14
|
-
export default defineConfig({
|
|
15
|
-
plugins: [
|
|
16
|
-
react(),
|
|
17
|
-
dts({
|
|
18
|
-
insertTypesEntry: true,
|
|
19
|
-
compilerOptions: { rootDir: resolve(__dirname, '../..') },
|
|
20
|
-
include: ['src'],
|
|
21
|
-
exclude: ['**/*.test.ts', '**/*.test.tsx', 'node_modules'],
|
|
22
|
-
skipDiagnostics: true,
|
|
23
|
-
}),
|
|
24
|
-
],
|
|
25
|
-
resolve: {
|
|
26
|
-
alias: {
|
|
27
|
-
'@': resolve(__dirname, './src'),
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
build: {
|
|
31
|
-
lib: {
|
|
32
|
-
entry: resolve(__dirname, 'src/index.tsx'),
|
|
33
|
-
name: 'ObjectUIPluginGantt',
|
|
34
|
-
fileName: 'index',
|
|
35
|
-
},
|
|
36
|
-
rollupOptions: {
|
|
37
|
-
external: ['react', 'react-dom', '@object-ui/components', '@object-ui/core', '@object-ui/react', '@object-ui/types', 'lucide-react'],
|
|
38
|
-
output: {
|
|
39
|
-
globals: {
|
|
40
|
-
react: 'React',
|
|
41
|
-
'react-dom': 'ReactDOM',
|
|
42
|
-
'@object-ui/components': 'ObjectUIComponents',
|
|
43
|
-
'@object-ui/core': 'ObjectUICore',
|
|
44
|
-
'@object-ui/react': 'ObjectUIReact',
|
|
45
|
-
'@object-ui/types': 'ObjectUITypes',
|
|
46
|
-
'lucide-react': 'LucideReact',
|
|
47
|
-
},
|
|
48
|
-
},
|
|
49
|
-
},
|
|
50
|
-
},
|
|
51
|
-
test: {
|
|
52
|
-
passWithNoTests: true,
|
|
53
|
-
},
|
|
54
|
-
});
|
package/vitest.config.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/// <reference types="vitest" />
|
|
2
|
-
import { defineConfig } from 'vite';
|
|
3
|
-
import react from '@vitejs/plugin-react';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
plugins: [react()],
|
|
8
|
-
test: {
|
|
9
|
-
environment: 'happy-dom',
|
|
10
|
-
globals: true,
|
|
11
|
-
setupFiles: ['./vitest.setup.ts'],
|
|
12
|
-
},
|
|
13
|
-
});
|
package/vitest.setup.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import '@testing-library/jest-dom';
|