Our pure JavaScript Scheduler component


Post by melissa.alday »

Pardon mats, EventStore has the same issue. You may check the code. In fact, I'm planning to reverting back to old code. Even after putting these patches, issue is not getting fixed. I'll come with more screenshots, if you want.


Post by mats »

Good catch, it goes a bit deeper. Ticket opened: https://github.com/bryntum/support/issues/2418


Post by imkookoo »

Hi mats...

Does this issue also exist perhaps with the the "set" method of an assignment store? I'm on the released 4.1.0-beta-3 build at the moment, and when I do the following ("containerAssignment" is an assignment store record):

containerAssignment.set('resource', theResource, true);

The assignment of the event does get changed, -and- the triggers are set off despite the silent arg = true.

EDIT:
If this is not a bug, is there a way I can update properties of an event/assignment without triggering the events?

My app will basically send data to the backend whenever the events are moved around the scheduler to save it to the database. In the event of any validation or other failures from the backend, I'm wanting the event to revert back to its original position on the frontend. I'm trying to set the values back to the original values in the frontend without having the events triggering off another save to the backend.


Post by mats »

Using 'silent' is not a good idea (it will likely be deprecated and kept as a private flag). If you are using the CrudManager, try calling revertChanges to undo any current changes?


Post by imkookoo »

I'm not using CrudManager actually, and handling all the syncing to the backend manually through our own functionality to send HTTP requests to our backend.

I tried to testing though to maybe potentially switch to using this model, but when I do a "revertChanges", the event's assignment seems to go away. I have the following defined:

[code]this.crudManager = new top.viewFrame.bryntum.schedulerpro.CrudManager({
resourceStore : this.schedulerPro.resourceStore,
eventStore : this.schedulerPro.eventStore,
assignmentStore : this.schedulerPro.assignmentStore,
stores : [ this.unplannedGrid.store ]
});
[/code]

.. and do a "this.crudManager.commit()". Then I change one of the events to a different time, and then do a "this.crudManager.revertChanges()". The event's startDate does seem to revert back to before the commit when I look at it directly through the JS console, but the assignment goes away, and it gets moved into the Unplanned grid that I also have setup. Not sure what I'm doing wrong.

This would be quite a bit of work though for me to switch over to this model. I have most things working at the moment, and found a workaround to prevent these reverted rows from being saved. But the other thing I might be doing in the future is syncing a list of containers on the screen so that if changes are made elsewhere or by another user, the current user's screen gets reflected. There'd be an AJAX poll to do this, and in that case, I'm wanting to automatically change the event's position in the scheduler.. in which case, "revertChanges()" would not work, and I'd still need a way to update the event's fields without it sending another save request to the backend.


Post by pmiklashevich »

You can try Scheduler/data/CrudManager#function-acceptChanges which is going to be public in 4.1.0.

I see you create a CrudManager instance, but you're using SchedulerPro. In SchedulerPro the Project should be used as a central data storage instead. CrudManager is supposed to be used with simple Scheduler.

Could you please prepare a small simple testcase based on one of our demos, so we can clearly see what you're doing and where there problem is?

Pavlo Miklashevych
Sr. Frontend Developer


Post by imkookoo »

1) For the "revertChanges" issue, I've attached "Examples of Issues.zip" to provide an example.

To setup, put the example.html file in the zip file in a directory, create an "import" directory in the same directory, and inside of that, put all of the SchedulerPro build files in there -- I used 4.1.0-beta-3. And then open example.html in a browser.

To replicate: I just have the schedulerPro instance as a global variable with the same label. So I tried doing the following:

  • Move the event to a different time and door
  • Execute "top.schedulerPro.project.acceptChanges()" in the browser console
  • Move the event to another time and door again
  • Execute "top.schedulerPro.project.revertChanges()" in the browser console. The event moves to the "Unscheduled Containers" area rather than back to where it was moved to in the first step (the assignment is no longer there). But if you look at the event, the startDate is reverted successfully to where it was moved to in the first step.

2) For the issue with triggers being executed, the zip file also has "example-trigger.html". I've placed alerts on the changes / "update" action. If a user changes the event, I'd like the event to trigger. But if there's something in the backend that updates the event, I'd like to suppress the trigger. "updateEvent" and "updateEvent2" are the two ways I've tried so far (former using the silent = true argument of the setter, and the latter using suspendEvents method), but they both execute the triggers.

Attachments
Examples of Issues.zip
(7.63 KiB) Downloaded 62 times

Post by pmiklashevich »

Hello!

Lets check issues one by one.

1) For the "revertChanges" issue, I've attached "Examples of Issues.zip" to provide an example.

To setup, put the example.html file in the zip file in a directory, create an "import" directory in the same directory, and inside of that, put all of the SchedulerPro build files in there -- I used 4.1.0-beta-3. And then open example.html in a browser.

To replicate: I just have the schedulerPro instance as a global variable with the same label. So I tried doing the following:

Move the event to a different time and door
Execute "top.schedulerPro.project.acceptChanges()" in the browser console
Move the event to another time and door again
Execute "top.schedulerPro.project.revertChanges()" in the browser console. The event moves to the "Unscheduled Containers" area rather than back to where it was moved to in the first step (the assignment is no longer there). But if you look at the event, the startDate is reverted successfully to where it was moved to in the first step.

The first issue happens because assignment record has no id defined. When you drag the event to a new resource, the assignment record gets updated, and since the record has autogenerated id, it is considered to be a phantom record, and the assignment store's "added" collection gets updated. When you revert changes, everything is removed from "added" and "modified" collections. Therefore the assignment record gets removed and the event record turned into an unassigned record. Adding ID will help:

