Using Bryntum Scheduler to Optimize Driver and Shift Logistics
Tags: javascript, tutorial, frontend, productivity
Published: 2023-08-29 05:45:55


[Bryntum Scheduler](https://www.bryntum.com/products/scheduler/) is a modern world-class tool that allows you to develop and integrate scheduling functionalities in your web applications. It provides intuitive functionalities such as dragging events, connecting scheduler tasks, and filtering events. The team at [Bryntum](https://www.bryntum.com/) has ensured that the tool is highly performant such that it works well with any application integration and on any device without using extensive amounts of memory and processing power, regardless of the volume of data it's processing. Additionally, it's highly customizable, giving you the freedom to quickly implement your ideas.

Bryntum Scheduler can be used in all kinds of use cases, including project management applications that require distributing tasks across users and optimizing shift logistics.

In this article, you'll learn how to integrate Bryntum Scheduler by creating a sample driver shift application. In this application, you'll implement some of Bryntum's basic features, like dragging events and listening for events.

## Implementing a Driver Shift Application

Before you begin, you'll need the following prerequisites to start using Bryntum Scheduler in your application:

* The latest version of [Node.js](https://nodejs.org/en/) and [npm](https://www.npmjs.com).
* A code editor: There are several code editors available for web development with useful features to speed up your development workflow, including [Visual Studio (VS) Code](https://code.visualstudio.com/) and [Sublime Text](https://www.sublimetext.com/).

In addition to these prerequisites, you also need to configure Bryntum Scheduler. There are [several licenses available](https://www.bryntum.com/store/scheduler/) depending on the type of product you're building and the number of developers that will be working on the product. However, for this tutorial, you'll be using the trial version.

Open your terminal and run the following commands:

```bash
npm config set "@bryntum:registry=https://npm.bryntum.com"
npm login --registry=https://npm.bryntum.com
```

You will be prompted for your username, password, and email. Enter your details in the following format:

```bash
Username: user..yourdomain.com
Password: trial
Email: (this IS public) user@yourdomain.com
```

> **Please note:** In the username, the "@" in your email was replaced with "..". Therefore, if your email is daniel@draft.dev, your username would look like this: daniel..draft.dev. In addition, you must use the word "trial" for your password. If not, you won't be able to access the trial version.

### Installing the Demo Application

Now that you have all the prerequisites, it's time to create the application. In your terminal, run the following command:

```bash
npx create-react-app driver-app --template @bryntum/cra-template-javascript-scheduler
```

After installation, open the `driver-app` directory in your favorite code editor.

> Note that if you want to take full control of the Bryntum Scheduler upgrades in the future, it's important that you remove the `^` sign that is automatically included in the versions of the dependency packages found in `package.json`. Therefore, remove the `^` sign (as seen here), and run `npm install` again:

```json
"dependencies": {
  "@bryntum/scheduler": "npm:@bryntum/scheduler-trial@5.1.3",
  "@bryntum/scheduler-react": "5.1.3",
  "react": "17.0.2",
  "react-dom": "17.0.2",
  "react-scripts": "4.0.3"
},
"devDependencies": {
  "babel-preset-react-app": "npm:@bryntum/babel-preset-react-app@10.0.0",
  "cross-env": "~7.0.3",
  "sass": "~1.42.1"
}
```

Then run the following:

```bash
npm install
```

Now you've successfully installed the demo Bryntum Scheduler app. To see how it looks, go to your terminal and run the following:

```bash
npm run dev
```

Then your browser will automatically launch [http://localhost:3000](http://localhost:3000), and you should see a web page like this:

![Sample Scheduler app](https://i.imgur.com/VJg7myi.png)

You can play around with the demo app before you start updating the application code to fit your application use case.

### Developing the Logistics Application

To begin developing the logistics application, open the `src/App.js` file, and you will see the following code:

```javascript
import { BryntumScheduler } from '@bryntum/scheduler-react';
import { schedulerConfig } from './SchedulerConfig';
import './App.scss';

function App() {
    return (
        <BryntumScheduler {...schedulerConfig} />
    );
}

// If you plan to use stateful React collections for data binding, please check this guide
// https://www.bryntum.com/docs/scheduler/guide/Scheduler/integration/react/data-binding

export default App;
```

The `BryntumScheduler` component is the component responsible for the scheduling user interface (UI) and interactivity you experienced when you visited [http://localhost:3000](http://localhost:3000). However, the type of information displayed and the events that occur when you interact with the Scheduler are only made possible by the variables and methods you pass to the `BryntumScheduler` component `allowed properties`. You can find the `allowed properties` with the help of the `Intellisese` code editor or by checking the [API documentation](https://www.bryntum.com/docs/scheduler/api/Scheduler/view/Scheduler).

In the `BryntumScheduler` component in `src/App.js`, you can see that some `BryntumScheduler` properties are passed through the `schedulerConfig` from `src/SchedulerConfig.js`, which is a static file. However, suppose you plan on loading some of the property variables dynamically. In that case, you have to remove the property from the `SchedulerConfig.js` file and declare the variable using any of React's hooks: [`useState`](https://reactjs.org/docs/hooks-state.html), [`useReducer`](https://reactjs.org/docs/hooks-reference.html#usereducer), or [`React Redux`](https://react-redux.js.org/). Then you pass the variable to the property in the `BryntumScheduler` component.

For instance, if you want to make the `rowHeight` and `columns` dynamic, then you need to update your `SchedulerConfig.js` and `App.js` files:

```javascript
# SchedulerConfig.js
const schedulerConfig = {

    startDate        : new Date(2022, 2, 20, 6),
    endDate          : new Date(2022, 2, 20, 20),
    viewPreset       : 'hourAndDay',
    barMargin        : 5,
    multiEventSelect : true,

    crudManager : {
        transport : {
            load : {
                url : 'data/scheduler-data.json'
            }
        },
        autoLoad  : true
    }
};

export { schedulerConfig };

```

```javascript
# App.js

import { useState } from 'react'
import { BryntumScheduler } from '@bryntum/scheduler-react';
import { schedulerConfig } from './SchedulerConfig';
import './App.scss';

function App() {


    const [rowHeight, setRowHeight] = useState(50)
    const [columns, setColumns] = useState([
      { text : 'Name', field : 'name', width : 130 }
  ])

    return (
        <BryntumScheduler {...schedulerConfig} rowHeight={rowHeight} columns={columns} />
    );
}

// If you plan to use stateful React collections for data binding, please check this guide
// https://www.bryntum.com/docs/scheduler/guide/Scheduler/integration/react/data-binding

export default App;
```

The focus should be more on the `App.js` file where the `useState` hook was used.

### Loading the Driver and Logistics Data

There are two options for loading the driver and logistics data into your application. You can use the [in-line option](https://www.bryntum.com/docs/scheduler/guide/Scheduler/integration/react/data-binding#binding-existing-data-to-the-component), where you fetch the data from an external source and pass the data using the `resources` and `events` properties (similar to the previous example), or you can use the [`CrudManager`](https://www.bryntum.com/docs/scheduler/guide/Scheduler/integration/react/data-binding#using-crudmanager-transport) transport, which is the default method that is currently being used in this demo app. The `CrudManager` transport provides more benefits as you tend to write less code because of the abstraction it provides compared to passing the data in line into the component.

In the `SchedulerConfig.js` file, you'll find the `crudManager` property, which allows you to fetch data from a source, and you can include the [`sync`](https://www.bryntum.com/docs/scheduler/guide/Scheduler/integration/react/data-binding#using-crudmanager-transport) property, which automatically sends the updated Scheduler events to your server. However, for this tutorial, you'll stick to using JSON data to populate the Scheduler.

Open `public/data/scheduler-data.json` in your editor and replace the previous content with the following:

```json
{
  "success": true,
  "resources": {
    "rows": [
      {
        "id": "1",
        "name": "Mark",
        "rowHeight": 70
      },
      {
        "id": "2",
        "name": "Sarah"
      },
      {
        "id": "3",
        "name": "Jonah"
      },
      {
        "id": "4",
        "name": "Rachel"
      }
    ]
  },
  "events": {
    "rows": [
      {
        "id": 1,
        "resourceId": "1",
        "startDate": "2022-03-20T10:00",
        "endDate": "2022-03-20T12:00",
        "name": "Package #345 delivery to 728 Jerry Toth Drive, Mcgrath, Alaska",
        "eventColor": "pink"
      },
      {
        "id": 2,
        "resourceId": "2",
        "startDate": "2022-03-20T12:00",
        "endDate": "2022-03-20T13:30",
        "name": "Package #105 delivery to 593 Riverside Drive, Atlanta, Georgia"
      },
      {
        "id": 3,
        "resourceId": "3",
        "startDate": "2022-03-20T14:00",
        "duration": 2,
        "durationUnit": "h",
        "name": "Package #246 Delivery to 4108 Peck Street, Chester, New Hampshire",
        "eventColor": "blue"
      },
      {
        "id": 4,
        "resourceId": "4",
        "startDate": "2022-03-20T08:00",
        "endDate": "2022-03-20T11:00",
        "name": "Package #112 delivery to 7448 Romano Street, Dedham, Massachusetts"
      }
    ]
  }
}

```

Return to [http://localhost:3000](http://localhost:3000), and you'll find that your data is now loaded:

![New Scheduler data](https://i.imgur.com/0nYOUXA.png)

In the previous code, you'll notice two important keys: [`resources` and `events`](https://www.bryntum.com/docs/scheduler/guide/Scheduler/data/displayingdata). The `resources` key contains your drivers' information.

Every `resources` field must have an `id` and `name` field. The `id` is used by the `events` key to reference the delivery information with the respective drivers, and the `name` field displays the resource's name on the Scheduler interface.

The `resources` key also accepts other fields, such as `columnWidth` and `rowHeight`, which are basically adjusting the styles of the particular rows, as seen in the example data in `public/data/scheduler-data.json`. Check out the [API guide](https://www.bryntum.com/docs/scheduler/api/Scheduler/model/ResourceModel#field-rowHeight) for more information on the fields the `resources` key accepts.

Meanwhile, the `events` key contains the actions the drivers are supposed to perform. The key contains fields referencing the driver from the `resources` key via `resourceId`, when the action should start and end via the `startDate` and `endDate` field, the information about the action via the `name` field, and other fields that you may choose to include, such as the `eventColor` and `eventIcon`. You can learn more about the acceptable fields on [Bryntum's website](https://www.bryntum.com/docs/scheduler/api/Scheduler/model/EventModel#fields).

### Performing Operations on the Scheduler

There are several actions you can perform on the Scheduler, including clicking, dragging, double-clicking, right-clicking, and adding events directly on the Scheduler. In addition, you can also perform custom operations based on the actions mentioned previously.

In your `App.js` file, replace the content with the following:

```javascript
import { BryntumScheduler } from '@bryntum/scheduler-react';
import { schedulerConfig } from './SchedulerConfig';
import './App.scss';

function App() {

    const onEventDrag = (value) => {
      // Performing custom operation
      console.log("Event Dragged", value);
    }

    const eventDoubleClick = (value) => {
      // Performing custom operation
      console.log("Event Double Clicked", value);
    }

    return (
        <BryntumScheduler {...schedulerConfig} onEventDrag={onEventDrag} onEventDblClick={eventDoubleClick} />
    );
}

// If you plan to use stateful React collections for data binding please check this guide
// https://www.bryntum.com/docs/scheduler/guide/Scheduler/integration/react/data-binding

export default App;
```

Now go to [http://localhost:3000](http://localhost:3000) and drag any of the events or double-click on any event that is logged in your console. If you open the inspect window by pressing `Command + Shift + C` on macOS or `Ctrl + Shift + C` on Windows, check your console tab to see some data appear when you drag or double-click any events. All this is possible because of the event listener properties you added to the `BryntumScheduler` component and then assigned a function to these properties. The custom functions contain the operations you would like to perform.

For more information on allowed event listeners, check out [this documentation](https://www.bryntum.com/docs/scheduler/api/Scheduler/view/mixin).

### Displaying Unavailable Drivers

There are scenarios where drivers may be unavailable but still need to be displayed on the Scheduler. To display unavailable drivers, you have to include the `readOnly` attribute on the `resources` and `events` keys of the associated driver. You can't drag new events to a driver with the `readOnly` attribute. In addition, you can't modify existing events for that driver.

> **Please note:** For read-only rows to work effectively, you need to include the `eventDragCreateFeature` property to the `BryntumScheduler` component in `App.js`.

The updated code for `public/data/scheduler-data.json` will look like this:

```json
{
  "success": true,
  "resources": {
    "rows": [
      {
        "id": "1",
        "name": "Mark",
        "rowHeight": 70,
        "readOnly": true
      },
      {
        "id": "2",
        "name": "Sarah"
      },
      {
        "id": "3",
        "name": "Jonah"
      },
      {
        "id": "4",
        "name": "Rachel"
      }
    ]
  },
  "events": {
    "rows": [
      {
        "id": 1,
        "resourceId": "1",
        "startDate": "2022-03-20T10:00",
        "endDate": "2022-03-20T12:00",
        "name": "Package #345 delivery to 728 Jerry Toth Drive, Mcgrath, Alaska",
        "eventColor": "pink",
        "readOnly": true
      },
      {
        "id": 2,
        "resourceId": "2",
        "startDate": "2022-03-20T12:00",
        "endDate": "2022-03-20T13:30",
        "name": "Package #105 delivery to 593 Riverside Drive, Atlanta, Georgia"
      },
      {
        "id": 3,
        "resourceId": "3",
        "startDate": "2022-03-20T14:00",
        "duration": 2,
        "durationUnit": "h",
        "name": "Package #246 Delivery to 4108 Peck Street, Chester, New Hampshire",
        "eventColor": "blue"
      },
      {
        "id": 4,
        "resourceId": "4",
        "startDate": "2022-03-20T08:00",
        "endDate": "2022-03-20T11:00",
        "name": "Package #112 delivery to 7448 Romano Street, Dedham, Massachusetts"
      }
    ]
  }
}
```

And the updated code for the `src/App.js` is as follows:

```javascript
import { BryntumScheduler } from '@bryntum/scheduler-react';
import { schedulerConfig } from './SchedulerConfig';
import './App.scss';

function App() {

    const onEventDrag = (value) => {
      // Performing custom operation
      console.log("Event Dragged", value);
    }

    const eventDoubleClick = (value) => {
      // Performing custom operation
      console.log("Event Double Clicked", value);
    }

    return (
        <BryntumScheduler {...schedulerConfig} onEventDrag={onEventDrag} onEventDblClick={eventDoubleClick} eventDragCreateFeature={false} />
    );
}

// If you plan to use stateful React collections for data binding please check this guide
// https://www.bryntum.com/docs/scheduler/guide/Scheduler/integration/react/data-binding

export default App;
```

![Disabled driver](https://i.imgur.com/eWcMkj9.png)

As you can see, the unavailable driver has their name blurred out, and because of that, it's not possible to add a new event or drag existing events associated with that driver.

## Conclusion

[Bryntum Scheduler](https://www.bryntum.com/products/scheduler/) is a sophisticated tool for creating or integrating scheduling functionalities into your applications without reinventing the wheel. With its powerful features and easy-to-use functionalities, it's easy to start integrating scheduling functionalities into your application.

In this tutorial, you learned how to install the Bryntum Scheduler, load data into it, and perform custom operations. Additionally, you can find the public repository for this tutorial on this [GitHub repo](https://github.com/tolustar/optimizing-drivers-shift-Bryntum-Scheduler).

Bryntum Scheduler isn't the only component offered by [Bryntum](https://www.bryntum.com). It has several other powerful components that have been carefully developed to ease integration and usage, like [Bryntum Gantt](https://bryntum.com/docs/gantt) and [Bryntum Scheduler Pro](https://www.bryntum.com/products/scheduler-pro/).

Are you already using [Bryntum Scheduler](https://www.bryntum.com/products/grid/)? We'd love to hear your feedback on how it's impacted your workflow.

[Bryntum](https://www.bryntum.com) helps the world stay on schedule. Our component library offers a selection of high-quality, advanced UI controls for various frontend frameworks. Want to learn more? Try out our scheduling and Gantt components at [bryntum.com](https://www.bryntum.com).