Our state of the art Gantt chart


Post by Qwerty »

Hi there,

It seems that tasks can be duplicated when reordering and when filtering is enabled.

Steps to Reproduce

  1. Go to the advanced demo: https://www.bryntum.com/examples/gantt/advanced/
  2. Rename "Install Apache" to "foo Install Apache"
  3. Rename "Setup load balancer" to "foo Setup load balancer"
  4. Using the column header on the name column, add a filter for "foo". You should now see only 2 tasks within "Setup web server"
  5. Drag "foo Setup load balancer" to the top of the list (above "foo Install Apache")

You'll notice that there are now 2 instances of "foo Setup load balancer" in the grid, both highlighted.

Not only does this appear to be a visual duplication but the taskStore seems to have gained a record after the drag (gantt.taskStore.allRecords.length is 41 before, 42 after).


Post by mats »

Reproduced, thanks for an excellent bug report: https://github.com/bryntum/support/issues/1074


Post by Qwerty »

Hi mats,

Thanks again for prioritizing this one.

We're at the point now where our own timelines are in jeopardy because of this issue and we yet don't have any workarounds.

We'd like to know what our options might be to resolve this issue ourselves just until the next release.

Would you be able to lend some guidance as to how the team are planning on tackling this issue and whether it's something we can preempt on our end in the meantime?

Thanks as always.


Post by Qwerty »

We've spent a bit of time on this ourselves and have diagnosed what we think is the root cause.

In TreeNode.js insertChildren is called by finalizeReorder in RowReorder.js. When removeChild is eventually called in the problem example above, unfilteredIndex is undefined meaning the node itself is not removed before it is added again, leading to the duplication.

We have found a workaround for the time being that seems to fix the issue, however we are well aware that this is solving the issue at the symptom level not necessarily at the root cause level. We still eagerly await the correct solution from you in the next release.

Our workaround is to call updateChildrenIndex for both children and unfilteredChildren before tryInsertChild is called in RowReorder#finalizeReorder.

 if (context.valid) {
  // the 2 calls described above:
  context.parent.updateChildrenIndex(context.parent.children || [], false);
  context.parent.updateChildrenIndex(context.parent.unfilteredChildren || [], true);

  // existing code
  result        = await context.parent.tryInsertChild(me.record, context.insertBefore);
  context.valid = result !== false;
}

We're doing our own manual testing of this change but in the meantime, would it be possible to run this change through your automated tests and let us know the results?


Post by arcady »

As a quick workaround that looks good!
Another place where this could be done is StoreFilter class but the fix would be pretty much the same.

The issue has actually discovered few major places to be refactored ..we'll work on them as part of that issue.
Thank you very much for the report!


Post Reply