Our pure JavaScript Scheduler component


Post by Takaner »

Usign: Bryntum Scheduler v3.0.0
Browser: Chrome 79.0.3945.130

I'm trying to add recurring time ranges linked to a specific resource.
Related to this post => viewtopic.php?f=44&t=12929
	this.schedulerEngine.features.timeRanges.store.data = [
          {
            resourceId: "014702580369",
            startDate: friday,
            duration: 2,
            durationUnit: "day",
            cls: "weekend",
            recurrenceRule: "FREQ=WEEKLY;"
          }
        ];
Right now it's rendering this weekly range - recurring correctly - for every row/resource but what I need is to render a diferent range for any of the rows.
I've tried adding this resourceId attribute, but notinhg has changed.

Post by mats »

Could you please post a full test case that we can run / debug?

Post by Takaner »

mats wrote: Tue Jan 21, 2020 11:20 am Could you please post a full test case that we can run / debug?
I've been using one of your demo examples: https://www.bryntum.com/examples/scheduler/timeranges/
Using this code:
import { DateHelper, WidgetHelper, Scheduler, RecurringTimeSpan, TimeSpan, RecurringTimeSpansMixin, Store } from '../../build/scheduler.module.js?438678';
import shared from '../_shared/shared.module.js?438678';


let scheduler;

//region Widgets

WidgetHelper.append([
    {
        type  : 'button',
        icon  : 'b-icon b-icon-add',
        color : 'b-orange b-raised',
        text  : 'Add range',
        onAction({ source : button }) {
            scheduler.features.timeRanges.store.add({
                name         : 'New time range',
                startDate    : DateHelper.add(scheduler.startDate, 8, 'h'),
                duration     : 1,
                durationUnit : 'h'
            });

            button.disable();
        }
    },
    {
        type  : 'button',
        color : 'b-orange b-raised',
        text  : 'Add recurring time ranges',
        onAction() {
            scheduler.features.timeRanges.store.data = [
                    {
            resourceId: 'a',
            startDate: new Date(2019, 1, 7, 8),             
            duration: 2,
            durationUnit: "day",
            style:'background: #eee',
            recurrenceRule: "FREQ=WEEKLY"
          }
        ];


        }
    },
    {
        type    : 'button',
        icon    : 'b-icon b-fa b-fa-angle-left',
        color   : 'b-blue b-raised',
        tooltip : 'View previous day',
        onAction() {
            scheduler.shiftPrevious();
        }
    },
    {
        type  : 'button',
        ref   : 'todayButton',
        color : 'b-blue b-raised',
        text  : 'Today',
        onAction() {
            const today = DateHelper.clearTime(new Date());
            today.setHours(5);
            scheduler.setTimeSpan(today, DateHelper.add(today, 18, 'hour'));
        }
    },
    {
        type    : 'button',
        icon    : 'b-icon b-fa b-fa-angle-right',
        color   : 'b-blue b-raised',
        tooltip : 'View next day',
        onAction() {
            scheduler.shiftNext();
        }
    }
], { insertFirst : document.getElementById('tools') || document.body });

//endregion

class MyTimeRange extends RecurringTimeSpan(TimeSpan) {


    // WORKAROUND: This method override won't be needed after the next release
};


class MyStore extends RecurringTimeSpansMixin(Store) {


    static get defaultConfig() {
        return {
            modelClass : MyTimeRange,
            storeId    : 'timeRanges'
        };
    }


    construct(config) {
        super.construct(config, true);
        // setup recurrence support
        this.setupRecurringTimeSpans();
    }
};

const timeRangesStore = new MyStore();

scheduler = new Scheduler({
    adopt      : 'container',
    minHeight  : '20em',
    eventStyle : 'colored',

    features : {
        stripe     : true,

        recurringTimeSpans: {
            store: timeRangesStore
          },

        timeRanges : {
            enableResizing      : true,
            showCurrentTimeLine : true,
            showHeaderElements  : true,
            store: timeRangesStore 
        },




    },

    columns : [
        { type : 'resourceInfo', imagePath : '../_shared/images/users/', text : 'Staff', field : 'name', width : '10em' }
    ],

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

    barMargin : 5,

    startDate  : new Date(2019, 1, 7, 8),
    endDate    : new Date(2020, 1, 9, 18),
    viewPreset : 'weekAndMonth',

    // Specialized body template with header and footer
    eventBodyTemplate : data => `
        <div class="b-sch-event-header">${data.headerText}</div>
        <div class="b-sch-event-footer">${data.footerText}</div>
    `,

    eventRenderer({ eventRecord })  {
        return {
            headerText : DateHelper.format(eventRecord.startDate, this.displayDateFormat),
            footerText : eventRecord.name || ''
        };
    }
});
Then you should press the 'Add recurring time ranges' button.

Post by Takaner »

mats wrote: Tue Jan 21, 2020 11:20 am Could you please post a full test case that we can run / debug?
Is my last reply not enough? I thought I'd be representative enough.
Any workarounds?

Thanks in advance

Post by arcady »

As far as I understand you want to define ranges for specific resources.

That's another feature, not time ranges but resource time ranges (here is its demo: https://www.bryntum.com/examples/scheduler/resourcetimeranges/).

So you repeat modifications (that we did for time ranges store/model) to add recurrence support to resource time ranges feature data model:
// Make a new model extending default ResourceTimeRangeModel w/ RecurringTimeSpan mixin
class MyResourceTimeRange extends RecurringTimeSpan(ResourceTimeRangeModel) {};

