v7.3.0
SupportExamplesFree Trial

Upgrade guides for Scheduler Pro v6.0.0+

Scheduler Pro v6.0.0

Adjusting your data structure for Calendar editor support

This release introduces the calendar editor - a special widget allowing to edit calendar data. Implementing the widget required a few changes on the data level. The CalendarIntervalModel model has got two new fields:

  • type - a string field with two possible values: Week and Exception.
  • availability - a store of the interval availability ranges.
  • compositeCode - a string field helping the calendar editor to identify cases when multiple intervals should be represented as a singe interval in UI (happens when configuring weeks).

Please add corresponding fields to your database structure if you plan to use the calendar editor.

Checking your data for Calendar editor support

For recurring calendar intervals we use the Later JS library under the hood. Its syntax is quite rich which is good. But the downside is it's tricky to cover all its possible configurations in the UI. Thus the calendar editor at the moment supports only the most common cases used by the calendars.

You can check if the new editor supports your data by calling the calendarManagerStorevalidateAllRecordsForCalendarEditor method after the data is loaded:

calendarManagerStore.validateAllRecordsForCalendarEditor();

That will report found errors to the browser console. If nothing is reported the data is good.

For instance the calendar editor data does not support so called composite schedules (rules looking like {rule1} and {rule2} or {rule1} except {rule2}). Let's say we have a "Working hours" calendar with the following unsupported rules:

{
    "recurrentStartDate" : "at 8:00 except on Saturday and Sunday",
    "recurrentEndDate"   : "at 17:00 except on Saturday and Sunday",
    "isWorking"          : true
},

So if we trigger calendars validation:

// validate all calendars in the store
calendarManagerStore.validateAllRecordsForCalendarEditor();

That will dump a warning in the browser console:

  CalendarEditorStore: The "Working hours" calendar interval cannot be handled. Please copy its data and
  report to  https://bryntum.com/forum :
{
  "id": "_generatedModelClass_9ce06c8d-df47-4d4d-921b-3b51fd806e98",
  "recurrentStartDate": "at 8:00 except on Saturday and Sunday",
  "recurrentEndDate": "at 17:00 except on Saturday and Sunday",
  "isWorking": true,
  "availability": null
}

In that exact case the rules can be easily changed to a non-composite look:

{
    "recurrentStartDate" : "every weekday at 8:00",
    "recurrentEndDate"   : "every weekday at 17:00",
    "isWorking"          : true
}

And other similar "composite cases" could require breaking an interval into multiple ones with simple rules. Or you could just try making them manually with the calendar editor.

As always if you face a case you cannot implement report us: https://bryntum.com/forum

BryntumProjectModel framework wrapper replaced

BryntumProjectModel framework wrapper was deprecated in v5.6.0 and is now removed. Use BryntumSchedulerProProjectModel instead.

Angular

app.component.ts:

import { BryntumSchedulerProProjectModelComponent } from '@bryntum/schedulerpro-angular';

app.component.html:

<bryntum-schedulerpro-project-model
   #project
   // Project properties
/>

React

App.tsx:

import { BryntumSchedulerProProjectModelComponent } from '@bryntum/schedulerpro-react';

...

function App() {
    return (
        <>
            <BryntumSchedulerProProjectModel
                ref={project}
                // Project properties
            />
        </>
    );
}

Vue

App.vue:

<template>
    <bryntum-schedulerpro-project-model
        ref="project"
        // Project properties
    />
</template>

<script>
    import { BryntumSchedulerProProjectModel } from '@bryntum/schedulerpro-vue-3';

    export default {
        components : {
            BryntumSchedulerProProjectModel
        }
    };
</script>

Removed eventBodyTemplate

With this release we removed the eventBodyTemplate function, which was deprecated in v5.6.2. It was originally ported over from our older line of products to ease migration, but it is redundant since an eventRenderer can accomplish the same result. By removing it we have simplified the codebase, and reduced confusion on where to put event bar customization code.

Old code:

const scheduler = new SchedulerPro({
    eventBodyTemplate : data => StringHelper.xss`
        <div>${data.headerText}</div>
        <div>${data.footerText}</div>
    `,

    eventRenderer({ eventRecord, resourceRecord, renderData }) {
        return {
            headerText : DateHelper.format(eventRecord.startDate, 'HH:mm'),
            footerText : StringHelper.encodeHtml(eventRecord.name || '')
        };
    }
});

