Skip to main content

Working with server

The Gantt library allows working both with the client and server data. The widget doesn't impose any special requirements on the backend. It can be easily connected with any backend platform.

You are free to create your custom server script or if you want to use the ready-made built-in backend, you can find the needed script in the following repository: Go backend

Handle actions​

You can listen to Gantt actions with api.on() and send each change to your server manually:

<script setup>
import { Gantt } from "@svar-ui/vue-gantt";

const server = "https://some-backend-url";

function init(api) {
api.on("add-task", ({ id, task }) => {
fetch(`${server}/tasks`, {
method: "POST",
body: JSON.stringify(task),
});
});
api.on("update-task", ({ id, task }) => {
fetch(`${server}/tasks/${id}`, {
method: "PUT",
body: JSON.stringify(task),
});
});
api.on("delete-task", ({ id }) => {
fetch(`${server}/tasks/${id}`, { method: "DELETE" });
});
}
</script>

<template>
<Gantt :init="init" :tasks="tasks" :links="links" />
</template>

The actions that modify data are: "add-task", "update-task", "delete-task", "add-link", "update-link", "delete-link", "move-task", "copy-task", "add-assignment", "update-assignment", "delete-assignment".

Use api.intercept() instead of api.on() if you need to modify the action data before it is applied or conditionally cancel it.

RestDataProvider​

To automate the process of working with the server, you can use the ready-made helper which is the RestDataProvider service.

The RestDataProvider service:

  • listens to the following actions and sends REST requests (via its send() method) to perform the corresponding data operations on the backend:

  • "add-task"

  • "update-task"

  • "delete-task"

  • "add-link"

  • "update-link"

  • "delete-link"

  • "move-task"

  • "copy-task"

  • "add-assignment"

  • "update-assignment"

  • "delete-assignment"

  • provides a special method for loading data: getData() gets a promise with tasks and links data. Passing { resources: true } loads resources together with tasks and links on initial load. Passing { assignments: true } loads assignments on both initial load (GET /assignments) and subtree load (GET /assignments/{id}), so lazy-loaded branches can deliver their assignments along with their tasks and links

  • offers the debounce functionality to avoid excessive server requests

Connecting RestDataProvider to the backend​

To connect RestDataProvider to the backend, you need to import the RestDataProvider component from @svar-ui/gantt-data-provider, and then create an instance by providing the path to your server in the constructor. You should also include RestDataProvider into the Event Bus order via the api.setNext() method to send the corresponding requests to the server. To load data, apply the getData method.

<script setup>
import { Gantt } from "@svar-ui/vue-gantt";
import { RestDataProvider } from "@svar-ui/gantt-data-provider";
import { ref } from "vue";

const url = "https://some_backend_url";

const server = new RestDataProvider(url);

const tasks = ref([]);
const links = ref([]);
server.getData().then(data => {
tasks.value = data.tasks;
links.value = data.links;
});

function init(api) {
api.intercept("update-task", data => {
data.custom = "custom event";
});
api.setNext(server);
}
</script>

<template>
<Gantt
:tasks="tasks"
:links="links"
:init="init" />
</template>

Enabling the batch mode​

RestDataProvider also supports batching that allows putting multiple API calls into one HTTP request using a single batch request. It's possible to send requests of different types in one batch ("PUT"|"POST"|"DELETE"). RestDataProvider will combine all individual requests into one batch request. Please, refer to batchURL.
To switch to the batch mode, in the constructor define the batchURL that will be applied to send multiple combined requests (e.g., POST https://master--svar-gantt-go-project.io/batch).

new RestDataProvider(
"https://master--svar-gantt-go-project.io",
{ batchURL: "batch" }
);

The example below demonstrates how to enable the batch mode for updating data on tasks and links in case mass editing takes place.

<script setup>
import { RestDataProvider } from "@svar-ui/gantt-data-provider";
import { Gantt, ContextMenu } from "@svar-ui/vue-gantt";
import { ref } from "vue";

const restProvider = new RestDataProvider(
"https://master--svar-gantt-go--myproject.io",
{ batchURL: "batch" }
);

const api = ref(null);
const tasks = ref(null);
const links = ref(null);

restProvider.getData().then(({ tasks: t, links: l }) => {
tasks.value = t;
links.value = l;
});

function init(api) {
api.setNext(restProvider);

api.on("request-data", (ev) => {
restProvider
.getData(ev.id, { assignments: true })
.then(({ tasks, links, assignments }) => {
api.exec("provide-data", {
id: ev.id,
data: {
tasks,
links,
assignments,
},
});
});
});
}
</script>

<template>
<ContextMenu :api="api">
<Gantt :init="init" :tasks="tasks" :links="links" ref="api"/>
</ContextMenu>
</template>

Getting changes from other users​

When several users edit the same project, you can show their changes live with the RemoteEvents service. It receives the changes saved by other clients from the server and applies them to Gantt.

To enable live updates:

  • create a RemoteEvents instance with your RestDataProvider and the URL of the server events stream
  • pass remoteEvents.clientId to the server in the X-Client-Id header via the setHeaders() method, so that the server doesn't send the client its own changes back
  • call remoteEvents.connect(api) in the init handler
  • reload data in the onResync handler, which is called after the connection is restored
<script setup>
import { Gantt } from "@svar-ui/vue-gantt";
import { RestDataProvider, RemoteEvents } from "@svar-ui/gantt-data-provider";
import { ref } from "vue";

const url = "https://some_backend_url";

const restProvider = new RestDataProvider(url);
const remoteEvents = new RemoteEvents(restProvider, {
url: `${url}/events`,
onResync: load,
});
restProvider.setHeaders({ "X-Client-Id": remoteEvents.clientId });

const tasks = ref([]);
const links = ref([]);

function load() {
restProvider.getData().then(data => {
tasks.value = data.tasks;
links.value = data.links;
});
}

function init(api) {
api.setNext(restProvider);
remoteEvents.connect(api).finally(load);
}
</script>

<template>
<Gantt :init="init" :tasks="tasks" :links="links" />
</template>

Changes from other users come to Gantt as regular actions ("add-task", "update-task", "delete-link", etc.) with eventSource: "remote". Such actions are not sent back to the server and are not added to the undo history. Use the eventSource parameter in your handlers to distinguish remote changes from the local ones:

api.on("update-task", ev => {
if (ev.eventSource === "remote") return;
// react to the local changes only
});

The server should provide the events stream. The ready-made Go backend supports it.


Related samples:

Related articles: