v7.3.0
SupportExamplesFree Trial

Upgrade guides for Gantt v4.0.0+

Gantt v4.0.0

Be sure to also check out the news in Grid, Scheduler and Scheduler Pro.

Version in line with other Bryntum products

The version of Gantt was bumped from 2.0 -> 4.0 to bring it in line with Grid, Scheduler, Scheduler Pro and Calendar. This will make it easier to determine which versions are compatible with each other.

Calendar changes

hoursPerDay, daysPerWeek and daysPerMonth fields has been moved from CalendarModel to the ProjectModel class. Loading the fields from the project calendar is still supported for backward compatibility. That support will be kept for few next releases and will be dropped for good after. Please take care of changing your application code accordingly.

  • Old CrudManager load response:
{
  "success": true,
  "project": {
    "calendar": 123,
    "..." : "..."
  },
  "calendars": {
    "rows": [
      {
        "id": 123,
        "hoursPerDay": 24,
        "daysPerWeek": 5,
        "daysPerMonth": 20
      },
      {
        "..." : "..."
      }
    ]
  }
}
  • New CrudManager load response
{
  "success": true,
  "project": {
    "calendar": 123,
    "hoursPerDay": 24,
    "daysPerWeek": 5,
    "daysPerMonth": 20,
    "...": "..."
  },
  "calendars": {
    "rows": [
      {
        "id": 123,
        "...": "..."
      }
    ]
  }
}

And in case you need to retrieve corresponding values…

Old code: dealing with the fields:

console.log(`1 day === ${project.calendar.hoursPerDay} hours`);
console.log(`1 week === ${project.calendar.daysPerWeek} days`);
console.log(`1 month === ${project.calendar.daysPerMonth} days`);

New code:

console.log(`1 day === ${project.hoursPerDay} hours`);
console.log(`1 week === ${project.daysPerWeek} days`);
console.log(`1 month === ${project.daysPerMonth} days`);

Task calendar field change

Since 4.0.0 release task calendar field always returns the task own calendar or null in case it's not provided. To get the effective calendar used by the task please use effectiveCalendar field. It falls back to the project calendar the same way calendar field used to work.

-Old code:

console.log(`The task uses ${task.calendar.name} for scheduling`)

-New code:

console.log(`The task uses ${task.effectiveCalendar.name} for scheduling`)

Dropped support for Edge 18 and older

We are not actively removing the fixes we have in place yet, but moving forward we will no longer add new fixes for versions of Edge <= 18. If you are using an old version of Edge, we strongly encourage you to update to a new blink based version.

Existing fixes are planned to be removed in version 5.0.

New gantt.lite.umd.js bundle to use with Angular

Bryntum Gantt is delivered with a new UMD package without polyfills. This was done to avoid conflicts with any external Promise polyfills, such as ZoneAwarePromise from zone.js for Angular applications. It fixes this runtime error:

Zone.js has detected that ZoneAwarePromise (window|global).Promise has been overwritten.
Most likely cause is that a Promise polyfill has been loaded after Zone.js 
(Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)

We recommend that all your Angular applications should be upgraded to use the new gantt.lite.umd.js bundle. Also, there should be no polyfills imported in app/src/polyfills.ts after import 'zone.js/dist/zone';. We have updated all our Angular examples to use this new bundle. Make sure to update all usages of gantt.umd.js to gantt.lite.umd.js within your application to avoid Bundle included twice runtime error.

Old code:

import { Button, Fullscreen, WidgetHelper } from 'bryntum-gantt/gantt.umd.js';

New code:

import { Button, Fullscreen, WidgetHelper } from 'bryntum-gantt/gantt.lite.umd.js';

WidgetHelper and BryntumWidgetAdapter

Registration of Widget classes for subsequent resolution through the type property of config objects has been simplified. The "Adapter" concept has been removed. Widget classes now register themselves with the Widget base class which is where they can also be looked up. When creating a custom widget, implement the static get type property to return the type name. And at the end simply call MyWidgetClass.initClass() to have the new Widget class register itself.

Old code:

class MyWidget extends Widget {

}

BryntumWidgetAdapterRegister.register('mywidget', MyWidget);