// Make a new store extending default ResourceTimeRangeStore w/ RecurringTimeSpansMixin mixin
class MyResourceTimeRangeStore extends RecurringTimeSpansMixin(ResourceTimeRangeStore) {
    static get defaultConfig() {
        return {
            modelClass : MyResourceTimeRange,
            storeId    : 'resourceTimeRanges'
        };
    }

    construct(config) {
        super.construct(config, true);
        // setup recurrence support
        this.setupRecurringTimeSpans();
    }
};

// instantiate new improved store class
const resourceTimeRangesStore = new MyResourceTimeRangeStore();
Now you need Scheduler to track that store ..to populate occurrences of recurring records. This job is done by https://www.bryntum.com/docs/scheduler/#Scheduler/feature/RecurringTimeSpans feature. But you already use it to handle time ranges store and unfortunately RecurringTimeSpans yet supports tracking of a single store only (we have a ticket to improve that but it's not done yet).

As a workaround let's simply make a new feature for the Scheduler:
// Make a new feature to handle our new store
class MyRecurringTimeSpans extends RecurringTimeSpans {
    static get $name() {
        return 'MyRecurringTimeSpans';
    }
};

// let's register the feature so scheduler was aware of it
GridFeatureManager.registerFeature(MyRecurringTimeSpans, false, 'Scheduler');
And now we simply add missing features to the Scheduler:
    features : {
        ...

        myRecurringTimeSpans : {
            store : resourceTimeRangesStore
        },
        
        resourceTimeRanges : {
            store : resourceTimeRangesStore
        }
    },

Post by Takaner »

arcady wrote: Mon Jan 27, 2020 2:26 pm As far as I understand you want to define ranges for specific resources.

That's another feature, not time ranges but resource time ranges (here is its demo: https://www.bryntum.com/examples/scheduler/resourcetimeranges/).

So you repeat modifications (that we did for time ranges store/model) to add recurrence support to resource time ranges feature data model:
// Make a new model extending default ResourceTimeRangeModel w/ RecurringTimeSpan mixin
class MyResourceTimeRange extends RecurringTimeSpan(ResourceTimeRangeModel) {};

// Make a new store extending default ResourceTimeRangeStore w/ RecurringTimeSpansMixin mixin
class MyResourceTimeRangeStore extends RecurringTimeSpansMixin(ResourceTimeRangeStore) {
    static get defaultConfig() {
        return {
            modelClass : MyResourceTimeRange,
            storeId    : 'resourceTimeRanges'
        };
    }

    construct(config) {
        super.construct(config, true);
        // setup recurrence support
        this.setupRecurringTimeSpans();
    }
};

// instantiate new improved store class
const resourceTimeRangesStore = new MyResourceTimeRangeStore();
Now you need Scheduler to track that store ..to populate occurrences of recurring records. This job is done by https://www.bryntum.com/docs/scheduler/#Scheduler/feature/RecurringTimeSpans feature. But you already use it to handle time ranges store and unfortunately RecurringTimeSpans yet supports tracking of a single store only (we have a ticket to improve that but it's not done yet).

As a workaround let's simply make a new feature for the Scheduler:
// Make a new feature to handle our new store
class MyRecurringTimeSpans extends RecurringTimeSpans {
    static get $name() {
        return 'MyRecurringTimeSpans';
    }
};

// let's register the feature so scheduler was aware of it
GridFeatureManager.registerFeature(MyRecurringTimeSpans, false, 'Scheduler');
And now we simply add missing features to the Scheduler:
    features : {
        ...

        myRecurringTimeSpans : {
            store : resourceTimeRangesStore
        },
        
        resourceTimeRanges : {
            store : resourceTimeRangesStore
        }
    },
Thank you very much!
It worked perfectly! :D

Post by jandresampaio »

Scheduler.feature.RecurringTimeSpans is no longer available. Where do we import it from?
I tried to rename it to RecurringTimeSpan (singular) but an error occurs in your demo:

RecurringResourcesTimespan.PNG
RecurringResourcesTimespan.PNG (140.44 KiB) Viewed 2039 times

Post by arcady »

Hello,

There were few quite major changes in version 4.0 and one of them was recurring events refactoring. We decided that stores should not keep occurrences. It's mentioned in 4.0 upgrade guide.
The feature class is no longer needed so it was removed.

Yet I've just checked and found out that resourceTimeRanges feature for some reason doesn't work with recurring ranges properly in 4.x.
I'll check what happens today and come back with results ASAP. Here is a ticket to track the problem: https://github.com/bryntum/support/issues/1907
Thank you for the feedback!


Post by arcady »

The issue is resolved now so tomorrow's nightly build will have the fixed code.

The up to date code will look like this:

// 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();

const scheduler = new Scheduler({
    ...
    features : {
        resourceTimeRanges : true
    },

    // store for "resourceTimeRanges" feature
    resourceTimeRangeStore,
    ...

I've actually added this code to examples/resourcetimeranges demo to demonstrate a recurring time range. So check it out in the nightly build.

Also FYI I've made a ticket to support recurring in that feature store & model out-of-the box: https://github.com/bryntum/support/issues/1919
When the ticket is done the code applying mixins to store and model classes won't be needed anymore. The classes will have them applied by default.


Post by jandresampaio »

Thanks for the help. It worked.
Related to this feature...We're using it to be able to display each resource working days and hours. Some users might work on sundays, for example. I've seen the working time example but doesn't seem to fit our requirements for a specific resource calendar.

Are we in the right direction or is there other feature that could help us display the working time (or calendar) for each resource?

Thank you.


Post Reply