New code:

const scheduler = new SchedulerPro({
    eventRenderer({ eventRecord, resourceRecord, renderData }) {
        return `
            <div>${DateHelper.format(eventRecord.startDate, 'HH:mm')}</div>
            <div>${StringHelper.encodeHtml(eventRecord.name || '')}</div>
        `;
    }
});

Or more efficiently using DomConfigs:

const scheduler = new SchedulerPro({
    eventRenderer({ eventRecord, resourceRecord, renderData }) {
        return [
            {
                class : 'b-sch-event-header',
                text  : DateHelper.format(eventRecord.startDate, 'HH:mm')
            },
            {
                class : 'b-sch-event-footer',
                text  : eventRecord.name || ''
            }
        ];
    }
});

Note that in some edge cases the new appearance might not be identical to the old. For example if your dataset has icons on the events, but your eventBodyTemplate did not render them, they might now be unexpectedly shown. Please review your UI after upgrading to ensure it looks as expected.

New location for Core.util.helper.Point class

The Core.util.helper.Point class was moved in v5.6.0 to solve circular module dependencies. It is now a named (Point) export of the Core.util.helper.Rectangle module.

Changes are required if you are directly importing the class from sources:

Old code:

import Point from 'path-to-lib/Core/helper/util/Point.js';

New code:

import { Point } from 'path-to-lib/Core/helper/util/Rectangle.js';

Note: No changes required for importing from module or umd bundles.

Restructured features

Internal development made it necessary to in v5.5.0 define two features specifically for Scheduler Pro and one for Scheduler:

  • Grid.feature.RowReorder -> Scheduler.feature.RowReorder
  • Grid.feature.CellEdit -> SchedulerPro.feature.CellEdit
  • Scheduler.feature.Dependencies -> SchedulerPro.feature.Dependencies

If you extended those features to add some custom logic or imported feature directly from source, you need change base classes to the new ones and use correct import path.

Angular View Engine wrappers for Angular 11 and older versions

In v5.3.3 a new @bryntum/schedulerpro-angular-view package designed to work with Angular 11 and older versions was added, which use the View Engine for rendering. If you are using one of the legacy Angular versions, please follow these steps to use the package:

Install the package using npm:

npm install @bryntum/schedulerpro-angular-view@6.0.0

Import the component in your Angular application:

import { BryntumSchedulerProComponent } from '@bryntum/schedulerpro-angular-view';

Do not forget to remove previously used @bryntum/schedulerPro-angular package which requires Angular 12 or newer version.

Please check Angular integration guide for additional information.

Localization update

Localization update

LocaleManager.registerLocale was deprecated in v5.3.0 and has now been removed. LocaleHelper.publishLocale should be used instead.

Old code:

LocaleManager.registerLocale('Es', {
    desc : 'Spanish', locale : {
        localeName : 'Es',
        localeDesc : 'Spanish',
        locale     : {
            /* localization */
        }
    }
});

New code:

LocaleHelper.publishLocale({
    localeName : 'Es',
    localeDesc : 'Spanish',
    localeCode : 'es',
    /* localization */
});

LocaleManager.extendLocale was deprecated in v5.3.0 and has now been removed. LocaleManager.applyLocale should be used instead.

Old code:

LocaleManager.extendLocale('Es', {
    desc : 'Spanish', locale : {
        locale : {
            /* localization */
        }
    }
});

New code:

LocaleManager.applyLocale({
    localeName : 'Es',
    localeDesc : 'Spanish',
    localeCode : 'es',
    /* localization */
});

Check our localization guide for the details.

New effort field in task editor

Task editor got a new Effort field on the Ganeral tab in v5.3.0. If you don't need it, it can be removed like this:

const scheduler = new SchedulerPro({
    features : {
        taskEdit : {
            items : {
                generalTab : {
                    items : {
                        // get rid of effort field
                        effortField : false
                    }
                }
            }
        }
    },
    ...
})

New module bundle for Angular

Bryntum Scheduler Pro is since v5.1.0 delivered with a new ES Module bundle without WebComponents. This was done to avoid conflicts with Angular which also uses WebComponents for applications.

