Skip to main content

Editor

The task editor dialog allows you to configure a set of fields (controls) for viewing and editing task data. The task editor modal dialog consists of configurable fields for managing task data.

Basic setup

To use the task editor, import both Gantt and a standalone Editor component based on SVAR Editor from @svar-ui/react-gantt and pass the api reference to both:

import { useRef } from "react";
import { Gantt, Editor } from "@svar-ui/react-gantt";

function App() {
const api = useRef(null);

return (
<>
<Gantt ref={api} />
<Editor api={api} />
</>
);
}

Configuring the Editor

To define the editor fields, use the items property of the standalone Editor component.

Supported editor field types include:

  • text and textarea
  • date
  • slider
  • select
  • counter
  • links

For example, to define a simple text input field, add its name to the comp field:

import { useRef } from "react";
import { Gantt, Editor } from "@svar-ui/react-gantt";

function App() {
const api = useRef(null);

const items = [
{
key: "text",
comp: "text",
label: "Name",
config: {
placeholder: "Add task name"
},
},
];

return (
<>
<Gantt ref={api} />
<Editor api={api} items={items} />
</>
);
}

To configure the default editor fields, import the getEditorItems helper to get the default array, modify it as needed, and pass the updated array to the Editor component via the items prop.

The example below shows how to remove the "Description" field (which uses the key "details") from the editor:

import { useRef } from "react";
import { Gantt, Editor, getEditorItems } from "@svar-ui/react-gantt";

function App() {
const api = useRef(null);

const items = getEditorItems().filter(item => item.key !== "details");

return (
<>
<Gantt ref={api} />
<Editor api={api} items={items} />
</>
);
}

The next example demonstrates how to selectively use specific fields from default array to configure a custom editor layout, and how to customize the editor's bottom toolbar with Save/Delete/Close buttons.

import { useRef } from "react";
import { getData } from "../data";
import { Gantt, Editor, getEditorItems } from "@svar-ui/react-gantt";

function App() {
const api = useRef(null);
const data = getData();

// Define only the fields you want to include
const keys = ["text", "type", "start", "end", "duration", "progress", "details"];
const items = keys.map(key => getEditorItems().find(op => op.key === key));

const bottomBar = {
items: [
{ comp: "button", type: "secondary", text: "Close", id: "close" },
{ comp: "spacer" },
{ comp: "button", type: "danger", text: "Delete", id: "delete" },
{ comp: "button", type: "primary", text: "Save", id: "save" },
],
};

return (
<>
<Gantt ref={api} tasks={data.tasks} links={data.links} scales={data.scales} />
<Editor api={api} items={items} bottomBar={bottomBar} topBar={false} placement="modal" />
</>
);
}

The next example demonstrates how to enable the TimePicker for comp: "date":

import { useRef } from "react";
import { getData } from "../data";
import { Gantt, Editor, getEditorItems } from "@svar-ui/react-gantt";

function App() {
const { tasks, links } = getData();
const api = useRef(null);

const items = getEditorItems().map(ed => ({
...ed,
...(ed.comp === "date" && { config: { time: true } }),
}));

return (
<>
<Gantt
ref={api}
tasks={tasks}
links={links}
durationUnit={"hour"}
/>
<Editor api={api} items={items} />
</>
);
}

Resources tab

When resources are passed to <Gantt>, the Editor automatically includes a Resources tab. No extra configuration is needed:

import { useRef } from "react";
import { Gantt, Editor } from "@svar-ui/react-gantt";

function App() {
const api = useRef(null);

return (
<>
<Gantt ref={api} tasks={tasks} links={links} scales={scales} resources={resources} assignments={assignments} />
<Editor api={api} />
</>
);
}

The Resources tab lets users assign resources to the task, adjust allocation, and remove assignments. It is hidden automatically for summary tasks.

For the full resources setup including the inline grid column, see Assign resources.

Custom controls

You can extend the task editor with custom React components using the registerEditorItem helper. A registered component can then be used as an editor field via the comp property.

The custom component must support value property and onChange callback.

The example below shows how to register a radio button group component and use it as "Type" field in the editor:

import { useRef } from "react";
import { Gantt, Editor, getEditorItems, registerEditorItem } from "@svar-ui/react-gantt";
import { RadioButtonGroup } from "@svar-ui/react-core";

registerEditorItem("radio", RadioButtonGroup);

const items = [
...getEditorItems(),
{
key: "type",
comp: "radio",
label: "Type",
options, // options for radio
type: "inline",
}
];

function App() {
const api = useRef(null);

return (
<>
<Gantt ref={api} />
<Editor api={api} items={items} />
</>
);
}

Related sample: Editor: custom controls

Comments

You can add a comments section to the task editor using the Comments component from the @wx/react-comments package.

Step 1. Register the Comments component as a custom editor control:

import { registerEditorItem } from "@svar-ui/react-gantt";
import { Comments } from "@wx/react-comments";

registerEditorItem("comments", Comments);

Step 2. Add a comments array to each task in your data. Each comment object requires the following fields:

  • id — unique comment ID
  • user — ID of the user who left the comment
  • content — comment text
  • date — comment date
data.tasks.forEach(task => {
task.comments = [];
});

// Example with initial comments on the first task:
data.tasks[0].comments = [
{ id: 1, user: 1, content: "Let's tackle at least half of the plan items soon.", date: new Date() },
{ id: 2, user: 2, content: "Agreed, let's execute efficiently.", date: new Date() },
];

