Our pure JavaScript Scheduler component


Post by alex.l »

Hi striker,

Thank you for the info and glad to hear you have workaround for now!

All the best,
Alex

All the best,
Alex


Post by striker »

When 4.1.3 version with fix will be released? I can't find any information on forum and on customerzone is nothing showed.


Post by mats »

Customer zone only shows released versions. We aim to release patch releases every 2-4 weeks.


Post by gorakh.nath »

@alex, I am getting the same error in react. I imported BryntumSchedulerPro from schedulerpro-react.
import { BryntumSchedulerPro } from '@bryntum/schedulerpro-react'
I also have the same scenario in which data is loading after scheduler has been initialized, How to resolve this issue because we cant hold the ui till data load we have to render scheduler before data comes from server call.

<BryntumSchedulerPro
          ref = {scheduler}
          autoHeight = {false}
          allowOverlap = {isAllowOverlap}
          zoomOnMouseWheel={false}
          zoomOnTimeAxisDoubleClick={false}
          viewPreset = {getViewPreset(timelineView, entityConfig)}
          tbar = {
            [
              {
                type: 'combo',
                value: timelineView,
                editable: false,
                ref: 'viewPresetCombo',
                cls: 'select-view',
                listCls: 'list-items',
                listeners: { change: viewPresetHandler },
                items: getTimeLineViewList()
              },
              {
                type: 'dateField',
                editable: false,
                cls: 'date-field',
                onChange ({ value, userAction }) {
                  if(hasSchedulerInstance() && userAction) {
                    limitMonthRange(value);
                    const diff = DateHelper.diff(
                      DateHelper.clearTime(getSchedulerInstance().startDate),
                      value,
                      'days'
                    );
                    getSchedulerInstance().startDate = DateHelper.add(
                      getSchedulerInstance().startDate,
                      diff,
                      'days'
                    );
                    getSchedulerInstance().scrollToDate(value, {
                      block: getViewPosition()
                    });
                    checkForDataFetch();
                  }
                },
                listeners: {
                  trigger: onDatePickerLoad
                },
                ref: 'selectDate'
              },
              {
                type: 'button',
                text: 'L{todayText}',
                onClick () {
                  const today = DateHelper.clearTime(new Date());
                  if(hasSchedulerInstance()) {
                    limitMonthRange(today);
                    const diff = DateHelper.diff(
                      DateHelper.clearTime(getSchedulerInstance().startDate),
                      today,
                      'days'
                    );
                    getSchedulerInstance().startDate = DateHelper.add(
                      getSchedulerInstance().startDate,
                      diff,
                      'days'
                    );
                    getSchedulerInstance().scrollToDate(today, {
                      block: getViewPosition()
                    });
                    checkForDataFetch();
                  }
                },
                cls: 'btn-today'
              },
              {
                type: 'button',
                icon: 'b-fa-angle-left',
                cls: 'btn-prev',
                onClick () {
                  if(hasSchedulerInstance()) {
                    getSchedulerInstance().shiftPrevious();
                    checkForDataFetch(true);
                  }
                }
              },
              {
                type: 'button',
                icon: 'b-fa-angle-right',
                cls: 'btn-next',
                onClick () {
                  if(hasSchedulerInstance()) {
                    getSchedulerInstance().shiftNext();
                    checkForDataFetch(true);
                  }
                }
              },
              '->',
              {
                type: 'textfield',
                ref: 'filterByName',
                placeholder: 'L{searchPlaceholder}',
                cls: 'input-search',
                clearable: true,
                keyStrokeChangeDelay: 100,
                triggers: {
                  filter: {
                    align: 'start',
                    cls: 'b-fa b-fa-search'
                  }
                },
                listeners: { change: searchHandler }
              }
            ]
          }
          resources = {data.resources || []}
          timeRanges={data.timeRanges || []}
          project ={ {
            timeRangeStore: timeRangeStores,
            resourceTimeRangeStore: resourceTimeRangeStore,
            calendar: 'weekend',
            calendarsData: data.calendars

      }}
      events = {data.events || []}