Angular wrappers use schedulerpro.module.js bundle in favor of removed schedulerpro.lite.umd.js one.

Your Angular applications should be upgraded to use the new schedulerpro.module.js bundle which is set as main for @bryntum/schedulerpro NPM package.

Replace all application imports from Bryntum packages as shown below:

Old code:

import { SchedulerPro } from '@bryntum/schedulerpro/schedulerpro.lite.umd.js';

New code:

import { SchedulerPro } from '@bryntum/schedulerpro';

New module bundle with WebComponents

Bryntum Scheduler Pro is since v5.1.0 delivered with a new schedulerpro.wc.module.js ES Module bundle with WebComponents.

Your applications which use WebComponents and modules bundle should be upgraded to import from new schedulerpro.wc.module.js instead of schedulerpro.module.js.

New keyboard shortcuts functionality

KeyMap is a mixin that allows for standardized and customizable keyboard shortcuts functionality. KeyMap is mixed in to Widget by default and therefore available to all Widget child classes. There is a new guide describing how to customize currently integrated keyboard shortcuts.

Scheduler Pro v5.0.4

EventCopyPaste enabled by default

The EventCopyPaste feature was enabled by default in Scheduler Pro v5.0.4. If that has some negative effect on your application you can turn it off:

const scheduler = new SchedulerPro({
    features : {
        eventCopyPaste : false
    }
});

Validating backend responses by default

The validateResponse flag on ProjectModel was changed v5.0.3 to default to true. When enabled, it validates responses from the backend and outputs a message on console if the format isn't valid. This is helpful during the development phase, but can be turned off in production:

const scheduler = new SchedulerPro({
   project : {
       // Turn response validation off
       validateResponse : false,
       ...
   }
});

New Vue wrapper config option relayStoreEvents

This option was introduced in v5.0.3 to allow relaying of store events to the Scheduler Pro instance. It defaults to false (no events relayed) which changes the default behavior so if your application relies on relayed events, configure it as true.

Example:

<bryntum-scheduler-pro
    :relayStoreEvents="true"
>

The config option applies to both Vue 2 and Vue 3.

ScaleColumn removed

It was previously moved to Scheduler, but a proxy was kept in Scheduler Pro for compatibility. This proxy has now been removed. If you were importing it directly from our sources, you need to update your import url:

Old code:

import ScaleColumn from 'lib/SchedulerPro/column/ScaleColumn.js';

New code:

import ScaleColumn from 'lib/Scheduler/column/ScaleColumn.js';

Store now defaults to use raw data for remotely loaded data

The useRawData setting on Store is now enabled by default when data is loaded remotely using an AjaxStore or a CrudManager (the ProjectModel), but with all sub-settings disabled. This will boost load performance slightly, by not cloning the incoming data objects.

If you want to restore the previous behavior, you can set useRawData : false on the store:

const scheduler = new SchedulerPro({
    project : {
        eventStore : {
            useRawData : false
        }
    }
});

Or for all project stores:

const scheduler = new SchedulerPro({
    project : {
        useRawData : false
    }
});

Manually scheduled events no longer extend over non-working time

The default value for ProjectModel.skipNonWorkingTimeInDurationWhenSchedulingManually is now false. If you want manually scheduled events to extend their duration when intersecting non-working time, you have to configure it as true:

const scheduler = new SchedulerPro({
    project : {
        skipNonWorkingTimeInDurationWhenSchedulingManually : true
    }
});

Removed fetchOptions and requestConfig from ProjectModel.transport

The previously (in v5.0.0) deprecated fetchOptions and requestConfig properties of ProjectModel.transport.load and ProjectModel.transport.sync were removed in v6.0.0. Any settings passed in those properties can instead be passed directly on the upper level (in the load or sync configuration objects).

Old code:

const scheduler = new SchedulerPro({
    project : {
        transport : {
            load : {
                fetchOptions : {
                    credentials : 'include'
                }
            }
        }
    }
});

New code:

const scheduler = new SchedulerPro({
    project : {
        transport : {
            load : {
                credentials : 'include'
            }
        }
    }
});

Scheduler Pro v6.0.2

TimelineHistogram, ResourceHistogram and ResourceUtilization classes getRectClass config is deprecated