// In your code:
const [event] = schedulerPro.project.eventStore.add([{
    'id'           : 1,
    'name'         : 'Task',
    'startDate'    : '2021-02-25T09:00:00',
    'duration'     : 120,
    'durationUnit' : 'm',
    'resizable'    : false
}]);
// Added 'id' here
schedulerPro.project.assignmentStore.add([{ 'id' : 1, 'resource' : 1, 'event' : event.id }]);

Basically this is easy to reproduce in our demo: schedulerpro/examples/drag-from-grid/
Please follow the steps one by one:

schedulerPro.eventStore.removeAll()
schedulerPro.eventStore.add({ id : 1000, name : 'test', startDate : new Date(2025, 11, 1, 9), duration : 1 })
schedulerPro.assignmentStore.add({ resourceId : 1, eventId : 1000 })
schedulerPro.assignmentStore.added.count
//1
// drag event to another resource
schedulerPro.project.acceptChanges()
schedulerPro.assignmentStore.added.count
//0
// drag event to another resource
schedulerPro.assignmentStore.added.count
//1 - The added collection is restored
schedulerPro.project.revertChanges()
schedulerPro.assignmentStore.added.count
//0
schedulerPro.assignmentStore.count
//0 - Record is removed
Снимок экрана 2021-04-02 в 13.10.22.png
Снимок экрана 2021-04-02 в 13.10.22.png (478.69 KiB) Viewed 1102 times

And the same with id specified. Please reload the page and start over:

schedulerPro.eventStore.removeAll()
schedulerPro.eventStore.add({ id : 1000, name : 'test', startDate : new Date(2025, 11, 1, 9), duration : 1 })
schedulerPro.assignmentStore.add({ id: 1000, resourceId : 1, eventId : 1000 })
schedulerPro.assignmentStore.added.count
//1
// drag event to another resource
schedulerPro.project.acceptChanges()
schedulerPro.assignmentStore.added.count
//0
// drag event to another resource
schedulerPro.assignmentStore.added.count
//0 - Record is not added since it has an id
schedulerPro.project.revertChanges()
schedulerPro.assignmentStore.added.count
//0
schedulerPro.assignmentStore.count
//1 - Record exists
Снимок экрана 2021-04-02 в 13.45.01.png
Снимок экрана 2021-04-02 в 13.45.01.png (538 KiB) Viewed 1102 times

Please add an ID to the assignment records to solve the issue.
I'll check the second issue you've reported and get back to you soon.

Best,
Pavel

Pavlo Miklashevych
Sr. Frontend Developer


Post by pmiklashevich »

Regarding your second issue.

2) For the issue with triggers being executed, the zip file also has "example-trigger.html". I've placed alerts on the changes / "update" action. If a user changes the event, I'd like the event to trigger. But if there's something in the backend that updates the event, I'd like to suppress the trigger. "updateEvent" and "updateEvent2" are the two ways I've tried so far (former using the silent = true argument of the setter, and the latter using suspendEvents method), but they both execute the triggers.

  1. "updateEvent":
    You can use model.set and pass individual arguments:
    https://lh/bryntum-suite/schedulerpro/docs/#Core/data/Model#function-set

    const eventRecord = top.schedulerPro.project.eventStore.getEventById('DESU1349834|2|CLV');
    eventRecord.set('name', 'test', true);
    

    or set as an object, but keep in mind that "silent" is 3rd param

    eventRecord.set({
        name : 'test'
    }, undefined, true); // silent is 3rd param
    

    or you can use batch update:
    https://lh/bryntum-suite/schedulerpro/docs/#Core/data/Model#function-beginBatch
    https://lh/bryntum-suite/schedulerpro/docs/#Core/data/Model#function-endBatch

    eventRecord.beginBatch();
    eventRecord.name = 'test';
    eventRecord.endBatch(true); // true means silent
    
  2. "updateEvent2":
    You need to suspend events on the object you add a listener to! You listen events on event store and assignment store. Then you need to mute them. Suspending events on the project does not suspend events on its stores.
    https://lh/bryntum-suite/schedulerpro/docs/#SchedulerPro/data/EventStore#function-suspendEvents
    https://lh/bryntum-suite/schedulerpro/docs/#SchedulerPro/data/EventStore#function-resumeEvents

    const eventStore = top.schedulerPro.project.eventStore;
    const eventRecord = eventStore.getEventById('DESU1349834|2|CLV');
    
    eventStore.suspendEvents(false);
    eventRecord.name = 'test';
    eventStore.resumeEvents();
    

    Note, when update records silently, the view will not display changes. You might need to refreshRows manually.

    Let us know please if the problems are solved.

    Best,
    Pavel

Pavlo Miklashevych
Sr. Frontend Developer


Post by imkookoo »

Hi Pavel,

Thank you for the quick response! Ahh, great on the Assignment model needing an ID. That does the trick with solving point #1.

For point #2, I added an "id" for the assignment, and did suspendEvents/resumeEvents (and also tried beginBatch/endBatch(true)) on the eventStore/assignmentStore and even did it on the unplannedGrid.store.... the EventStore trigger is successfully suppressed. But the AssignmentStore trigger is still triggering.

I've attached an updated example. updateEvent2 is the version using suspendEvents, and updateEvent3 is the version using beginBatch.

Attachments
example-trigger-v2.zip
(4.1 KiB) Downloaded 54 times

Post Reply