/>

Post by mats »

@gorakh: Please don't double post your questions


Post by striker »

Hello, I want to ask will this problem be solved in 4.2.4?
Greetings


Post by mats »

Ticket is in review phase, so likely it'll be in 4.2.5


Post by saki »

This issue has been resolved so the fix will be available in tomorrow's nightlies and then in 4.2.4.


Post by striker »

So....

this.schedulerInstance.resourceTimeRangeStore = new ResourceTimeRangeStore();

is causing following error:

error.png
error.png (25.48 KiB) Viewed 669 times

So I tried

this.schedulerInstance.project.resourceTimeRangeStore = new ResourceTimeRangeStore();

with enabled resourceTimeRanges feature in scheduler config and is working.

But...
I tried to load at runtime my time ranges by this code:

        (<ResourceTimeRangeStore>this.schedulerInstance.resourceTimeRangeStore).add({
          id: i++,
          resourceId: ganttResource.id,
          startDate: workingInterval.startDate,
          endDate: workingInterval.endDate,
          timeRangeColor: 'red'
        });
 
error2.png
error2.png (49.16 KiB) Viewed 669 times

And I can't see time ranges. I think I'm doing everything good.

You can reproduce this by modyfing this example:
https://www.bryntum.com/examples/examples-scheduler/resourcetimeranges/

by code:

import { Scheduler, DateHelper, ResourceTimeRangeModel, RecurringTimeSpan, RecurringTimeSpansMixin, ResourceTimeRangeStore } from '../../build/schedulerpro.module.js';
import shared from '../_shared/shared.module.js';
/* eslint-disable no-unused-vars */

//region Data

const resources          = [
        { id : 'r1', name : 'Mike' },
        { id : 'r2', name : 'Linda' },
        { id : 'r3', name : 'Lisa' },
        { id : 'r4', name : 'Madison' },
        { id : 'r5', name : 'Mark' },
        { id : 'r6', name : 'Kate' },
        { id : 'r7', name : 'Dan' },
        { id : 'r8', name : 'Henrik' },
        { id : 'r9', name : 'Rob' },
        { id : 'r10', name : 'Gloria' }
    ],
    events             = [
        {
            id         : 1,
            resourceId : 'r1',
            startDate  : new Date(2019, 0, 1, 8),
            endDate    : new Date(2019, 0, 1, 11),
            name       : 'Investigation',
            iconCls    : 'b-fa b-fa-search'
        }, {
            id         : 2,
            resourceId : 'r1',
            startDate  : new Date(2019, 0, 1, 13),
            endDate    : new Date(2019, 0, 1, 15),
            name       : 'Brief',
            iconCls    : 'b-fa b-fa-newspaper'
        },
        {
            id         : 3,
            resourceId : 'r2',
            startDate  : new Date(2019, 0, 1, 8),
            endDate    : new Date(2019, 0, 1, 9, 30),
            name       : 'Scrum',
            iconCls    : 'b-fa b-fa-bullhorn'
        },
        {
            id         : 4,
            resourceId : 'r3',
            startDate  : new Date(2019, 0, 1, 8),
            endDate    : new Date(2019, 0, 1, 9, 30),
            name       : 'Scrum',
            iconCls    : 'b-fa b-fa-bullhorn'
        },
        {
            id         : 5,
            resourceId : 'r4',
            startDate  : new Date(2019, 0, 1, 7),
            endDate    : new Date(2019, 0, 1, 11),
            name       : 'Meeting',
            iconCls    : 'b-fa b-fa-calendar'
        },
        {
            id         : 6,
            resourceId : 'r4',
            startDate  : new Date(2019, 0, 1, 15),
            endDate    : new Date(2019, 0, 1, 17),
            name       : 'Meeting',
            iconCls    : 'b-fa b-fa-calendar',
            eventColor : 'blue'
        },
        {
            id         : 7,
            resourceId : 'r6',
            startDate  : new Date(2019, 0, 1, 12, 30),
            endDate    : new Date(2019, 0, 1, 19),
            name       : 'Important meeting',
            iconCls    : 'b-fa b-fa-exclamation-triangle',
            eventColor : 'red'
        },
        {
            id         : 8,
            resourceId : 'r6',
            startDate  : new Date(2019, 0, 1, 9),
            endDate    : new Date(2019, 0, 1, 12),
            name       : 'Generic meeting',
            iconCls    : 'b-fa b-fa-calendar'
        },
        {
            id         : 9,
            resourceId : 'r7',
            startDate  : new Date(2019, 0, 1, 9),
            endDate    : new Date(2019, 0, 1, 11),
            name       : 'Dad\'s birthday',
            iconCls    : 'b-fa b-fa-birthday-cake',
            eventColor : 'green'
        },
        {
            id         : 10,
            resourceId : 'r9',
            startDate  : new Date(2019, 0, 1, 13),
            endDate    : new Date(2019, 0, 1, 20),
            name       : 'Golf tournament',
            iconCls    : 'b-fa b-fa-golf-ball',
            eventColor : 'green'
        }
    ],