TimelineHistogram class getRectClass config is deprecated in favor of new getBarClass config to make naming more consistent. The old config is still there but will be eliminated in v7.0.0 release so please make sure you code is updated respectively.

Old code:

new ResourceHistogram({
    getRectClass : () => {
        ...
    }
})

New code:

new ResourceHistogram({
    getBarClass : () => {
        ...
    }
})

Scheduler Pro v6.2.0

EventColorPicker record config is deprecated

The record config of EventColorPicker has been deprecated in favor of the new records config, which allows changing the color property for multiple selected records. The old record config is still there, but it will be removed in the v7.0.0 release. Please update your code accordingly.

Old code:

new EventColorPicker({
    record : firstEvent
})

New code:

new EventColorPicker({
    records : [firstEvent]
})

AjaxHelper.fetch credentials change

The AjaxHelper.fetch() utility function is used by AjaxStore and ProjectModel to fetch data from the server. Previously it by default used the credentials: 'include' option, which meant that cookies were always sent with the request. To better match the default behavior of the native fetch API, our default value has been removed (thus it instead uses 'same-origin', which is the native default). If you want to restore the old behavior, you can do so using AjaxHelper.DEFAULT_FETCH_OPTIONS:

Old code

new ProjectModel({
    loadUrl  : 'load.php',
    autoLoad : true
})

New code

AjaxHelper.DEFAULT_FETCH_OPTIONS = { credentials : 'include' };

new ProjectModel({
    loadUrl  : 'load.php',
    autoLoad : true
})

Scheduler Pro v6.3.0

Naming simplification for project data properties

The ProjectModel can consume inline data for the different sorts of entities it supports: events, resources, assignments, dependencies, time ranges, resource time ranges and calendars.

In the past, the configs and properties related to this has been named according to [entityName]Data: eventsData, resourcesData, assignmentsData, dependenciesData, timeRangesData, resourcetimeRangesData and calendarsData.

This has been simplified to only [entityName]: events, resources, assignments, dependencies, timeRanges, resourceTimeRanges and calendars.

The old properties are still available but are marked as deprecated and will be removed in a future release. We recommend you update the names used in your code to avoid breakage later.

Old code

const scheduler = new SchedulerPro({
    project : {
        eventsData : [ ... ],
        resourcesData : [ ... ],
        assignmentsData : [ ... ]
    }
})

New code

const scheduler = new SchedulerPro({
    project : {
        events : [ ... ],
        resources : [ ... ],
        assignments : [ ... ]
    }
})

This change also applies to APIs that get or set the data on the ProjectModel, such as inlineData, and json. For example:

Old code

const { inlineData } = scheduler.project;

// inlineData would previously have `eventsData`, `resourcesData` etc. properties

New code

const { inlineData } = scheduler.project;

// inlineData now has `events`, `resources` etc. properties. 
// Note that the old properties are still included too

Re-enabled early rendering for projects loaded using the CRUD manager

When using early rendering (the default, tasks are rendered before scheduling calculations take place), we did not actually render early when loading data using the projects CRUD manager functionality. This was an oversight when we added support for project settings to the CRUD manager a while back.

This has now been fixed, and early rendering is once again enabled for projects loaded using the CRUD manager. As a result, any renderers you have configured (e.g. for tasks, baselines etc.) might now be called earlier than before, and with unscheduled data. If you are supplying incomplete task data (e.g. without one of startDate, endDate, duration), you might need to adjust your renderers to handle this correctly.

Old code

const scheduler = new SchedulerPro({
    project : {
        loadUrl : '/api/projects',
        autoLoad : true
    },

    eventRenderer({ eventRecord }) {
        // If endDate was not passed in the data, it might be 
        // null here on first call with early rendering
        if (eventRecord.endDate.getTime() < someTimeStamp) {
            return 'This event is before some time';
        } 
        return 'This event is after some time';
    }
});

New code

const scheduler = new SchedulerPro({
    project : {
        loadUrl : '/api/projects',
        autoLoad : true
    },

    eventRenderer({ eventRecord }) {
        if (!eventRecord.endDate) {
            // Handle case where called before scheduling calculations
            return 'This event has no end date yet';
        }
        if (eventRecord.endDate.getTime() < someTimeStamp) {
            return 'This event is before some time';
        } 
        return 'This event is after some time';
    }
});

Contents