Using Bryntum UI components

In this blog post, I want to look at a common problem in our development process and how we solved it by using Bryntum. The first part of this blog will be a generic part talking about the problem and how to solve it. The second part will actually dive into some of the code to see how the tool helped us overcome the problems.

Time planning… Something all too common in the transport business. No matter what piece of the puzzle you look at in the logistics business, it’s inevitable that some kind of time-based planning pops up along the road (pun intended). Offering users a compelling and versatile way to manage these time-based schedules is a challenge… A challenge we solved with the Bryntum scheduler.

We have a piece of software called “driver-truck-planning”, or DTP for short. It allows the user to manage the availability, maintenance, vacation-days and all other aspects of their drivers and trucks. Having all this info registered makes it easier for the user to schedule who will drive which truck and when. This avoids scheduling mistakes like scheduling a driver who’s currently on holiday.

Whilst building DTP we needed a way for the user to easily add, modify, view and interact with a “planning” (a.k.a schedule). Think of a single big calendar with data in it for a whole force of drivers, or worse, a fleet of trucks. Giving the planner the means to register all data and then providing a good overview of that data is key to find possible bottlenecks, such as a truck that is having maintenance with a driver planned on it, before they happen and to improve overall workforce satisfaction.

Now, we’re not building this application from scratch, we already offer a somewhat older solution of which we could migrate parts into the new and improved app. However… we soon stumbled upon the same roadblock that pestered the previous solution… the scheduling component.

We often use third-party libraries to solve our problems but for scheduling specifically, most of them eventually fall short once a project goes more in-depth. The biggest problem here is the sheer size of the data and the number of custom implementations we want to add. We’ve tried most of the schedulers out there, including scheduleJS, kendo, devextreme, daypilot, dhtmlx but all of them have given us trouble in the past. It was time for something better.

After some more digging, we laid our eyes on the Bryntum-scheduler and we have been using that in 3 of our products so far. We’re pretty excited to have a scheduler which is both customizable yet also delivers a lot out of the box.

What does that all look like? Have a look:

This page shows a sidebar section on the left which contains all of the trucks grouped into what is known as a “trucking group”. The planner can freely collapse and expand the rows to gain a more detailed look at the schedule of a certain group. By default, the planner is shown 4 weeks at a time and he/she can open as many of the trucking groups as required.

The planner can simply drag from the start date through to an end date and he/she will be presented with a form to enter the required data for the selected period. In here the planner can mark a Truck as “In maintenance”, or “Out of commission” which will help him/her whilst actually creating a work schedule for any given week. The images below show both a single day edit and a date range edit.

The example above only explains this matter for drivers but a planner can do the exact same thing for the trucks. By combining the two data sets it’s easy for the planner to find a driver and a truck combination that is valid, meaning that both driver and truck are available.

All in all having this Bryntum-scheduler component in place makes the overview neat and tidy whilst offering the user the flexibility they need.
So far our users are pretty happy with it… but what about our developers?

Implementing the Bryntum scheduler in our codebase.

From here on out the blog will dive into some of the more technical stuff surrounding the component. Code examples are also included.
Feel free to skip to the conclusion of the article if you’re not interested in the development aspects of this blog.

The scheduler itself comes in many forms but we chose to wrap the UMD module and the dependencies together into an npm package for internal use. This is what we call the “core”. We have a second package for use in Angular applications which uses this core package (and thus, the UMD module) to expose a few often-used (Angular) components. Some of these components were copied over from the included Angular examples from the Bryntum website (for example, the bry-button).

Each team that wants to use the scheduler simply includes these packages and writes their logic around them. A basic example of what this looks like for DTP can be found below.

<!-- In the HTML we simply include the scheduler and pass it the required parameters. 
The events property contains the events (blocks) to show on the schedule. -->
<bry-scheduler
  #scheduler
  [rowHeight]="schedulerConfig.rowHeight"
  [minHeight]="schedulerConfig.minHeight"
  [barMargin]="barMargin"
  [startDate]="schedulerConfig.startDate"
  [endDate]="schedulerConfig.endDate"
  [columns]="schedulerConfig.columns"
  [events]="schedulerConfig.events"
  [eventColor]="schedulerConfig.eventColor"
  [eventStyle]="schedulerConfig.eventStyle"
  [eventRenderer]="schedulerConfig.eventRenderer"
  [timeRangesFeature]="schedulerConfig.timeRangesFeature"
  [eventEditFeature]="schedulerConfig.eventEditFeature"
  (onSchedulerEvents)="onSchedulerEvents($event)"
></bry-scheduler>

This scheduler can be wrapped further by each application allowing them to, for example, keep the same row-height consistent throughout certain parts of the application.

We are using NGXS as our state manager so all the data used on the scheduler comes from our state-store and is transformed to work with the Bryntum scheduler per use case. The screens from the previous chapter use the following code to do so:

// we make sure we receive the DriversAvailability from the state-store
@Select(DriverAvailabilityState.DriversAvailability)
public $entities: Observable < DriverAvailability[] > ;

// whenever that happens we update the calendarItems (events) of the bryntum-scheduler:
this.bindEventToState(this.$entities.pipe(skip(1)), () => {
  this.config.calendarItems = this.createCalendarItems();
});

// this private function takes the DriverAvailability entities and transforms 
them into CalendarItems (events) to be used by the bryntum-scheduler.
private createCalendarItems(): CalendarItem[] {
  const items: CalendarItem[] = [];

  this.entities.forEach((driverAvailability: DriverAvailability) => {
    const item: CalendarItem = {
      availabilityId: driverAvailability.id,
      resourceId: `${driverAvailability.truckingGroup.id}+${driverAvailability.driver.id}`,
      startDate: driverAvailability.startTime,
      endDate: driverAvailability.endTime,
      name: driverAvailability.attendanceType.name,
      remark: driverAvailability.remarks,
      seriesId: driverAvailability.seriesId,
      eventColor: driverAvailability.attendanceType.backgroundColor,
      style: CalendarConstants.textColorCls + driverAvailability.attendanceType.foregroundColor,
    };
    items.push(item);
  });
  return items;
}

The code above shows some of the flexibility we can achieve with the component and how we can use it to display, edit, and work with the data in a neat way. Overall the development experience is pretty good. I asked some other developers to give their opinion as well, this is what they had to say:

Some words from our developers

A great tool which comes with many features out of the box. It makes the development very easy by using the built-in components which have a clean look and feel.

Bryntum is a modern tool with a clean UI and a great UX. The provided components are very easy to configure and integrate into your application. Also, the support team has a good response time with clear and well-described feedback.

Conclusion

All in all, we are pretty happy with our decision to go with Bryntum for our solution. It has worked well for our users and our developers are happy to code with and around it.
As mentioned by the developers the support team is also pretty active, they have given us detailed instructions and feedback. They also listen to feedback that is given back.

Overall a really solid experience.