resourceTimeRanges = [
    {
        id             : 1,
        resourceId     : 'r1',
        startDate      : '2019-01-01T11:00',
        endDate        : '2019-01-01T13:00',
        name           : 'Lunch',
        // this time range should repeat every day
        recurrenceRule : 'FREQ=DAILY'
    },
    { id : 2, resourceId : 'r8', startDate : '2019-01-01T11:00', endDate : '2019-01-01T13:00', name : 'Lunch' },
    { id : 3, resourceId : 'r9', startDate : '2019-01-01T11:00', endDate : '2019-01-01T13:00', name : 'Lunch' },
    { id : 4, resourceId : 'r10', startDate : '2019-01-01T11:00', endDate : '2019-01-01T13:00', name : 'Lunch' },
    { id : 5, resourceId : 'r3', startDate : '2019-01-01T12:00', endDate : '2019-01-01T14:00', name : 'Lunch' },
    { id : 6, resourceId : 'r4', startDate : '2019-01-01T12:00', duration : 2, durationUnit : 'h', name : 'Lunch' },
    { id : 7, resourceId : 'r2', startDate : '2019-01-01T10:00', endDate : '2019-01-01T17:00', name : 'AFK (uses timeRangeColor)', timeRangeColor : 'red' },
    { id : 8, resourceId : 'r7', startDate : '2019-01-01T12:00', endDate : '2019-01-01T18:00', name : 'Afternoon off (custom style)', style : 'background: rgba(255,165,0,.3);color : orange' },
    { id : 9, resourceId : 'r5', startDate : '2019-01-01T06:00', endDate : '2019-01-01T20:00', name : 'Parental leave (custom CSS)', cls : 'custom' }
];

// We want to use recurring time ranges (see first entry in resourceTimeRanges array above)
// so we make a special model extending standard ResourceTimeRangeModel
// with RecurringTimeSpan which adds recurrence support
class MyResourceTimeRange extends RecurringTimeSpan(ResourceTimeRangeModel) {};

// Define a new store extending standard ResourceTimeRangeStore
// with RecurringTimeSpansMixin mixin to add recurrence support to the store.
// This store will contain time ranges.
class MyResourceTimeRangeStore extends RecurringTimeSpansMixin(ResourceTimeRangeStore) {
    static get defaultConfig() {
        return {
            // use our new MyResourceTimeRange model
            modelClass : MyResourceTimeRange
        };
    }
};

// Instantiate store for resourceTimeRanges using our new classes
const resourceTimeRangeStore = new MyResourceTimeRangeStore({
    data : resourceTimeRanges
});

//endregion

let newRangeCount = 0;