New code:

class MyWidget extends Widget {
    static get type() {
        return 'mywidget';
    }
}

MyWidget.initClass();

Fewer widgets are auto imported with the removal of the Adapter which imported a base set of Widgets. This means that when not using a bundle, application code must import the widgets it uses. It also means that custom builds may be smaller by including only what is used.

If your code previously had:

import 'lib/Core/adapter/widget/BryntumWidgetAdapter.js';
import WidgetHelper from 'lib/Core/helper/WidgetHelper.js';

WidgetHelper.append([
    {
        type : 'button',
        text : 'Click'
    }
], /*...*/);

It should now instead not import the adapter, and instead directly import the button:

import WidgetHelper from 'lib/Core/helper/WidgetHelper.js';
import 'lib/Core/widget/Button.js';

WidgetHelper.append([
    {
        type : 'button',
        text : 'Click'
    }
], /*...*/);

Model Field Inheritance

Fields defined in a derived class Model that coincide by name with a field declared in a super class will now only override those field config properties specified by the derived class. This allows derived classes to adjust a field definition in one way, say to change the default value and still inherit other field properties, such as a convert function.

For example:

    class ModelOne extends Model {
    static get fields() {
        return [
            { name : 'barcode', convert : v => String(v) }
        ];
    }
}

class ModelTwo extends ModelOne {
    static get fields() {
        return [
            { name : 'barcode', defaultValue : 'ABC123' }
        ];
    }
}

In previous releases, ModelTwo would have had to redefine the convert config for the barcode field.

Scheduling Engine changes

The Gantt Scheduling Engine has been seriously refactored which allowed to reduce memory usage and improve performance when dealing with big datasets. The new Engine also provides more robust protection from cycles of the graph entries.

There are few noticeable API changes in that version:

  1. project.propagate method has been renamed to project.commitAsync (there is also a synchronous version of it project.commit). Old name is still supported till the next major release so please change your code accordingly.
  2. The Engine now commits changes automatically and asynchronously, so calling project.commitAsync is not really needed unless you need to get up-to-date consistent results:
// move predecessor task
predecessor.startDate = new Date(2020, 8, 1)

// let's trigger propagation and wait till it's done
await project.commitAsync()

// now we know how that change affected the task successor
console.log("Successor moved to: " + successor.startDate)

Changed event triggering timing

The stores that are part of the project (EventStore, ResourceStore, AssignmentStore and DependencyStore) has had the timing of their event triggering for certain events modified. The change was made to assure async date calculations are finished when the event is triggered. This affects the following events:

  • add
  • remove
  • removeAll
  • change
  • refresh

This change should lead to better backward compatibility with the old Scheduler. Consider the following scenario:

const scheduler = new Scheduler({
    events : [/*...*/],

    listeners : {
        add({ records }) {
            console.assert(records[0].endDate)
        }
    }
});

scheduler.eventStore.add({ startDate : '2020-09-09', duration : 1 });

Without the change, the add event would be triggered immediately on the call to add(). Since date calculations are async, the endDate would not yet be available.

With the change, the event is triggered after calculations has finished, making endDate available in the listener.

It is still possible to catch the events at the earlier stage, in case you do not care about waiting for data to be in a calculated state. To achieve that, listen for addBeforeCommit, removeBeforeCommit and so on instead.

Renamed CSS themes

The Default, Light and Dark themes were renamed to Classic, Classic-Light and Classic-Dark. This change highlights the fact that they are variations of the same theme, and that it is not the default theme (Stockholm is our default theme since version 2.0).

If you are using one of these themes, you will have to adjust your css import to match the new name.

Old code:

<link rel="stylesheet" href="build/grid.dark.css" id="bryntum-theme">

New code:

<link rel="stylesheet" href="build/grid.classic-dark.css" id="bryntum-theme">

If you have theme specific selectors in your code/CSS you have to adjust those also:

Old code:

.b-theme-dark {
. . .
}

New code:

.b-theme-classic-dark {
. . .
}

TaskEditor configs changes

