@object-ui/plugin-gantt 2.0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"GanttView.d.ts","sourceRoot":"","sources":["../../src/GanttView.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA6BH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;IACX,GAAG,EAAE,IAAI,CAAA;IACT,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,GAAG,CAAA;IACV,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;CACnC;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,SAAS,CAAC,EAAE,IAAI,CAAA;IAChB,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,QAAkB,EAClB,SAAS,EACT,OAAO,EACP,WAAW,EACX,YAAY,EACZ,UAAU,EACV,SAAS,EACV,EAAE,cAAc,2CAwQhB"}
1
+ {"version":3,"file":"GanttView.d.ts","sourceRoot":"","sources":["../../src/GanttView.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAmCH,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,IAAI,CAAA;IACX,GAAG,EAAE,IAAI,CAAA;IACT,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,GAAG,CAAA;IACV,YAAY,CAAC,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAA;CACnC;AAED,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,EAAE,CAAA;IAClB,QAAQ,CAAC,EAAE,aAAa,CAAA;IACxB,SAAS,CAAC,EAAE,IAAI,CAAA;IAChB,OAAO,CAAC,EAAE,IAAI,CAAA;IACd,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;IACvC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAA;IAC5C,UAAU,CAAC,EAAE,MAAM,IAAI,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,QAAkB,EAClB,SAAS,EACT,OAAO,EACP,WAAW,EACX,YAAY,EACZ,UAAU,EACV,SAAS,EACV,EAAE,cAAc,2CAqRhB"}
@@ -5,6 +5,7 @@ export interface ObjectGanttProps {
5
5
  dataSource?: DataSource;
6
6
  className?: string;
7
7
  onTaskClick?: (record: any) => void;
8
+ onRowClick?: (record: any) => void;
8
9
  onEdit?: (record: any) => void;
9
10
  onDelete?: (record: any) => void;
10
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ObjectGantt.d.ts","sourceRoot":"","sources":["../../src/ObjectGantt.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAyB,MAAM,kBAAkB,CAAC;AAI5F,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAClC;AAyFD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA+KlD,CAAC"}
1
+ {"version":3,"file":"ObjectGantt.d.ts","sourceRoot":"","sources":["../../src/ObjectGantt.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAyB,MAAM,kBAAkB,CAAC;AAM5F,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,IAAI,CAAC;CAClC;AAyFD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAyMlD,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { StoryObj } from '@storybook/react';
2
+ declare const meta: {
3
+ title: string;
4
+ component: import('react').ForwardRefExoticComponent<Omit<{
5
+ schema: import('@object-ui/core').SchemaNode;
6
+ } & Record<string, any>, "ref"> & import('react').RefAttributes<any>>;
7
+ parameters: {
8
+ layout: string;
9
+ };
10
+ tags: string[];
11
+ argTypes: {
12
+ schema: {
13
+ table: {
14
+ disable: true;
15
+ };
16
+ };
17
+ };
18
+ };
19
+ export default meta;
20
+ type Story = StoryObj<typeof meta>;
21
+ export declare const Default: Story;
22
+ export declare const SimpleTimeline: Story;
23
+ //# sourceMappingURL=ObjectGantt.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObjectGantt.stories.d.ts","sourceRoot":"","sources":["../../src/ObjectGantt.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAKvD,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;CAUW,CAAC;AAEtB,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAUnC,eAAO,MAAM,OAAO,EAAE,KA+DrB,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAkB5B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@object-ui/plugin-gantt",
3
- "version": "2.0.0",
3
+ "version": "3.0.0",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Gantt chart plugin for Object UI",
@@ -24,22 +24,22 @@
24
24
  }
25
25
  },
26
26
  "dependencies": {
27
- "@objectstack/spec": "^2.0.7",
27
+ "@objectstack/spec": "^3.0.2",
28
28
  "lucide-react": "^0.563.0",
29
- "@object-ui/components": "2.0.0",
30
- "@object-ui/core": "2.0.0",
31
- "@object-ui/fields": "2.0.0",
32
- "@object-ui/react": "2.0.0",
33
- "@object-ui/types": "2.0.0"
29
+ "@object-ui/components": "3.0.0",
30
+ "@object-ui/core": "3.0.0",
31
+ "@object-ui/fields": "3.0.0",
32
+ "@object-ui/react": "3.0.0",
33
+ "@object-ui/types": "3.0.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "react": "^18.0.0 || ^19.0.0",
37
37
  "react-dom": "^18.0.0 || ^19.0.0"
38
38
  },
39
39
  "devDependencies": {
40
- "@types/react": "^19.2.13",
41
- "@types/react-dom": "^19.2.3",
42
- "@vitejs/plugin-react": "^5.1.3",
40
+ "@types/react": "19.2.13",
41
+ "@types/react-dom": "19.2.3",
42
+ "@vitejs/plugin-react": "^5.1.4",
43
43
  "typescript": "^5.9.3",
44
44
  "vite": "^7.3.1",
45
45
  "vite-plugin-dts": "^4.5.4"
package/src/GanttView.tsx CHANGED
@@ -30,9 +30,15 @@ import {
30
30
  } from "@object-ui/components"
31
31
 
32
32
  const HEADER_HEIGHT = 50;
33
- const ROW_HEIGHT = 40;
34
33
  const COLUMN_WIDTH = 100; // Time column width
35
34
 
35
+ function getResponsiveColumnWidth() {
36
+ const w = typeof window !== 'undefined' ? window.innerWidth : 1024;
37
+ if (w < 640) return 35;
38
+ if (w < 1024) return 50;
39
+ return 60;
40
+ }
41
+
36
42
  export interface GanttTask {
37
43
  id: string | number
38
44
  title: string
@@ -68,7 +74,19 @@ export function GanttView({
68
74
  className
69
75
  }: GanttViewProps) {
70
76
  const [currentDate, setCurrentDate] = React.useState(new Date());
71
- const [columnWidth, setColumnWidth] = React.useState(60);
77
+ const [rowHeight, setRowHeight] = React.useState(
78
+ typeof window !== 'undefined' && window.innerWidth < 640 ? 32 : 40
79
+ );
80
+ const [columnWidth, setColumnWidth] = React.useState(getResponsiveColumnWidth());
81
+
82
+ React.useEffect(() => {
83
+ const handleResize = () => {
84
+ setRowHeight(window.innerWidth < 640 ? 32 : 40);
85
+ setColumnWidth(getResponsiveColumnWidth());
86
+ };
87
+ window.addEventListener('resize', handleResize);
88
+ return () => window.removeEventListener('resize', handleResize);
89
+ }, []);
72
90
 
73
91
  // Calculate timeline range
74
92
  const timelineRange = React.useMemo(() => {
@@ -147,27 +165,28 @@ export function GanttView({
147
165
  return (
148
166
  <div className={cn("flex flex-col h-full bg-background border rounded-lg overflow-hidden", className)}>
149
167
  {/* Toolbar */}
150
- <div className="flex items-center justify-between p-2 border-b bg-card">
168
+ <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-2 p-2 border-b bg-card">
151
169
  <div className="flex items-center gap-2">
152
- <Button variant="outline" size="sm" onClick={() => onAddClick?.()}>
153
- <Plus className="h-4 w-4 mr-2" />
154
- New Task
170
+ <Button variant="outline" size="sm" onClick={() => onAddClick?.()} aria-label="Create new task">
171
+ <Plus className="h-4 w-4 mr-1 sm:mr-2" />
172
+ <span className="hidden sm:inline">New Task</span>
173
+ <span className="sm:hidden">New</span>
155
174
  </Button>
156
- <div className="h-4 w-px bg-border mx-2" />
175
+ <div className="h-4 w-px bg-border mx-1 sm:mx-2" />
157
176
  <Button variant="ghost" size="icon" className="h-8 w-8">
158
177
  <ChevronLeft className="h-4 w-4" />
159
178
  </Button>
160
179
  <Button variant="ghost" size="icon" className="h-8 w-8">
161
180
  <ChevronRight className="h-4 w-4" />
162
181
  </Button>
163
- <span className="font-semibold text-sm">
182
+ <span className="font-semibold text-xs sm:text-sm">
164
183
  {timelineRange.start.toLocaleDateString(undefined, { month: 'long', year: 'numeric' })}
165
184
  </span>
166
185
  </div>
167
186
 
168
187
  <div className="flex items-center gap-2">
169
188
  <Select value={viewMode} onValueChange={(v) => onViewChange?.(v as GanttViewMode)}>
170
- <SelectTrigger className="w-[120px] h-8">
189
+ <SelectTrigger className="w-[100px] sm:w-[120px] h-8">
171
190
  <SelectValue />
172
191
  </SelectTrigger>
173
192
  <SelectContent>
@@ -178,10 +197,10 @@ export function GanttView({
178
197
  </SelectContent>
179
198
  </Select>
180
199
  <div className="flex bg-muted rounded-md p-1">
181
- <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => setColumnWidth(prev => Math.max(20, prev - 10))}>
200
+ <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => setColumnWidth(prev => Math.max(15, prev - 10))}>
182
201
  <ZoomOut className="h-3 w-3" />
183
202
  </Button>
184
- <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => setColumnWidth(prev => Math.min(100, prev + 10))}>
203
+ <Button variant="ghost" size="icon" className="h-6 w-6" onClick={() => setColumnWidth(prev => Math.min(120, prev + 10))}>
185
204
  <ZoomIn className="h-3 w-3" />
186
205
  </Button>
187
206
  </div>
@@ -191,15 +210,15 @@ export function GanttView({
191
210
  {/* Gantt Body */}
192
211
  <div className="flex flex-col flex-1 overflow-hidden">
193
212
  {/* Headers Row */}
194
- <div className="flex border-b bg-muted/30 shrink-0 h-[50px]">
213
+ <div className="flex border-b bg-muted/30 shrink-0 h-10 sm:h-[50px]">
195
214
  {/* List Header */}
196
215
  <div
197
- className="flex items-center font-medium text-xs text-muted-foreground px-4 border-r bg-card z-20 shadow-sm"
216
+ className="flex items-center font-medium text-xs text-muted-foreground px-2 sm:px-4 border-r bg-card z-20 shadow-sm"
198
217
  style={{ width: taskListWidth, minWidth: taskListWidth }}
199
218
  >
200
219
  <div className="flex-1">Task Name</div>
201
- <div className="w-20 text-right">Start</div>
202
- <div className="w-20 text-right">End</div>
220
+ <div className="w-16 sm:w-20 text-right hidden sm:block">Start</div>
221
+ <div className="w-16 sm:w-20 text-right hidden sm:block">End</div>
203
222
  </div>
204
223
 
205
224
  {/* Timeline Header */}
@@ -235,21 +254,21 @@ export function GanttView({
235
254
  {tasks.map((task) => (
236
255
  <div
237
256
  key={task.id}
238
- className="flex items-center border-b px-4 hover:bg-accent/50 cursor-pointer transition-colors"
239
- style={{ height: ROW_HEIGHT }}
257
+ className="flex items-center border-b px-2 sm:px-4 hover:bg-accent/50 cursor-pointer transition-colors touch-manipulation"
258
+ style={{ height: rowHeight }}
240
259
  onClick={() => onTaskClick?.(task)}
241
260
  >
242
- <div className="flex-1 truncate font-medium text-sm flex items-center gap-2">
261
+ <div className="flex-1 truncate font-medium text-xs sm:text-sm flex items-center gap-2">
243
262
  <div
244
- className="w-2 h-2 rounded-full"
263
+ className="w-2 h-2 rounded-full shrink-0"
245
264
  style={{ backgroundColor: task.color || '#3b82f6' }}
246
265
  />
247
266
  {task.title}
248
267
  </div>
249
- <div className="w-20 text-right text-xs text-muted-foreground">
268
+ <div className="w-16 sm:w-20 text-right text-xs text-muted-foreground hidden sm:block">
250
269
  {task.start.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' })}
251
270
  </div>
252
- <div className="w-20 text-right text-xs text-muted-foreground">
271
+ <div className="w-16 sm:w-20 text-right text-xs text-muted-foreground hidden sm:block">
253
272
  {task.end.toLocaleDateString(undefined, { month: 'numeric', day: 'numeric' })}
254
273
  </div>
255
274
  </div>
@@ -258,7 +277,7 @@ export function GanttView({
258
277
 
259
278
  {/* Right Side: Timeline */}
260
279
  <div
261
- className="flex-1 overflow-auto bg-background/50 relative"
280
+ className="flex-1 overflow-auto bg-background/50 relative [-webkit-overflow-scrolling:touch]"
262
281
  ref={timelineRef}
263
282
  onScroll={handleScroll}
264
283
  >
@@ -286,10 +305,10 @@ export function GanttView({
286
305
  <div
287
306
  key={task.id}
288
307
  className="relative border-b hover:bg-black/5"
289
- style={{ height: ROW_HEIGHT }}
308
+ style={{ height: rowHeight }}
290
309
  >
291
310
  <div
292
- className="absolute top-2 h-[calc(100%-16px)] rounded-sm bg-primary border border-primary-foreground/20 shadow-sm cursor-pointer hover:brightness-110 flex items-center px-2 group"
311
+ className="absolute top-1 sm:top-2 h-[calc(100%-8px)] sm:h-[calc(100%-16px)] rounded-sm bg-primary border border-primary-foreground/20 shadow-sm cursor-pointer hover:brightness-110 flex items-center px-2 group"
293
312
  style={{
294
313
  left: style.left,
295
314
  width: style.width,
@@ -0,0 +1,112 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { SchemaRenderer, SchemaRendererProvider } from '@object-ui/react';
3
+ import type { BaseSchema } from '@object-ui/types';
4
+ import { createStorybookDataSource } from '@storybook-config/datasource';
5
+
6
+ const meta = {
7
+ title: 'Plugins/ObjectGantt',
8
+ component: SchemaRenderer,
9
+ parameters: {
10
+ layout: 'padded',
11
+ },
12
+ tags: ['autodocs'],
13
+ argTypes: {
14
+ schema: { table: { disable: true } },
15
+ },
16
+ } satisfies Meta<any>;
17
+
18
+ export default meta;
19
+ type Story = StoryObj<typeof meta>;
20
+
21
+ const dataSource = createStorybookDataSource();
22
+
23
+ const renderStory = (args: any) => (
24
+ <SchemaRendererProvider dataSource={dataSource}>
25
+ <SchemaRenderer schema={args as unknown as BaseSchema} />
26
+ </SchemaRendererProvider>
27
+ );
28
+
29
+ export const Default: Story = {
30
+ render: renderStory,
31
+ args: {
32
+ type: 'object-gantt',
33
+ objectName: 'Project',
34
+ gantt: {
35
+ startDateField: 'startDate',
36
+ endDateField: 'endDate',
37
+ titleField: 'name',
38
+ progressField: 'progress',
39
+ dependenciesField: 'dependencies',
40
+ },
41
+ tasks: [
42
+ {
43
+ id: '1',
44
+ name: 'Requirements Gathering',
45
+ startDate: '2024-01-01',
46
+ endDate: '2024-01-20',
47
+ progress: 100,
48
+ },
49
+ {
50
+ id: '2',
51
+ name: 'System Design',
52
+ startDate: '2024-01-15',
53
+ endDate: '2024-02-10',
54
+ progress: 80,
55
+ dependencies: ['1'],
56
+ },
57
+ {
58
+ id: '3',
59
+ name: 'Frontend Development',
60
+ startDate: '2024-02-01',
61
+ endDate: '2024-04-15',
62
+ progress: 45,
63
+ dependencies: ['2'],
64
+ },
65
+ {
66
+ id: '4',
67
+ name: 'Backend Development',
68
+ startDate: '2024-02-01',
69
+ endDate: '2024-04-30',
70
+ progress: 35,
71
+ dependencies: ['2'],
72
+ },
73
+ {
74
+ id: '5',
75
+ name: 'QA Testing',
76
+ startDate: '2024-04-15',
77
+ endDate: '2024-05-30',
78
+ progress: 0,
79
+ dependencies: ['3', '4'],
80
+ },
81
+ {
82
+ id: '6',
83
+ name: 'Deployment',
84
+ startDate: '2024-05-25',
85
+ endDate: '2024-06-10',
86
+ progress: 0,
87
+ dependencies: ['5'],
88
+ },
89
+ ],
90
+ className: 'w-full',
91
+ } as any,
92
+ };
93
+
94
+ export const SimpleTimeline: Story = {
95
+ render: renderStory,
96
+ args: {
97
+ type: 'object-gantt',
98
+ objectName: 'Milestone',
99
+ gantt: {
100
+ startDateField: 'start',
101
+ endDateField: 'end',
102
+ titleField: 'title',
103
+ },
104
+ tasks: [
105
+ { id: '1', title: 'Phase 1: Planning', start: '2024-01-01', end: '2024-02-28' },
106
+ { id: '2', title: 'Phase 2: Development', start: '2024-03-01', end: '2024-06-30' },
107
+ { id: '3', title: 'Phase 3: Testing', start: '2024-07-01', end: '2024-08-31' },
108
+ { id: '4', title: 'Phase 4: Launch', start: '2024-09-01', end: '2024-09-30' },
109
+ ],
110
+ className: 'w-full',
111
+ } as any,
112
+ };
@@ -25,6 +25,8 @@
25
25
  import React, { useEffect, useState, useMemo } from 'react';
26
26
  import type { ObjectGridSchema, DataSource, ViewData, GanttConfig } from '@object-ui/types';
27
27
  import { GanttConfigSchema } from '@objectstack/spec/ui';
28
+ import { useNavigationOverlay } from '@object-ui/react';
29
+ import { NavigationOverlay } from '@object-ui/components';
28
30
  import { GanttView, type GanttTask } from './GanttView';
29
31
 
30
32
  export interface ObjectGanttProps {
@@ -32,6 +34,7 @@ export interface ObjectGanttProps {
32
34
  dataSource?: DataSource;
33
35
  className?: string;
34
36
  onTaskClick?: (record: any) => void;
37
+ onRowClick?: (record: any) => void;
35
38
  onEdit?: (record: any) => void;
36
39
  onDelete?: (record: any) => void;
37
40
  }
@@ -128,6 +131,7 @@ export const ObjectGantt: React.FC<ObjectGanttProps> = ({
128
131
  dataSource,
129
132
  className,
130
133
  onTaskClick,
134
+ onRowClick,
131
135
  ...rest
132
136
  }) => {
133
137
  const [data, setData] = useState<any[]>([]);
@@ -180,8 +184,8 @@ export const ObjectGantt: React.FC<ObjectGanttProps> = ({
180
184
  } else if (result && typeof result === 'object') {
181
185
  if (Array.isArray((result as any).data)) {
182
186
  items = (result as any).data;
183
- } else if (Array.isArray((result as any).value)) {
184
- items = (result as any).value;
187
+ } else if (Array.isArray((result as any).records)) {
188
+ items = (result as any).records;
185
189
  }
186
190
  }
187
191
  setData(items);
@@ -253,6 +257,12 @@ export const ObjectGantt: React.FC<ObjectGanttProps> = ({
253
257
  }).filter(task => !isNaN(task.start.getTime()) && !isNaN(task.end.getTime()));
254
258
  }, [data, ganttConfig]);
255
259
 
260
+ const navigation = useNavigationOverlay({
261
+ navigation: (schema as any).navigation,
262
+ objectName: schema.objectName,
263
+ onRowClick,
264
+ });
265
+
256
266
  if (loading) {
257
267
  return (
258
268
  <div className={className}>
@@ -290,12 +300,31 @@ export const ObjectGantt: React.FC<ObjectGanttProps> = ({
290
300
  <div className="h-[calc(100vh-200px)] min-h-[600px]">
291
301
  <GanttView
292
302
  tasks={tasks}
293
- onTaskClick={(task) => onTaskClick?.(task.data)}
303
+ onTaskClick={(task) => {
304
+ navigation.handleClick(task.data);
305
+ onTaskClick?.(task.data);
306
+ }}
294
307
  onAddClick={() => {
295
308
  // Placeholder for add action
296
309
  }}
297
310
  />
298
311
  </div>
312
+ {navigation.isOverlay && (
313
+ <NavigationOverlay {...navigation} title="Task Details">
314
+ {(record) => (
315
+ <div className="space-y-3">
316
+ {Object.entries(record).map(([key, value]) => (
317
+ <div key={key} className="flex flex-col">
318
+ <span className="text-xs font-medium text-muted-foreground uppercase tracking-wide">
319
+ {key.replace(/_/g, ' ')}
320
+ </span>
321
+ <span className="text-sm">{String(value ?? '—')}</span>
322
+ </div>
323
+ ))}
324
+ </div>
325
+ )}
326
+ </NavigationOverlay>
327
+ )}
299
328
  </div>
300
329
  );
301
330
  };