Premium support for our pure JavaScript UI components


Post by paul.manole »

mats wrote: Wed Jan 03, 2024 3:06 pm

This demo is now merged to our master branch meaning it'll be part of upcoming 6.0 release (Late January). You can grab the demo already from the nightly builds in our customer zone and use it in your own application.

Splendid! Thank you!


Post by paul.manole »

I noticed a bit of animation jankiness if I move a duty then toggle the view. See this video: https://github.com/brokenthorn/imgs/raw/main/chrome_gSl6QIjLWh.mp4


Post by fabio.mazza »

Hello paul and thank you very much for your feedback!
I'm taking a look at it and I'll keep you update

Best regards,
Fabio


Post by fabio.mazza »

Hello Paul, now it's fixed, let me know if it works for you now :)

Best regards,
Fabio


Post by paul.manole »

Hey Fabio, not sure I can look at it now, not sure sure what's changed either, I presume I have to download the latest alpha, but before I get to that, I have another problem.

I have finally started working on implementing the switching between planned and actual dates for events, but I have been having lots of issues trying to make it work.

I am on 5.6.1 still, as we cannot use alpha versions and, as far I could tell, the demo for planned vs actual that has been added to v6-alpha1 does not look like it is using any new functionality that is not present in the previous version.

The problem I seem to have is that when clearing the duration field on the event, it also clears the actual end date field, which is a field that endDate is mapped to using the dataSource property.

I am assuming that Scheduler does this because by design, it works with a start date plus a duration, and endDate is calculated as needed dynamically through its getter. This is probably so that events stay consistent when rescheduled, as you only need to update the start date, or the duration, and not have to think about the end date.

I don't understand why Scheduler deletes my end date though, but by clearing the duration as the demo shows it should be done, and the end date clearing itself as a side effect on my machine, that leaves the events with just a start date, which makes them unrenderable. I basically don't get any events rendered when I perform the switch.

I did manage to get the desired behavior, but I used a different approach. Instead of clearing the duration, I manually update each event's startDate and duration. This means I do not have to reload the data or do a toJSON serialization, which seems like a huge cost to have just do update a couple of fields and render the change in the UI. Plus this reload might be unexpected and break some state within our React app...

Anyway, I am not sure if this is optimal. It does not seem to perform as fast as it should, plus there are some animation glitches like events contracting to zero size before sizing back to the correct size, but that is probably because of the way we have implement some of the rest of the code, and I will look into that later.

Do you think you can give me some insights on what would be the best approach? Basically we have the same data, the same DTO, for both planned and actual dates, already loaded in the store, and all we want is for each event to switch between two sets of dates and two sets of resource IDs, because we have a planned resource and an actual resource as well. I might have forgotten to mention that, but I assume the process would be the same.

Our data does not contain a duration, we didn't model it like that from the beginning, but we do have sets of start and end date instances for both planned and actual. Let me know if it's a faster/more performant approach if we added duration precalculated from the backend, and switched to a logic based on just start dates and durations.

Here is effectively what I have now, and please tell me what you think of this approach:

  1. in a useEffect, whenever the view is switched, we do
    modelClass.fieldMap.startDate.dataSource = "plannedOrActualStartDateTime"

  2. we do the same for endDate

  3. we do the same for resourceId

  4. the we suspend refresh

  5. then we do an eventStore.forEach and update the event.startDate, and event.duration based on current view, as well as the resourceId, using the data already present on the event for each view

  6. then we resume refresh

And this seems to work. The dataSource remapping step does not seem to be necessary anymore, as the changes are done manually. Am I right?

Also, if we don't do the manual updating in the forEach, but do the dataSource remapping, nothing changes, like startDate is still the same value, and does not switch between the planned and actual start date fields, even if on runtime inspection, the fieldMap does take the new values. And like I said, doing a data reload with data = toJSON does not help as the dates are lost and nothing renders, but inspecting the store, the data is there, it just lacks a duration, which is set to null, and the actual end date property is not present anymore. I did log the toJSON result before giving it to data though, and the data was still there, nothing was missing, which is weird.

So, if we keep using this approach with an explicit manual edit of all fields that need to change from planned to actual and vice versa, without the dataSource-type remapping, is that worse in terms of performance, does it have any drawbacks or unwanted side effects we might not be aware of?

Sorry for so many questions. I will be patient for you to reply, as I really need to write a good performing solution with this one. The requirements demand it :D.

Thank you and thanks to everyone that helped!


Post by fabio.mazza »

Hello Paul. You can grab the updated demo from the nightly builds in our customer zone.
However, it's weird that when setting the duration field to undefined, the endDate field is being cleared.
The scheduler engine should automatically recalculate the duration considering start and end dates.
However, yes, your approach is fine as well. Important thing for the performance is always to suspend refresh when changing many events data and resume it later.
I would like to have your code to dive into the endDate issue, can you send it to me, please?

Best regards,
Fabio


Post by paul.manole »

Hi Fabio,

Yes, I can give you the code but I would have to extract it first into an MRE. I will try to prepare it today, after I'm done with some work.

But, it is great to hear that my alternative approach is also good, provided we suspend refresh when doing such bulk updates, then resume. I am very happy to hear that, because we were already starting to think we needed a contingency plan if this feature would not work out as we expected it to.

I actually like this approach more to be honest, because there is no step where I have to reload the event store with the same events, and have to serialize them beforehand from the event store just to pipe them back in. That seems like an inordinate amount of work for what we want to achieve here, and we also had some edge cases because of some other reloads we had to do, and the demo for planned vs actuals got me worried about that again.

I guess what I mean is, for example, if I had 5k events loaded in Scheduler, switching all of them from a planned schedule to an actual schedule, requires updating all these events, regardless of the approach!

So, logically, I don't see why we would have to add an extra step of reloading the event store and triggering a full project model resync. I assume that Scheduler batches all view model updates in a queue if more than one update is executed in the same function call, and the next time the event loop runs to check that queue, it will take those queued tasks and schedule an UI update. So, I assume that this kind of automatic batching takes place, making UI updates smoother.

Now that I think about this, it would be great for us if we understood some of these technical workings of Scheduler just from a high level perspective, so we can write performant code when working with it. Do you guys have any technical articles like that, that go a bit in-depth on how Scheduler works, to help provide your customers' developers with some useful insights, and intuition, into how to best develop features when working with Scheduler?

Thanks for your help. I will work on the MRE as soon as possible and come back to you when it's done.


Post by saki »

I assume that Scheduler batches all view model updates in a queue if more than one update is executed in the same function call

Actually, we have a some methods to call before and after batch operations. One, https://bryntum.com/products/scheduler/docs/api/Core/data/Store#function-beginBatch, you call on store, then you update records and then you call https://bryntum.com/products/scheduler/docs/api/Core/data/Store#function-endBatch.

Another option would be to call
https://bryntum.com/products/scheduler/docs/api/Scheduler/view/SchedulerBase#function-suspendRefresh on the scheduler and, after the batch update, call https://bryntum.com/products/scheduler/docs/api/Scheduler/view/SchedulerBase#function-resumeRefresh.

Both prevent updating the UI during batch data operations.


Post Reply