tabsConfig and extraItems configs are deprecated and will be removed in version 5.0. TaskEditor tabs and widgets in the tabs are configured in a single items config. Please check out our new Customization / TaskEdit guide for details.

Old code:

const gantt = new Gantt({
    features : {
        taskEdit : {
            editorConfig : {
                extraItems : {
                    generaltab : [
                        { type : 'button', text : 'New Button' }
                    ]
                }
            },
            tabsConfig   : {
                generaltab : { title : 'Common' },
                notestab   : false,
                filestab   : { type : 'custom_filestab' }
            }
        }
    }
});

New code:

const gantt = new Gantt({
    features : {
        taskEdit : {
            items : {
                generalTab : {
                    title : 'Common',
                    items : {
                        newButton : { type : 'button', text : 'New Button' }
                    }
                },
                notesTab   : false,
                filesTab   : { type : 'custom_filestab' }
            }
        }
    }
});

Context menu

Menu features renamed

All menu features have had the word "Context" removed from their names, to follow the same naming scheme in all products. TaskContextMenu is now called TaskMenu and so on.

Task menu for cells

Task context menu is shown on cell click since cells are parts of a task in Gantt. Cell menu items are handled by the TaskMenu feature. The CellMenu feature is no longer supported when the TaskMenu feature is enabled:

Old code:

const gantt = new Gantt({
    features : {
        contextMenu : {
            cellItems : [
                { text : 'My cell item' }
            ]
        },

        taskContextMenu : {
            items : {
                myTaskItem : { text : 'My task item' }
            }
        }
    }
});

New code:

const gantt = new Gantt({
    features : {
        taskMenu : {
            items : {
                myTaskItem : { text : 'My task item' },
                myCellItem : { text : 'My cell item' }
            },

            processItems({ items, column }) {
                if (!column || column.type === 'timeAxis') {
                    items.myCellItem = false;
                }
            }
        }
    }
});

But since task element and cells refer to the same TaskRecord, it makes sense to have similar items in both cases. If you need a column specific item you can still use cellMenuItems column config:

const gantt = new Gantt({
    columns : [
        {
            type          : 'name',
            field         : 'name',
            cellMenuItems : {
                columnSpecificItem : { text : 'Column specific cell item' }
            }
        }
    ],

    features : {
        taskMenu : {
            items : {
                myTaskItem : { text : 'My task item' }
            }
        }
    }
});

CellMenu feature can be used if TaskMenu feature is disabled:

const gantt = new Gantt({
    features : {
        taskMenu : false,
        cellMenu : {
            items : {
                myCellItem : { text : 'My cell item' }
            }
        }
    },
});

Context menu events

Some of the events triggered by TaskContextMenu was renamed to match the new name of the feature:

  • taskContextMenuBeforeShow -> taskMenuBeforeShow;
  • taskContextMenuShow -> taskMenuShow;
  • taskContextMenuItem -> taskMenuItem;

For example:

Old code:

const scheduler = new Scheduler({
    listeners : {
        taskContextMenuBeforeShow : () => {/*...*/},
        taskContextMenuShow : () => {/*...*/},
        taskContextMenuItem : () => {/*...*/}
    }
});

New code:

const scheduler = new Scheduler({
    listeners : {
        taskMenuBeforeShow : () => {/*...*/},
        taskMenuShow : () => {/*...*/},
        taskMenuItem : () => {/*...*/}
    }
});

Gantt v4.0.1

AssignmentField picker now is a Grid, previously it contained a Grid

The picker of the AssignmentField was promoted to be an AssignmentGrid. This means you no longer have to configure the grid using the grid config, instead you simply configure the field picker directly.

Old code:

const gantt = new Gantt({
    appendTo : 'container',
    columns  : [
        { type : 'name', field : 'name', text : 'Name', width : 250 },
        {
            type        : 'resourceassignment',
            width       : 250,
            showAvatars : true,
            editor      : {
                type   : 'assignmentfield',
                picker : {
                    grid : {
                        features : {
                            /*...*/
                        },
                        height   : 350,
                        width    : 450,
                        columns  : [
                            /*...*/
                        ]
                    }
                }
            }
        }
    ]
});

New code:

