@object-ui/plugin-gantt 0.3.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/LICENSE +21 -0
- package/README.md +260 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +504 -0
- package/dist/index.umd.cjs +6 -0
- package/dist/src/ObjectGantt.d.ts +12 -0
- package/dist/src/ObjectGantt.d.ts.map +1 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.d.ts.map +1 -0
- package/package.json +53 -0
- package/src/ObjectGantt.tsx +408 -0
- package/src/index.tsx +29 -0
- package/tsconfig.json +18 -0
- package/vite.config.ts +50 -0
|
@@ -0,0 +1,408 @@
|
|
|
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
|
+
|
|
28
|
+
export interface ObjectGanttProps {
|
|
29
|
+
schema: ObjectGridSchema;
|
|
30
|
+
dataSource?: DataSource;
|
|
31
|
+
className?: string;
|
|
32
|
+
onTaskClick?: (record: any) => void;
|
|
33
|
+
onEdit?: (record: any) => void;
|
|
34
|
+
onDelete?: (record: any) => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Helper to get data configuration from schema
|
|
39
|
+
*/
|
|
40
|
+
function getDataConfig(schema: ObjectGridSchema): ViewData | null {
|
|
41
|
+
if (schema.data) {
|
|
42
|
+
return schema.data;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (schema.staticData) {
|
|
46
|
+
return {
|
|
47
|
+
provider: 'value',
|
|
48
|
+
items: schema.staticData,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (schema.objectName) {
|
|
53
|
+
return {
|
|
54
|
+
provider: 'object',
|
|
55
|
+
object: schema.objectName,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Helper to convert sort config to QueryParams format
|
|
64
|
+
*/
|
|
65
|
+
function convertSortToQueryParams(sort: string | any[] | undefined): Record<string, 'asc' | 'desc'> | undefined {
|
|
66
|
+
if (!sort) return undefined;
|
|
67
|
+
|
|
68
|
+
// If it's a string like "name desc"
|
|
69
|
+
if (typeof sort === 'string') {
|
|
70
|
+
const parts = sort.split(' ');
|
|
71
|
+
const field = parts[0];
|
|
72
|
+
const order = (parts[1]?.toLowerCase() === 'desc' ? 'desc' : 'asc') as 'asc' | 'desc';
|
|
73
|
+
return { [field]: order };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// If it's an array of SortConfig objects
|
|
77
|
+
if (Array.isArray(sort)) {
|
|
78
|
+
return sort.reduce((acc, item) => {
|
|
79
|
+
if (item.field && item.order) {
|
|
80
|
+
acc[item.field] = item.order;
|
|
81
|
+
}
|
|
82
|
+
return acc;
|
|
83
|
+
}, {} as Record<string, 'asc' | 'desc'>);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Helper to get gantt configuration from schema
|
|
91
|
+
*/
|
|
92
|
+
function getGanttConfig(schema: ObjectGridSchema): GanttConfig | null {
|
|
93
|
+
// Check if schema has gantt configuration
|
|
94
|
+
if (schema.filter && typeof schema.filter === 'object' && 'gantt' in schema.filter) {
|
|
95
|
+
return (schema.filter as any).gantt as GanttConfig;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// For backward compatibility, check if schema has gantt config at root
|
|
99
|
+
if ((schema as any).gantt) {
|
|
100
|
+
return (schema as any).gantt as GanttConfig;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const ObjectGantt: React.FC<ObjectGanttProps> = ({
|
|
107
|
+
schema,
|
|
108
|
+
dataSource,
|
|
109
|
+
className,
|
|
110
|
+
onTaskClick,
|
|
111
|
+
}) => {
|
|
112
|
+
const [data, setData] = useState<any[]>([]);
|
|
113
|
+
const [loading, setLoading] = useState(true);
|
|
114
|
+
const [error, setError] = useState<Error | null>(null);
|
|
115
|
+
const [objectSchema, setObjectSchema] = useState<any>(null);
|
|
116
|
+
|
|
117
|
+
const dataConfig = getDataConfig(schema);
|
|
118
|
+
const ganttConfig = getGanttConfig(schema);
|
|
119
|
+
const hasInlineData = dataConfig?.provider === 'value';
|
|
120
|
+
|
|
121
|
+
// Fetch data based on provider
|
|
122
|
+
useEffect(() => {
|
|
123
|
+
const fetchData = async () => {
|
|
124
|
+
try {
|
|
125
|
+
setLoading(true);
|
|
126
|
+
|
|
127
|
+
if (hasInlineData && dataConfig?.provider === 'value') {
|
|
128
|
+
setData(dataConfig.items as any[]);
|
|
129
|
+
setLoading(false);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!dataSource) {
|
|
134
|
+
throw new Error('DataSource required for object/api providers');
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (dataConfig?.provider === 'object') {
|
|
138
|
+
const objectName = dataConfig.object;
|
|
139
|
+
const result = await dataSource.find(objectName, {
|
|
140
|
+
$filter: schema.filter,
|
|
141
|
+
$orderby: convertSortToQueryParams(schema.sort),
|
|
142
|
+
});
|
|
143
|
+
setData(result?.data || []);
|
|
144
|
+
} else if (dataConfig?.provider === 'api') {
|
|
145
|
+
console.warn('API provider not yet implemented for ObjectGantt');
|
|
146
|
+
setData([]);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
setLoading(false);
|
|
150
|
+
} catch (err) {
|
|
151
|
+
setError(err as Error);
|
|
152
|
+
setLoading(false);
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
fetchData();
|
|
157
|
+
}, [dataConfig, dataSource, hasInlineData, schema.filter, schema.sort]);
|
|
158
|
+
|
|
159
|
+
// Fetch object schema for field metadata
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
const fetchObjectSchema = async () => {
|
|
162
|
+
try {
|
|
163
|
+
if (!dataSource) return;
|
|
164
|
+
|
|
165
|
+
const objectName = dataConfig?.provider === 'object'
|
|
166
|
+
? dataConfig.object
|
|
167
|
+
: schema.objectName;
|
|
168
|
+
|
|
169
|
+
if (!objectName) return;
|
|
170
|
+
|
|
171
|
+
const schemaData = await dataSource.getObjectSchema(objectName);
|
|
172
|
+
setObjectSchema(schemaData);
|
|
173
|
+
} catch (err) {
|
|
174
|
+
console.error('Failed to fetch object schema:', err);
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
if (!hasInlineData && dataSource) {
|
|
179
|
+
fetchObjectSchema();
|
|
180
|
+
}
|
|
181
|
+
}, [schema.objectName, dataSource, hasInlineData, dataConfig]);
|
|
182
|
+
|
|
183
|
+
// Transform data to gantt tasks
|
|
184
|
+
const tasks = useMemo(() => {
|
|
185
|
+
if (!ganttConfig || !data.length) {
|
|
186
|
+
return [];
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const { startDateField, endDateField, titleField, progressField, dependenciesField } = ganttConfig;
|
|
190
|
+
|
|
191
|
+
return data.map((record, index) => {
|
|
192
|
+
const startDate = record[startDateField];
|
|
193
|
+
const endDate = record[endDateField];
|
|
194
|
+
const title = record[titleField] || 'Untitled Task';
|
|
195
|
+
const progress = progressField ? record[progressField] : 0;
|
|
196
|
+
const dependencies = dependenciesField ? record[dependenciesField] : [];
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
id: record.id || record._id || `task-${index}`,
|
|
200
|
+
title,
|
|
201
|
+
start: startDate ? new Date(startDate) : new Date(),
|
|
202
|
+
end: endDate ? new Date(endDate) : new Date(),
|
|
203
|
+
progress: Math.min(100, Math.max(0, progress || 0)), // Clamp between 0-100
|
|
204
|
+
dependencies: Array.isArray(dependencies) ? dependencies : [],
|
|
205
|
+
data: record,
|
|
206
|
+
};
|
|
207
|
+
}).filter(task => !isNaN(task.start.getTime()) && !isNaN(task.end.getTime()));
|
|
208
|
+
}, [data, ganttConfig]);
|
|
209
|
+
|
|
210
|
+
// Calculate timeline range
|
|
211
|
+
const timelineRange = useMemo(() => {
|
|
212
|
+
if (!tasks.length) {
|
|
213
|
+
const now = new Date();
|
|
214
|
+
return {
|
|
215
|
+
start: new Date(now.getFullYear(), now.getMonth(), 1),
|
|
216
|
+
end: new Date(now.getFullYear(), now.getMonth() + 3, 0),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const allDates = tasks.flatMap(task => [task.start, task.end]);
|
|
221
|
+
const minDate = new Date(Math.min(...allDates.map(d => d.getTime())));
|
|
222
|
+
const maxDate = new Date(Math.max(...allDates.map(d => d.getTime())));
|
|
223
|
+
|
|
224
|
+
// Add some padding
|
|
225
|
+
minDate.setDate(minDate.getDate() - 7);
|
|
226
|
+
maxDate.setDate(maxDate.getDate() + 7);
|
|
227
|
+
|
|
228
|
+
return { start: minDate, end: maxDate };
|
|
229
|
+
}, [tasks]);
|
|
230
|
+
|
|
231
|
+
// Generate month headers
|
|
232
|
+
const months = useMemo(() => {
|
|
233
|
+
const result = [];
|
|
234
|
+
const current = new Date(timelineRange.start);
|
|
235
|
+
current.setDate(1);
|
|
236
|
+
|
|
237
|
+
while (current <= timelineRange.end) {
|
|
238
|
+
result.push(new Date(current));
|
|
239
|
+
current.setMonth(current.getMonth() + 1);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return result;
|
|
243
|
+
}, [timelineRange]);
|
|
244
|
+
|
|
245
|
+
// Calculate task bar position and width
|
|
246
|
+
const getTaskPosition = (task: any) => {
|
|
247
|
+
const totalDays = (timelineRange.end.getTime() - timelineRange.start.getTime()) / (1000 * 60 * 60 * 24);
|
|
248
|
+
const taskStart = (task.start.getTime() - timelineRange.start.getTime()) / (1000 * 60 * 60 * 24);
|
|
249
|
+
const taskDuration = (task.end.getTime() - task.start.getTime()) / (1000 * 60 * 60 * 24);
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
left: `${(taskStart / totalDays) * 100}%`,
|
|
253
|
+
width: `${(taskDuration / totalDays) * 100}%`,
|
|
254
|
+
};
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
if (loading) {
|
|
258
|
+
return (
|
|
259
|
+
<div className={className}>
|
|
260
|
+
<div className="flex items-center justify-center h-96">
|
|
261
|
+
<div className="text-muted-foreground">Loading Gantt chart...</div>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (error) {
|
|
268
|
+
return (
|
|
269
|
+
<div className={className}>
|
|
270
|
+
<div className="flex items-center justify-center h-96">
|
|
271
|
+
<div className="text-destructive">Error: {error.message}</div>
|
|
272
|
+
</div>
|
|
273
|
+
</div>
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (!ganttConfig) {
|
|
278
|
+
return (
|
|
279
|
+
<div className={className}>
|
|
280
|
+
<div className="flex items-center justify-center h-96">
|
|
281
|
+
<div className="text-muted-foreground">
|
|
282
|
+
Gantt configuration required. Please specify startDateField, endDateField, and titleField.
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
|
290
|
+
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
<div className={className}>
|
|
294
|
+
<div className="border rounded-lg bg-background overflow-hidden">
|
|
295
|
+
<div className="flex">
|
|
296
|
+
{/* Task List */}
|
|
297
|
+
<div className="w-64 border-r flex-shrink-0">
|
|
298
|
+
<div className="border-b p-3 font-semibold bg-muted">Tasks</div>
|
|
299
|
+
<div>
|
|
300
|
+
{tasks.map(task => (
|
|
301
|
+
<div
|
|
302
|
+
key={task.id}
|
|
303
|
+
className="border-b p-3 hover:bg-muted/50 cursor-pointer"
|
|
304
|
+
onClick={() => onTaskClick?.(task.data)}
|
|
305
|
+
>
|
|
306
|
+
<div className="font-medium text-sm truncate">{task.title}</div>
|
|
307
|
+
<div className="text-xs text-muted-foreground mt-1">
|
|
308
|
+
{task.start.toLocaleDateString()} - {task.end.toLocaleDateString()}
|
|
309
|
+
</div>
|
|
310
|
+
{task.progress > 0 && (
|
|
311
|
+
<div className="mt-2">
|
|
312
|
+
<div className="flex justify-between text-xs mb-1">
|
|
313
|
+
<span>Progress</span>
|
|
314
|
+
<span>{task.progress}%</span>
|
|
315
|
+
</div>
|
|
316
|
+
<div className="h-1.5 bg-muted rounded-full overflow-hidden">
|
|
317
|
+
<div
|
|
318
|
+
className="h-full bg-primary"
|
|
319
|
+
style={{ width: `${task.progress}%` }}
|
|
320
|
+
/>
|
|
321
|
+
</div>
|
|
322
|
+
</div>
|
|
323
|
+
)}
|
|
324
|
+
</div>
|
|
325
|
+
))}
|
|
326
|
+
</div>
|
|
327
|
+
</div>
|
|
328
|
+
|
|
329
|
+
{/* Timeline */}
|
|
330
|
+
<div className="flex-1 overflow-x-auto">
|
|
331
|
+
{/* Month Headers */}
|
|
332
|
+
<div className="border-b bg-muted sticky top-0 z-10">
|
|
333
|
+
<div className="flex">
|
|
334
|
+
{months.map((month, index) => {
|
|
335
|
+
const daysInMonth = new Date(
|
|
336
|
+
month.getFullYear(),
|
|
337
|
+
month.getMonth() + 1,
|
|
338
|
+
0
|
|
339
|
+
).getDate();
|
|
340
|
+
|
|
341
|
+
return (
|
|
342
|
+
<div
|
|
343
|
+
key={index}
|
|
344
|
+
className="border-r p-3 text-center font-semibold text-sm"
|
|
345
|
+
style={{ minWidth: `${daysInMonth * 20}px` }}
|
|
346
|
+
>
|
|
347
|
+
{monthNames[month.getMonth()]} {month.getFullYear()}
|
|
348
|
+
</div>
|
|
349
|
+
);
|
|
350
|
+
})}
|
|
351
|
+
</div>
|
|
352
|
+
</div>
|
|
353
|
+
|
|
354
|
+
{/* Task Bars */}
|
|
355
|
+
<div className="relative">
|
|
356
|
+
{tasks.map((task) => {
|
|
357
|
+
const position = getTaskPosition(task);
|
|
358
|
+
|
|
359
|
+
return (
|
|
360
|
+
<div
|
|
361
|
+
key={task.id}
|
|
362
|
+
className="border-b relative"
|
|
363
|
+
style={{ height: '60px' }}
|
|
364
|
+
>
|
|
365
|
+
{/* Month grid lines */}
|
|
366
|
+
<div className="absolute inset-0 flex pointer-events-none">
|
|
367
|
+
{months.map((month, idx) => {
|
|
368
|
+
const daysInMonth = new Date(
|
|
369
|
+
month.getFullYear(),
|
|
370
|
+
month.getMonth() + 1,
|
|
371
|
+
0
|
|
372
|
+
).getDate();
|
|
373
|
+
|
|
374
|
+
return (
|
|
375
|
+
<div
|
|
376
|
+
key={idx}
|
|
377
|
+
className="border-r"
|
|
378
|
+
style={{ minWidth: `${daysInMonth * 20}px` }}
|
|
379
|
+
/>
|
|
380
|
+
);
|
|
381
|
+
})}
|
|
382
|
+
</div>
|
|
383
|
+
|
|
384
|
+
{/* Task Bar */}
|
|
385
|
+
<div
|
|
386
|
+
className="absolute top-1/2 -translate-y-1/2 h-8 bg-primary/80 rounded cursor-pointer hover:bg-primary transition-colors flex items-center px-2 text-white text-xs font-medium overflow-hidden"
|
|
387
|
+
style={position}
|
|
388
|
+
onClick={() => onTaskClick?.(task.data)}
|
|
389
|
+
>
|
|
390
|
+
{/* Progress overlay */}
|
|
391
|
+
{task.progress > 0 && (
|
|
392
|
+
<div
|
|
393
|
+
className="absolute inset-0 bg-primary-foreground/20"
|
|
394
|
+
style={{ width: `${task.progress}%` }}
|
|
395
|
+
/>
|
|
396
|
+
)}
|
|
397
|
+
<span className="relative z-10 truncate">{task.title}</span>
|
|
398
|
+
</div>
|
|
399
|
+
</div>
|
|
400
|
+
);
|
|
401
|
+
})}
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
</div>
|
|
405
|
+
</div>
|
|
406
|
+
</div>
|
|
407
|
+
);
|
|
408
|
+
};
|
package/src/index.tsx
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
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 { ObjectGantt } from './ObjectGantt';
|
|
12
|
+
import type { ObjectGanttProps } from './ObjectGantt';
|
|
13
|
+
|
|
14
|
+
export { ObjectGantt };
|
|
15
|
+
export type { ObjectGanttProps };
|
|
16
|
+
|
|
17
|
+
// Register component
|
|
18
|
+
const ObjectGanttRenderer: React.FC<{ schema: any }> = ({ schema }) => {
|
|
19
|
+
return <ObjectGantt schema={schema} dataSource={null as any} />;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
ComponentRegistry.register('object-gantt', ObjectGanttRenderer, {
|
|
23
|
+
label: 'Object Gantt',
|
|
24
|
+
category: 'plugin',
|
|
25
|
+
inputs: [
|
|
26
|
+
{ name: 'objectName', type: 'string', label: 'Object Name', required: true },
|
|
27
|
+
{ name: 'gantt', type: 'object', label: 'Gantt Config', description: 'startDateField, endDateField, titleField, progressField, dependenciesField' },
|
|
28
|
+
],
|
|
29
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
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"]
|
|
18
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
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
|
+
include: ['src'],
|
|
20
|
+
exclude: ['**/*.test.ts', '**/*.test.tsx', 'node_modules'],
|
|
21
|
+
skipDiagnostics: true,
|
|
22
|
+
}),
|
|
23
|
+
],
|
|
24
|
+
resolve: {
|
|
25
|
+
alias: {
|
|
26
|
+
'@': resolve(__dirname, './src'),
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
build: {
|
|
30
|
+
lib: {
|
|
31
|
+
entry: resolve(__dirname, 'src/index.tsx'),
|
|
32
|
+
name: 'ObjectUIPluginGantt',
|
|
33
|
+
fileName: 'index',
|
|
34
|
+
},
|
|
35
|
+
rollupOptions: {
|
|
36
|
+
external: ['react', 'react-dom', '@object-ui/components', '@object-ui/core', '@object-ui/react', '@object-ui/types', 'lucide-react'],
|
|
37
|
+
output: {
|
|
38
|
+
globals: {
|
|
39
|
+
react: 'React',
|
|
40
|
+
'react-dom': 'ReactDOM',
|
|
41
|
+
'@object-ui/components': 'ObjectUIComponents',
|
|
42
|
+
'@object-ui/core': 'ObjectUICore',
|
|
43
|
+
'@object-ui/react': 'ObjectUIReact',
|
|
44
|
+
'@object-ui/types': 'ObjectUITypes',
|
|
45
|
+
'lucide-react': 'LucideReact',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|