const scheduler = new Scheduler({
    appendTo : 'container',

startDate         : new Date(2019, 0, 1, 6),
endDate           : new Date(2019, 0, 1, 20),
viewPreset        : 'hourAndDay',
rowHeight         : 90,
barMargin         : 3,
resourceMargin    : 25,
resourceImagePath : '../_shared/images/users/',

eventStyle : 'plain',
eventColor : 'blue',

columns : [
    { type : 'resourceInfo', text : 'Name', field : 'name', width : 130 }
],

features : {
    resourceTimeRanges : true
},

resources,
events,

tbar : [
    {
        type     : 'button',
        icon     : 'b-icon-add',
        text     : 'Add new range',
        onAction : () => {
            if (newRangeCount < 10) {
                scheduler.resourceTimeRangeStore.add({
                    name           : 'New time range',
                    startDate      : new Date(2019, 0, 1, 6),
                    duration       : 2,
                    durationUnit   : 'h',
                    timeRangeColor : 'green',
                    resourceId     : 'r' + (++newRangeCount)
                });
            }
        }
    },
    {
        type     : 'button',
        icon     : 'b-fa-clock',
        text     : 'Move lunch',
        onAction : () => {
            scheduler.resourceTimeRangeStore.forEach(range => {
                if (range.name === 'Lunch') {
                    range.startDate = DateHelper.add(range.startDate, 1, 'hour');
                }
            });
        }
    }
]
});

scheduler.project.resourceTimeRangesStore = new MyResourceTimeRangeStore();

for (const range of resourceTimeRanges) {
   scheduler.project.resourceTimeRangesStore.add(range);
}

console.log(scheduler.project.resourceTimeRangesStore);

Post by saki »

Is it somehow possible that you're still running the old version? I was trying to reproduce the first error you report in our SchedulerPro resource-histogram demo and it worked as expected. To test I've changed app.component.html to include [resourceTimeRangesFeature] = "true" (otherwise the range would not show on the screen) and app.component.ts to read:

/**
 * App component script
 */
import { AfterViewInit, Component, ViewChild } from '@angular/core';
import { BryntumResourceHistogramComponent, BryntumSchedulerProComponent } from '@bryntum/schedulerpro-angular';
import { ResourceHistogram, ResourceTimeRangeStore, SchedulerPro } from '@bryntum/schedulerpro/schedulerpro.lite.umd.js';

import { histogramConfig, schedulerProConfig } from './app.config';

@Component({
    selector    : 'app-root',
    templateUrl : './app.component.html'
})

export class AppComponent implements AfterViewInit {
    title = 'Drag between Schedulers Angular demo';
    schedulerProConfig = schedulerProConfig;
    histogramConfig = histogramConfig;

    schedulerPro: SchedulerPro;
    resourceHistogram: ResourceHistogram;

    @ViewChild(BryntumSchedulerProComponent) schedulerProComponent: BryntumSchedulerProComponent;
    @ViewChild(BryntumResourceHistogramComponent) resourceHistogramComponent: BryntumResourceHistogramComponent;

    ngAfterViewInit(): void {
        this.schedulerPro = this.schedulerProComponent.instance;
        this.resourceHistogram = this.resourceHistogramComponent.instance;
        this.resourceHistogram.addPartner(this.schedulerPro);

        this.schedulerPro.resourceTimeRangeStore = new ResourceTimeRangeStore();

        // @ts-ignore
        this.schedulerPro.resourceTimeRangeStore.add({
            id           : 1,
            name         : 'Range',
            duration     : 4,
            durationUnit : 'day',
            startDate    : '2020-05-01',
            resourceId   : 'r1'

        });
    }

    /**
     * handles clicks on toolbar checkboxes
     */
    onCheckboxAction({ source }, option: string): void {
        this.resourceHistogram[option] = source.checked;
    }

    /**
     * Handles zoom-in click event
     */
    onZoomIn(): void {
        this.schedulerPro.zoomIn();
    }

    /**
     * Handles zoom-out click event
     */
    onZoomOut(): void {
        this.schedulerPro.zoomOut();
    }
}

which results in the following (w/o any console error):

Screen Shot 2021-08-31 at 11.24.31.png
Screen Shot 2021-08-31 at 11.24.31.png (531.74 KiB) Viewed 665 times

Should you still experience problems, we need a showcase that we can run, investigate and debug.


Post Reply