Premium support for our pure JavaScript UI components


Post by clovisapp »

Hi Bryntum team,

How can we enhance the behavior of tasks when moving them ?

Here in attachements you will find two videos:

  • One example with our bryntum implementation, moving back a task makes the predecesors move back for no reason
  • one example with Notion's Gantt, with a "normal" behavior (moving back a predecessor makes the ancestor move)

Thanks a lot for your help !

Attachments
Screen Recording 2024-01-12 at 15.44.30.mov
(24.58 MiB) Downloaded 43 times
Screen Recording 2024-01-12 at 15.45.45.mov
(8.95 MiB) Downloaded 52 times

Image


Post by marcio »

Hey,

You're looking for https://bryntum.com/products/gantt/docs/api/Gantt/feature/TaskDrag#config-pinSuccessors

features : {
	taskDrag: {
   		pinSuccessors: true
   	}
}

Best regards,
Márcio


Post by clovisapp »

Hi Marcio,

I tried to test it (cf screenshot and video) but it doesn't work (using bryntum gantt 5.0.5).

To be clear i have two problems in this ticket (you can see them in initial video):

  • the fact that when moving back an ANCESTOR after pushing a PREDECESSOR, the PREDECESSOR is moved back
  • moving back a PREDECESSOR doesn't move back an ANCESTOR (the video i give in this message)
Attachments
Screenshot 2024-01-12 at 17.14.16.png
Screenshot 2024-01-12 at 17.14.16.png (161.88 KiB) Viewed 1664 times
Screen Recording 2024-01-12 at 17.05.48.mov
(13.24 MiB) Downloaded 52 times

Image


Post by marcio »

Hey,

Thanks for the clarification, you could use the beforeTaskDropFinalize event listener, and then do the operations to move the ANCESTOR as you want to.

https://bryntum.com/products/gantt/docs/api/Gantt/feature/TaskDrag#event-beforeTaskDropFinalize

Best regards,
Márcio


Post by clovisapp »

Thanks a lot @marcio,

I think you didn't understood my main problem (seen video in attachments):

  • TASK 1 is ANCESTOR of TASK 3
  • TASK 1 is moved in the future, pushing PREDECESSOR TASK 3 in the future (all good for now)
  • BUT when TASK 1 i then moved back in the past, TASK 2 is also moved back in the past (like if it was a Ctrl + Z). This behavior is wrong for us. Expected behavior:
    => TASK 1 i then moved back, and TASK 3 DOESN'T have to move
Attachments
Screen Recording 2024-01-12 at 15.44.30.mov
(24.58 MiB) Downloaded 36 times

Image


Post by tasnim »

Hi,

Please try something like this (An idea).
Of course, you can customize the code however you like

    listeners : {
        beforeTaskDropFinalize(props) {
            const { context } = props;
            const isNegative = context.timeDiff < 0;
            let newTimeDiff = context.timeDiff;
            if (isNegative) {
                let stringTimeDiff = String(newTimeDiff).split('');
                stringTimeDiff.shift();
                newTimeDiff = stringTimeDiff.join('');
            }
                context.record.dependencies.forEach(dep => {
                    if (isNegative) {
                        dep.lag = myObj[dep.id];
                    }
                    if (!isNegative) {
                        myObj[`${dep.id}`] = DateHelper.as(dep.lagUnit, newTimeDiff, 'ms');
                    }
                    console.log(dep.lag);
                    window.dep = dep;
                });
        }
    }

myObj is assigned outside of gantt scope.

Best regards,
Tasnim


Post by clovisapp »

thanks @tasnim.

Is that so complicate to make the gantt not have this kind of backward "stickiness" ? (by stickiness, i mean that the predecessor gos back when an ancestor is also moved back)

Image


Post by tasnim »

Hi,

Yes, it's a bit complicated because it doesn't work out of the box.

I've updated the code a bit

    listeners : {
        beforeTaskDropFinalize(props) {
            const { context } = props;
            const isNegative = context.timeDiff < 0;
            let newTimeDiff = context.timeDiff;
            if (isNegative) {
                let stringTimeDiff = String(newTimeDiff).split('');
                stringTimeDiff.shift();
                newTimeDiff = Number(stringTimeDiff.join(''));
            }
            context.record.dependencies.forEach(dep => {
                myObj[`${dep.id}`] = DateHelper.as(dep.lagUnit, newTimeDiff, 'ms');
                if (isNegative) {
                    dep.lag = myObj[dep.id] + dep.lag;
                }
            });
        }
    },

Docs https://bryntum.com/products/schedulerpro/docs/api/Scheduler/model/DependencyModel#field-lag

Attachments
chrome_w99Y6wRJYu.gif
chrome_w99Y6wRJYu.gif (505.23 KiB) Viewed 1181 times

Post by clovisapp »

Thanks @tasnim,

The variables "myObj" and "DateHelper" are not defined in your code extract. Can you write me a working code extract ? Thanks a lot !

    listeners : {
        beforeTaskDropFinalize(props) {
            const { context } = props;
            const isNegative = context.timeDiff < 0;
            let newTimeDiff = context.timeDiff;
            if (isNegative) {
                let stringTimeDiff = String(newTimeDiff).split('');
                stringTimeDiff.shift();
                newTimeDiff = Number(stringTimeDiff.join(''));
            }
            context.record.dependencies.forEach(dep => {
                myObj[`${dep.id}`] = DateHelper.as(dep.lagUnit, newTimeDiff, 'ms');
                if (isNegative) {
                    dep.lag = myObj[dep.id] + dep.lag;
                }
            });
        }
    },

Image


Post by tasnim »

Hi,

myObj is defined outside of the ganttConfig like this

let myObj

And DateHelper needs to be imported from @bryntum/gantt

import { DateHelper } from '@bryntum/gantt'

Post Reply