# Plugin Gantt





Gantt chart component for ObjectQL data sources - visualizes project tasks, timelines, and dependencies.

## Installation [#installation]

```bash
npm install @object-ui/plugin-gantt
```

## Overview [#overview]

The `@object-ui/plugin-gantt` plugin provides Gantt chart visualization for ObjectQL data sources. It's designed to work with object-based data providers and automatically maps record fields to Gantt chart tasks.

**Note**: This plugin is designed for use with ObjectQL data sources. For a simpler timeline component, see [Timeline Plugin](/docs/plugins/plugin-timeline).

## Features [#features]

* **ObjectQL Integration**: Works seamlessly with object/api/value data providers
* **Automatic Field Mapping**: Maps database fields to Gantt tasks
* **Task Timeline**: Visual bars showing task duration
* **Progress Tracking**: Display task completion percentage (0-100%)
* **Dependencies**: Visualize task dependencies and relationships
* **Date Ranges**: Automatic date range calculation
* **Interactive**: Click handling for tasks
* **Drag-and-drop rescheduling**: Drag a bar to move it; drag either edge to
  resize start/end. Snaps to whole days and persists the change through
  `dataSource.update()` automatically (optimistic local update + revert on
  failure). See the [package README](https://github.com/objectstack-ai/objectui/blob/main/packages/plugin-gantt/README.md#drag-and-drop-rescheduling) for details on the
  lower-level `onTaskUpdate` hook when embedding `<GanttView>` directly.

<PluginLoader plugins="['gantt']">
  ## Interactive Examples [#interactive-examples]

  ### Basic Gantt Chart [#basic-gantt-chart]

  <SchemaExample id="plugin-gantt/project-timeline-with-dependencies" />

  ### Software Development Sprint [#software-development-sprint]

  <SchemaExample id="plugin-gantt/sprint-development-timeline" />

  ### Construction Project [#construction-project]

  <SchemaExample id="plugin-gantt/construction-project-phases" />
</PluginLoader>

## Usage [#usage]

### Basic Usage with ObjectQL [#basic-usage-with-objectql]

```tsx
import '@object-ui/plugin-gantt'
import type { ObjectGanttSchema } from '@object-ui/types'

const schema: ObjectGanttSchema = {
  type: 'object-gantt',
  objectName: 'tasks',  // Your ObjectQL object
  gantt: {
    startDateField: 'startDate',
    endDateField: 'endDate',
    titleField: 'taskName',
    progressField: 'completion',
    dependenciesField: 'dependencies'
  }
}
```

### With Static Data [#with-static-data]

```tsx
const schema = {
  type: 'object-gantt',
  staticData: [
    {
      id: 1,
      taskName: 'Design Phase',
      startDate: '2024-01-01',
      endDate: '2024-01-15',
      completion: 100
    },
    {
      id: 2,
      taskName: 'Development',
      startDate: '2024-01-16',
      endDate: '2024-02-28',
      completion: 60,
      dependencies: [1]
    },
    {
      id: 3,
      taskName: 'Testing',
      startDate: '2024-03-01',
      endDate: '2024-03-15',
      completion: 0,
      dependencies: [2]
    }
  ],
  gantt: {
    startDateField: 'startDate',
    endDateField: 'endDate',
    titleField: 'taskName',
    progressField: 'completion',
    dependenciesField: 'dependencies'
  }
}
```

## Schema API [#schema-api]

```plaintext
{
  type: 'object-gantt',
  objectName?: string,              // ObjectQL object name (read third)
  staticData?: Array<any>,          // Static data array (read second)
  data?: ViewData,                  // Advanced data configuration (read first)
                                    // At least one of data / staticData / objectName is required
  gantt?: GanttConfig,              // Gantt-specific configuration
  viewMode?: 'day' | 'week' | 'month' | 'quarter' | 'year',
  readOnly?: boolean                // disable every edit path
}
```

`onTaskClick` and `className` are &#x2A;*React props on `<ObjectGantt>`**, not schema
keys — the renderer never reads them off the schema, and a function cannot
survive serializable metadata anyway. `viewMode` is read through the gantt
config, so it applies alongside a `gantt` block or the flat `*Field` keys.

### GanttConfig [#ganttconfig]

```plaintext
{
  startDateField: string,      // Field containing task start date
  endDateField: string,        // Field containing task end date
  titleField: string,          // Field to use as task title
  progressField?: string,      // Field for progress (0-100)
  dependenciesField?: string   // Field for task dependencies (array of IDs)
}
```

## Configuration [#configuration]

### Field Mapping [#field-mapping]

Map your database fields to Gantt properties:

```tsx
import type { ObjectGanttSchema } from '@object-ui/types';

const fieldMappedGantt: ObjectGanttSchema = {
  type: 'object-gantt',
  objectName: 'project_tasks',
  gantt: {
    titleField: 'name',           // Database field for task name
    startDateField: 'starts_at',  // Database field for start date
    endDateField: 'ends_at',      // Database field for end date
    progressField: 'percent_done', // Database field for progress
    dependenciesField: 'depends_on' // Database field for dependencies
  }
};
```

### Progress Field [#progress-field]

The progress field should contain a number between 0-100 representing the completion percentage:

{/* doc-snippet: fragment — a SHAPE excerpt of one of the READER's own task RECORDS, not an expression: a bare object literal at statement position parses as a block with labels (measured: TS1005 x4, TS1128 x1). No ObjectUI type describes it — `taskName` / `completion` are the caller's own record fields, named by `gantt.titleField` / `gantt.progressField` above */}

```tsx
{
  id: 1,
  taskName: 'Development',
  startDate: '2024-01-01',
  endDate: '2024-02-01',
  completion: 75  // 75% complete
}
```

### Dependencies Field [#dependencies-field]

The dependencies field should contain an array of task IDs that this task depends on:

{/* doc-snippet: fragment — a SHAPE excerpt of the READER's own task RECORDS, not an expression: a bare array literal at statement position is an expression statement whose element object literals parse as labelled blocks (measured: TS1005 x4). No ObjectUI type describes it — `dependencies` is the caller's own record field, named by `gantt.dependenciesField` above */}

```tsx
[
  {
    id: 1,
    taskName: 'Design',
    startDate: '2024-01-01',
    endDate: '2024-01-15',
    dependencies: []  // No dependencies
  },
  {
    id: 2,
    taskName: 'Development',
    startDate: '2024-01-16',
    endDate: '2024-02-28',
    dependencies: [1]  // Depends on task 1 (Design)
  },
  {
    id: 3,
    taskName: 'Testing',
    startDate: '2024-03-01',
    endDate: '2024-03-15',
    dependencies: [2]  // Depends on task 2 (Development)
  }
]
```

## Data Providers [#data-providers]

### Object Provider (Database) [#object-provider-database]

```tsx
import type { ObjectGanttSchema } from '@object-ui/types';

const objectProviderGantt: ObjectGanttSchema = {
  type: 'object-gantt',
  objectName: 'project_tasks',
  gantt: {
    startDateField: 'start_date',
    endDateField: 'due_date',
    titleField: 'title',
    progressField: 'progress'
  }
};
```

### Value Provider (Static) [#value-provider-static]

```tsx
const valueProviderGantt = {
  type: 'object-gantt',
  staticData: [
    { id: 1, title: 'Task 1', start: '2024-01-01', end: '2024-01-15' },
    { id: 2, title: 'Task 2', start: '2024-01-16', end: '2024-01-31' }
  ],
  gantt: {
    startDateField: 'start',
    endDateField: 'end',
    titleField: 'title'
  }
};
```

### API Provider [#api-provider]

```tsx
const apiProviderGantt = {
  type: 'object-gantt',
  data: {
    provider: 'api',
    // the api member is `read` / `write` HTTP requests — there is no
    // top-level `endpoint` key, and nothing reads one
    read: { url: '/api/project/tasks', method: 'GET' }
  },
  gantt: {
    startDateField: 'startDate',
    endDateField: 'endDate',
    titleField: 'taskName',
    progressField: 'percentComplete'
  }
};
```

When the view renders inside a `SchemaRendererProvider` that supplies an
`apiFetch` (the console host wires an authenticated fetch there), api-provider
requests carry the same credentials — `Authorization`, tenant, and locale
headers — as native platform requests. Without it, requests fall back to the
bare global fetch and rely on same-origin cookies alone.

## Event Handling [#event-handling]

### Task Click [#task-click]

The click handler is a **React prop**, not a schema key — the schema stays
serializable:

```tsx
import { ObjectGantt } from '@object-ui/plugin-gantt';
import type { DataSource } from '@object-ui/types';

export function ProjectGantt({ dataSource }: { dataSource: DataSource }) {
  return (
    <ObjectGantt
      schema={{
        type: 'object-gantt',
        objectName: 'tasks',
        gantt: {
          startDateField: 'start',
          endDateField: 'end',
          titleField: 'name'
        }
      }}
      dataSource={dataSource}
      onTaskClick={(task) => {
        console.log('Task clicked:', task);
        // Open task details / edit / show dependencies
      }}
    />
  );
}
```

Rendered through the registered `object-gantt` type there is usually nothing to
wire: clicking a row already opens the standard detail drawer.

## Examples [#examples]

### Software Project [#software-project]

```tsx
import type { ObjectGanttSchema } from '@object-ui/types';

const softwareProject: ObjectGanttSchema = {
  type: 'object-gantt',
  objectName: 'sprint_tasks',
  gantt: {
    startDateField: 'startDate',
    endDateField: 'endDate',
    titleField: 'taskTitle',
    progressField: 'completionPercent',
    dependenciesField: 'blockedBy'
  }
}
```

### Construction Project [#construction-project-1]

```tsx
import type { ObjectGanttSchema } from '@object-ui/types';

const constructionGantt: ObjectGanttSchema = {
  type: 'object-gantt',
  objectName: 'construction_phases',
  gantt: {
    startDateField: 'phase_start',
    endDateField: 'phase_end',
    titleField: 'phase_name',
    progressField: 'percent_complete'
  }
}
```

### Marketing Campaign [#marketing-campaign]

```tsx
const campaignGantt = {
  type: 'object-gantt',
  staticData: [
    {
      id: 1,
      activity: 'Market Research',
      start: '2024-01-01',
      end: '2024-01-14',
      done: 100
    },
    {
      id: 2,
      activity: 'Content Creation',
      start: '2024-01-15',
      end: '2024-02-15',
      done: 80,
      requires: [1]
    },
    {
      id: 3,
      activity: 'Campaign Launch',
      start: '2024-02-16',
      end: '2024-02-29',
      done: 0,
      requires: [2]
    },
    {
      id: 4,
      activity: 'Performance Analysis',
      start: '2024-03-01',
      end: '2024-03-15',
      done: 0,
      requires: [3]
    }
  ],
  gantt: {
    titleField: 'activity',
    startDateField: 'start',
    endDateField: 'end',
    progressField: 'done',
    dependenciesField: 'requires'
  }
}
```

## Comparison with Timeline Plugin [#comparison-with-timeline-plugin]

| Feature           | object-gantt             | timeline (gantt variant) |
| ----------------- | ------------------------ | ------------------------ |
| **Data Source**   | ObjectQL (database)      | Static arrays            |
| **Dependencies**  | Yes                      | No                       |
| **Progress**      | Yes (0-100%)             | No                       |
| **Use Case**      | Project management       | Simple timelines         |
| **Field Mapping** | Configurable             | Fixed schema             |
| **Best For**      | Database-driven projects | Static presentations     |

**When to use object-gantt**:

* You're using ObjectQL for data management
* You need task dependencies and progress tracking
* Tasks come from a database or API
* You're building project management features

**When to use timeline (gantt variant)**:

* You have static timeline data
* You don't need dependencies or progress
* You're creating simple visual timelines
* You're not using ObjectQL

## Typical Use Cases [#typical-use-cases]

1. **Project Management**: Track project tasks, milestones, and dependencies
2. **Sprint Planning**: Visualize agile sprint tasks and their timeline
3. **Construction Planning**: Display construction phases and their relationships
4. **Event Planning**: Show event preparation tasks and schedules
5. **Product Roadmap**: Display product features and release timelines

## TypeScript Support [#typescript-support]

```plaintext
import type { ObjectGridSchema, GanttConfig } from '@object-ui/types'

const ganttConfig: GanttConfig = {
  startDateField: 'startDate',
  endDateField: 'endDate',
  titleField: 'taskName',
  progressField: 'completion',
  dependenciesField: 'dependencies'
}

const ganttSchema: ObjectGridSchema = {
  type: 'object-gantt',
  objectName: 'project_tasks',
  gantt: ganttConfig
}
```

## Related Documentation [#related-documentation]

* [Timeline Plugin](/docs/plugins/plugin-timeline) - Simpler timeline visualization
* [Plugin System Overview](/docs/guide/plugins)
* [Package README](https://github.com/objectstack-ai/objectui/tree/main/packages/plugin-gantt)