Step 3. Add the comments field to the editor items and pass a users list and the activeUser ID:

import { useRef } from "react";
import { Gantt, Editor, getEditorItems, registerEditorItem } from "@svar-ui/react-gantt";
import { Comments } from "@wx/react-comments";

registerEditorItem("comments", Comments);

const keys = ["text", "details"];
const items = getEditorItems().filter(op => keys.includes(op.key));
items.push({
key: "comments",
comp: "comments",
label: "Comments",
users: [
{ id: 1, name: "Alex" },
{ id: 2, name: "John" },
{ id: 3, name: "Bob" },
],
activeUser: 1,
});

function App() {
const api = useRef(null);

return (
<>
<Gantt ref={api} tasks={data.tasks} links={data.links} scales={data.scales} />
<Editor api={api} items={items} />
</>
);
}

Related sample: Editor: custom comments

Tasklist

You can embed a checklist inside the task editor using the Tasklist component from the @wx/react-tasklist package.

Step 1. Register the Tasklist component as a custom editor control:

import { registerEditorItem } from "@svar-ui/react-gantt";
import { Tasklist } from "@wx/react-tasklist";

registerEditorItem("tasks", Tasklist);

Step 2. Add a tasks array to each task in your data. Each item requires:

  • id — unique item ID
  • content — item description text
  • status1 for completed, 0 for incomplete
  • date — (optional) item date
data.tasks.forEach(task => {
task.tasks = [];
});

// Example with initial checklist items on the first task:
data.tasks[0].tasks = [
{ id: 1, content: "Research best practices for the integration", status: 1 },
{ id: 2, content: "Explore modern approaches to building the app", status: 0 },
{ id: 3, content: "Optimize performance", status: 0 },
];

Step 3. Add the task list field to the editor items:

import { useRef } from "react";
import { Gantt, Editor, getEditorItems, registerEditorItem } from "@svar-ui/react-gantt";
import { Tasklist } from "@wx/react-tasklist";

registerEditorItem("tasks", Tasklist);

const keys = ["text", "details"];
const items = getEditorItems().filter(op => keys.includes(op.key));
items.push({
key: "tasks",
comp: "tasks",
label: "Tasks",
});

function App() {
const api = useRef(null);

return (
<>
<Gantt ref={api} tasks={data.tasks} links={data.links} scales={data.scales} />
<Editor api={api} items={items} />
</>
);
}

Related sample: Editor: custom tasks

Validation

You can add validation rules to editor fields by extending the items returned from getEditorItems(). Set autoSave={false} on the Editor component so that validation runs before the task is saved.

Each field supports the following validation properties:

  • required — marks the field as required; the editor will block saving if the field is empty
  • validation — a function (value) => boolean that returns true if the value is valid
  • validationMessage — the error message shown when validation returns false
import { useRef } from "react";
import { Gantt, Editor, getEditorItems } from "@svar-ui/react-gantt";

function App() {
const api = useRef(null);

const items = getEditorItems().map(ed => ({
...ed,
...(ed.comp === "text" && { required: true }),
...(ed.comp === "counter" && {
validation: v => v <= 50,
validationMessage: "Task duration should not exceed 50 days",
}),
}));

return (
<>
<Gantt ref={api} tasks={data.tasks} links={data.links} scales={data.scales} />
<Editor api={api} items={items} autoSave={false} />
</>
);
}

In this example:

  • The task name field (comp: "text") is required
  • The duration field (comp: "counter") must not exceed 50 days

Related sample: Editor: validation

Custom editor dialog

To add your custom editor, you should:

  • Import the custom Form component for adding/editing tasks
  • Use the api.intercept method to disable opening the default editor by blocking the show-editor action (return false)
  • Add the Form tag, define tasks and taskTypes, and add the action handler function that triggers the update-task or delete-task action.
import { useState, useRef } from "react";
import { getData } from "../data";
import { Gantt } from "@svar-ui/react-gantt";
import { Form } from "../custom/Form.jsx";

function App() {
const data = getData();
const taskTypes = [
{ id: "task", label: "Task" },
{ id: "milestone", label: "Milestone" },
{ id: "summary", label: "Project" },
];

const [task, setTask] = useState(null);
const api = useRef(null);
let store;

const init = (apiInstance) => {
store = apiInstance.getState().tasks;

apiInstance.intercept("show-editor", data => {
setTask(store.byId(data.id));
return false;
});
};

const formAction = (ev) => {
const { action, data } = ev;

switch (action) {
case "close-form":
setTask(null);
break;

default:
api.current.exec(action, data); // "update-task", "delete-task" actions
break;
}
};

return (
<>
<Gantt
tasks={data.tasks}
links={data.links}
scales={data.scales}
ref={api}
init={init}
/>

{task && (
<Form task={task} taskTypes={taskTypes} onAction={formAction} />
)}
</>
);
}

Related sample: Custom edit form

Read-only editor

You can set the Editor to readonly to allow users to view task data without being able to edit it. Pass the readonly prop to the Editor component:

<Gantt ref={api} tasks={data.tasks} links={data.links} scales={data.scales} />
<Editor api={api} readonly />

This affects only the editor dialog. To make the entire Gantt chart non-interactive, use the Gantt-level readonly property instead.

Related sample: Editor: readonly