Our pure JavaScript Scheduler component


Post by alexp »

Hi!
We use your great scheduler and noticed an issue in the mentioned function while updating to the newest patch 5.2.4 from 5.2.3.

To give a little background:

  • - We offer our users to control the viewport of the scheduler with a date range input: when they select a start and an end date, data is loaded from the backend only for this time range and the view should zoom and scroll to focus the user on that time frame

  • - to achieve this, we use the member zoomTo of the scheduler instance using {startDate, endDate} options.

  • - We have an e2e Cypress test that changes the date frame and checks if the new frame is visible

  • - this test failed after the update, because the zoom was not adjusted by zoomTo()

  • - it seems this issue only occurs if the scheduler have only a small horizontal width

  • - the issues does not occur for single day frames

I could reproduce this in your examples:

  • - copy these two buttons in the tbar:

        {
            type : 'button',
            text : 'zoomTo 01-01 - 01-04',
            onClick() {
                scheduler.zoomTo({startDate: new Date("2017-01-01"), endDate: new Date("2017-01-04")})
            }
        },
        {
            type : 'button',
            text : 'zoomTo 01-01 - 01-02',
            onClick() {
                scheduler.zoomTo({startDate: new Date("2017-01-01"), endDate: new Date("2017-01-02")})
            }
        },

If the scheduler is wide enough, you can click both buttons alternately and the zoom/scroll will adjust correctly: switch from 2 days window to 4 days and back.

If you shrink the width of the main grid to about 800px with the separator of the code editor and click the buttons alternately, the zoom stops to work at all. One has to either manually zoom out with the mouse or change the width of the grid again.


Post by alex.l »

Hi alexp,

In this particular case it stops zooming because there is no other presets available to fit requirements. try to comment presets config in the Scheduler in same example, this will unlock default set of zoom levels that have more levels and will handle this case.

How it worked for you before last upgrade? Did you override default presets in you real app?

All the best,
Alex


Post by alexp »

Hi alex.l,
you're right. So this might not be the issue I have in my real app.

In the real app, we basically grab the default presets from PresetManager.allRecords, filter out ['weekAndMonth', 'weekAndDayLetter', 'weekAndDay-54by80', 'minuteAndHour-30by60'], and patch the rest so that they are language aware:

const getPatches = (lang: string): Record<string, Partial<ViewPreset>> => {
  const dateSeparator = lang === 'de' ? '.' : '/';

  return {
    // ...
    hourAndDay: {
      displayDateFormat: 'll HH:mm',
      headers: [
        {
          unit: 'day',
          dateFormat: `ddd DD${dateSeparator}MM`
        },
        {
          unit: 'hour',
          dateFormat: 'HH:mm'
        }
      ]
    },
    weekAndDay: {
      displayDateFormat: 'll HH:mm',
      headers: [
        {
          unit: 'week',
          renderer: formatWeekDay
        },
        {
          unit: 'day',
          dateFormat: 'DD'
        }
      ]
    },
    ...
  };
};

export const patchPresets = (presets: Array<Partial<ViewPresetInstance>>, lang: string): Array<Partial<ViewPreset>> => {
  const patches = getPatches(lang);

  return presets
    .filter((preset) => !exclude.includes(String(preset.id)))
    .map((preset) => {
      const presetId = preset.baseId ? String(preset.baseId) : String(preset.id);
      if (presetId && patches[presetId]) {
        return merge({ ...preset.data }, patches[presetId]);
      }

  return {
    ...preset.data
  };
});
};
// and in each change of the app language:
this.scheduler.presets = patchPresets(PresetManager.allRecords as ViewPresetInstance[], lang);

In v5.2.3 it was able to zoom from a range of 2 days to a range of 4 days. We only did the update and didn't change the preset config.

In v5.2.4 only the last 2 days of the 4 day frame are in the viewport, the zoom+scroll didn't change.


Post by alex.l »

Ok, I got it. Could you please post something runnable that I could debug? I will check that in both versions and if it's regression, the ticket will get higher priority.
Try to change our configuration demo that you already mentioned?

All the best,
Alex


Post by alexp »

Ok, got it reproduced. It is about the viewport width of the events and might be only happen on initial render.

I use Google Chrome in v107.0.5304.122.

We can set it up with your playground the following way:

  • - Shrink the browser window to 730pixel. This is for me the size that the b-grid-subgrid is at 118px width after you open the code editor.

  • - Refresh the browser tab.

  • - Open code editor and paste this:



import { DateHelper, EventModel, Scheduler, PresetManager } from '../../build/scheduler.module.js?463787';
import shared from '../_shared/shared.module.js?463787';

const
    resources = [
        { id : 1, name : 'Arcady', role : 'Core developer', eventColor : 'purple' },
    ],
    events    = [
        {
            id          : 1,
            resourceId  : 1,
            percentDone : 60,
            startDate   : new Date(2017, 0, 1, 10),
            endDate     : new Date(2017, 0, 1, 12)
        },
    ];

class EventModelWithPercent extends EventModel {
    static get fields() {
        return [
            { name : 'percentDone', type : 'number', defaultValue : 0 }
        ];
    }
}

const scheduler = new Scheduler({
    appendTo          : 'container',
    resourceImagePath : '../_shared/images/users/',

features : {
    stripe : true,
    sort   : 'name'
},

columns : [
    {
        type  : 'resourceInfo',
        text  : 'Staff',
        width : '10em'
    }
],

resources  : resources,
eventStore : {
    modelClass : EventModelWithPercent,
    data       : events
},

startDate : new Date(2017, 0, 1),
endDate   : new Date(2017, 1, 1),
   
eventRenderer : ({ eventRecord, renderData }) => {
    const value = eventRecord.percentDone || 0;
    renderData.children.push({
        className : 'value',
        style     : {
            width : `${value}%`
        },
        html : value
    });
},

tbar : [
    {
        type : 'button',
        text : 'zoomTo 4 days',
        onClick() {
            scheduler.zoomTo({startDate: new Date(2017, 0, 1), endDate: new Date(2017, 0, 5)})
        }
    },
    {
        type : 'button',
        text : 'zoomTo 1 day',
        onClick() {
            scheduler.zoomTo({startDate: new Date(2017, 0, 1), endDate: new Date(2017, 0, 2)})
        }
    },

]
});

  • - Just click the first button once. Here I would expect to see 4 days, but the zoom is kept and we still see 6 days. When you click the second button, you kind of "repair" it and after that you can toggle both views back and forth.

So in general the zoom works, but not the first time. That is why our e2e test failed :)

Thank you for looking into it!


Post by alex.l »

Thank you for the test case, I've reproduced the problem. Here is a link to track the status https://github.com/bryntum/support/issues/5704

All the best,
Alex


Post Reply