const gantt = new Gantt({
    appendTo : 'container',
    columns  : [
        { type : 'name', field : 'name', text : 'Name', width : 250 },
        {
            type        : 'resourceassignment',
            width       : 250,
            showAvatars : true,
            editor      : {
                type   : 'assignmentfield',
                picker : {
                    // Grid configs go here
                    height   : 350,
                    width    : 450,
                    features : {
                        /*...*/
                    },
                    columns  : [
                        // Additional columns go here
                    ]
                }
            }
        }
    ]
});

Gantt v4.0.8

Added short responses support to Crud Manager

Crud Manager default behaviour has been changed to allow short sync responses that include only server-side changes. Previously it was mandatory to mention all updated and removed records in the response to confirm the changes are applied. With this release the Crud Manager automatically confirms changes of all updated/removed records mentioned in the corresponding sync request. If your code relies on the old behavior please use supportShortSyncResponse to enable it back. To revert to the old behavior please set supportShortSyncResponse config to false:

new Gantt({
    /*...*/
    project : {
        // disable simlified responses support
        supportShortSyncResponse : false,
        /*...*/
    }
});

Gantt v4.1.0

Be sure to also check out the news in Grid, Scheduler and SchedulerPro.

Dropped support for RequireJS

In version 4.1.0 we have removed the RequireJS demo from the project, since it is an outdated technology. We instead recommend using modern ES6 module imports which is supported in all modern browsers (Chrome, FireFox, Safari, Edge (chromium)).

You could easily upgrade old application code to use new technology.

Old code:

index.html

<script data-main="scripts/app" src="scripts/require.js"></script>

scripts/app.js

requirejs.config({
    paths : {
        gantt : '../../../build/gantt.umd'
    }
});

requirejs(['gantt'], function(bryntum) {
    new bryntum.Gantt({
        // config here
    });
});

New code:

index.html

<script type="module" src="scripts/app.js"></script>

scripts/app.js

import { Gantt } from '../../../build/gantt.module.js';

new Gantt({
    // config here
});

ProjectModel API changes

ProjectModel commit was deprecated in favor of acceptChanges. ProjectModel commitCrudStores was deprecated in favor of acceptChanges. ProjectModel reject was deprecated in favor of revertChanges. ProjectModel rejectCrudStores was deprecated in favor of revertChanges.

Old code:

gantt.project.commit();
gantt.project.commitCrudStores();
gantt.project.reject();
gantt.project.rejectCrudStores();

New code:

gantt.project.acceptChanges();
gantt.project.revertChanges();

DependencyCreation events

DependencyCreation events were all missing useful params about the state of the creation state as you drag and drop to setup a link between two events. The data param is now deprecated and will be removed in a future major version.

Old code:

gantt.on({
    beforedependencycreatedrag({ data }) {
        // Use undocumented params in data
    }
});

New code:

gantt.on({
    dependencycreatedrop({ source, target, dependency }) {
        // Documented access to source task, target task, and the created dependency
    }
});

Frameworks examples

Frameworks examples were moved to examples/frameworks folder:

Framework Examples folder
Angular examples/frameworks/angular
React examples/frameworks/react
Vue v2 examples/frameworks/vue
Vue v3 examples/frameworks/vue-3

Gantt v4.1.1

Wrapper dependencies

In order to support installing trial package alias for wrappers they now require adding @bryntum/gantt dependency to application's package.json file.

Example for licensed version for Angular framework:

{
  "dependencies": {
    "@bryntum/gantt": "4.1.1",
    "@bryntum/gantt-angular": "4.1.1"
  }
}

Example for trial version for Angular framework:

{
  "dependencies": {
    "@bryntum/gantt": "npm:@bryntum/gantt-trial@4.1.1",
    "@bryntum/gantt-angular": "4.1.1"
  }
}

Gantt v4.1.2

Lag unit defaults

When editing predecessors or successors, if not providing a lag unit, the task durationUnit is now used (previously used the unit from the current time axis which led to weird behaviors).

Gantt v4.1.3

Task editor width locale change

The width of the task editor is now defined in Scheduler Pro's locale instead of in Gantt's. With this move, the key was renamed and if you are using a custom locale based width you have to update your locale:

Old code:

TaskEditor : {
    editorWidth : '60em'
}

New code:

GanttTaskEditor : {
    editorWidth : '60em'
}

TaskDrag dragTipTemplate renamed to tooltipTemplate

Simple renaming in the TaskDrag feature, see this demonstrated in the updated "tooltips" demo:

Old code:

features : {
    taskDrag : {
        dragTipTemplate : ({ taskRecord, startDate }) => {
            return 'foo'
        }
    }
}

New code:

features : {
    taskDrag : {
        tooltipTemplate : ({ taskRecord, startDate }) => {
            return 'foo'
        }
    }
}

TaskDrag dragTipTemplate / tooltipTemplate deprecated params

The startText, endText, startClockHtml, endClockHtml, dragData params of the dragTipTemplate / tooltipTemplate have been deprecated and will be removed in 5.0.

Gantt v4.1.4

Task milestones CSS classes changed

CSS classes for baseline elements changed slightly so make sure to revise any styling you have used based on b-baseline-milestone CSS class (removed). Each baseline task now has b-task-baseline and milestones have b-task-baseline-milestone.

Gantt v4.1.5

beforeTaskEditShow listeners can now be used to change/apply initial values

This release has changes to the beforeTaskEditShow event that might affect the logic of your app:

  1. It is now possible to assign values to task editor fields using a beforeTaskEditShow listener.
  2. Values that are programmatically applied to the fields using beforeTaskEditShow and later will now be applied to the task record (previously only user-typed changes were applied).
  3. If a field is added to a task editor in a beforeTaskEditShow listener, make sure to apply an initial value for it since default values are applied at an earlier stage.

Gantt v4.2.0

TaskDragCreate

The TaskDragCreate feature now operates on a live instance of a TaskModel, updating its dates as you drag as opposed to the previous behaviour which updated then when the operation ended.

Dependencies can now be created by dropping anywhere on the task bar element

In previous versions you had to hit a specific side circle element to define it. The new behavior allows you to setup a dependency by dropping anywhere on the task bar. This creates a dependency with the default type, as defined by the defaultValue of the DependencyModel type field.

If you prefer the old behavior, simply set allowDropOnEventBar to false on the feature config:

const gantt = new Gantt({
    features : {
        dependencies : {
            allowDropOnEventBar : false
        }
    }
});

Gantt v4.3.0

Buttons with menus shows a caret down arrow icon

Button has a new config menuIcon that specifies an icon to show when the button has a menu. It defaults to show a caret down arrow icon. If you are using buttons with menus and want to get rid of this icon (for example if you are already displaying a hamburger icon), set menuIcon : null on the button.

Old code:

const button = new Button({
    icon : 'fa fa-bars',
    menu : [
        { text : 'First item'},
        { text : 'Second item'}
    ]
})

New code:

const button = new Button({
    icon     : 'fa fa-bars',
    menuIcon : null,
    menu     : [
        { text : 'First item'},
        { text : 'Second item'}
    ]
})

Buttons menuIconCls deprecated

Buttons menuIconCls was deprecated in favor of the menuIcon config mentioned above. It will be removed in 5.0. Please replace any usages:

Old code:

const button = new Button({
    menuIconCls : 'fa fa-bars',
    menu        : [
        { text : 'First item'},
        { text : 'Second item'}
    ]
})

New code:

const button = new Button({
    menuIcon : 'fa fa-bars',
    menu     : [
        { text : 'First item'},
        { text : 'Second item'}
    ]
})

Gantt v4.3.7

PdfExport feature

beforeExport Gantt event has been renamed to beforePdfExport and export event has been renamed to pdfExport respectively. Please modify your code to match the new names.

Old code:

gantt.on({
    beforeExport({ config }) { /*...*/ },

    export({ config }) { /*...*/ }
})

New code:

gantt.on({
    beforePdfExport({ config }) {
        const { orientation } = config;
        /*...*/
    },

    pdfExport({ config }) {
        const { orientation } = config;
        /*...*/
    }
});

Also the events signature had deprecated properties copied from config section which have been removed in this release.

Contents