Our state of the art Gantt chart


Post by amitcodeadda »

Hello, I am using the drag drop column on the left panel of Gantt to re-position tasks. I have three level of tasks under main root task. How to save re-position of task ?


Post by mats »

Can you please share an image and highlight the UI state you want to save? Is it the left table section width value you refer to?


Post by amitcodeadda »

firstPostion.png
firstPostion.png (76.04 KiB) Viewed 469 times

In this image I want to change position of task 2

change.png
change.png (55.71 KiB) Viewed 469 times

the position is change how can we save the position of task in database. If any function please let me know


Post by marcio »

Hey,

The property that you're looking for is parentIndex, which stands for that purpose that you mentioned.

https://www.bryntum.com/docs/gantt/api/Core/data/mixin/TreeNode#field-parentIndex

Best regards,
Márcio


Post by amitcodeadda »

Hey marcio ,

The property parentIndex is not solving my purpose. I want to store the child index of particular parent


Post by mats »

@amitcodeadda: Please explain a bit better what your needs are. parentIndex is the child index of a particular parent.


Post by amitcodeadda »

So how can I get the parentIndex of particular parent. I can use all the functions given in doc. but not get/fetch the parentIndex


Post by mats »

It's available on every Task record. Open https://bryntum.com/examples/gantt/advanced/

In console type:

gantt.taskStore.getById(14).name;
gantt.taskStore.getById(14).parentIndex;
Attachments
Screenshot 2022-07-07 at 07.33.04.png
Screenshot 2022-07-07 at 07.33.04.png (69.34 KiB) Viewed 444 times

Post by amitcodeadda »

Hello ,

export const ganttConfig = {
    tbar: { type: 'gantttoolbar' },
    dependencyIdField: 'wbsCode',
    infiniteScroll: true,
    visibleDate: {
        date: new Date(),
        block: 'center'
    },
    subGridConfigs: {
        locked: {
            flex: 3
        },
        normal: {
            flex: 4
        }
    },
    columnLines: true,
    viewPreset: {
        base: 'weekAndDay',
        tickWidth: 50,
        tickHeight: 50,
        shiftIncrement: 1,
        shiftUnit: 'day',

    timeResolution: {
        unit: 'day',
        increment: 1
    },
    headers: [
        {
            unit: 'month',
            dateFormat: 'MMM YYYY',
            align: 'center'
        },
        {
            unit: 'week',
            renderer: (startDate, endDate) => `${DateHelper.format(startDate, 'DD MMM')} - ${DateHelper.format(endDate, 'DD MMM')} (Week ${DateHelper.format(startDate, 'WW')})`
        },
        {
            unit: 'day',
            dateFormat: 'ddd, D'
        }
    ],

},
timeRangesFeature: {
    showCurrentTimeLine: true
},


columns: [
    {
        type: 'name',
        text: 'Task name',
        editor: false,
        width: 100,
        renderer: ({ record, grid, grid: { extraData } }) => {
            if (record.type === 'Milestone') {
                return <>
                    <DemoButton
                        text={'EditMeilstone'}
                        name={record.name}
                        onClick={() => extraData.edit({ record, grid })}
                    />
                </>
            } else if (record.type === 'Task') {
                if (record.isCompletedSuccessfully === true) {
                    return record.name
                } else {
                    return <>
                        <DemoButton
                            text={'EditTask'}
                            name={record.name}
                            onClick={() => extraData.edit({ record, grid })}
                        />
                    </>
                }

            } else {
                return record.name
            }
        }
    }, { type: 'duration', editor: false, },
    {
        editor: false,
        text: 'Status',
        width: 100,
        renderer: ({ record }) =>
            record.type === 'Task' ? record.status_code[0].label : null
    },
    {
        text: 'Action',
        editor: false,
        width: 100,
        renderer: ({ record, grid: { extraData } }) =>
            record.type === 'Milestone' ? (
                <>
                    <DemoButton
                        text={'AddTask'}
                        onClick={() => extraData.add({ record })}
                    />
                </>
            ) : null

    }],
rollupsFeature: {
    disabled: true
},
baselinesFeature: {
    disabled: true
},
progressLineFeature: {
    disabled: true,
    statusDate: new Date(2019, 0, 25)
},
listeners: {
    beforeDependencyDelete({ dependencyRecord }) {
        const raw = {
            id: dependencyRecord.id,
            toTask: dependencyRecord.toTask.id
        }
        Apis.deleteLink(raw).then((res) => {
            console.log(res)
        }).catch((error) => {
            console.log(error)
        })

    },
    beforeDependencyCreateFinalize({ source, target, fromSide, toSide }) {
        if (fromSide === 'right' && toSide === 'left') {
            const raw = {
                fromTask: source.id,
                toTask: target.id
            }
            Apis.createLink(raw).then((res) => {
                console.log(res)
            }).catch((error) => {
                console.log(error)
            })
        }

    },
    taskResizeEnd({ taskRecord }) {
        const raw = {
            name: taskRecord.name,
            duration: taskRecord.duration,
            id: taskRecord.id,
        }
        Apis.resizeTask(raw).then((res) => {
            console.log(res)
        }).catch((error) => {
            console.log(error)
        })
    }
},
rowReorderFeature: {
    listeners: {
        gridRowDrag: ({ context }) => {

            console.log(context.records[0].parentIndex)
        }
    }
},
dependencyEditFeature: {
    editorConfig: {
        title: 'Do you want to delete dependency?',
        items: {
            // Custom label for the type field
            typeField: {
                hidden: true
            },
            lagField: {
                hidden: true
            },
            activeField: {
                hidden: true
            }
        },
        bbar: {
            items: {
                saveButton: {
                    hidden: true
                },
                deleteButton: {
                    cls: 'b-raised',
                    icon: 'b-fa-trash b-fa-fw',
                    color: 'b-red',
                }
            }
        }
    }
},
taskDragFeature: {
    validatorFn(draggedTaskRecords, newStartDate,) {
        if (draggedTaskRecords[0].status_code[0].label === 'Constrained') {
            const date1 = new Date(draggedTaskRecords[0].previousSibling.endDate)
            const date2 = new Date(newStartDate)
            const getBusinessDatesCount = (startDate, endDate) => {
                let count = 0;
                let curDate = +startDate;
                while (curDate <= +endDate) {
                    const dayOfWeek = new Date(curDate).getDay();
                    const isWeekend = (dayOfWeek === 6) || (dayOfWeek === 0);
                    if (!isWeekend) {
                        count++;
                    }
                    curDate = curDate + 24 * 60 * 60 * 1000
                }
                return count;
            }
            const diff = getBusinessDatesCount(date1, date2)
            let date = new Date(newStartDate)
            date = new Date(date.setTime(date.getTime() + 6 * 60 * 60 * 1000))
            const raw = {
                type: draggedTaskRecords[0].type,
                startdate: new Date(date),
                id: draggedTaskRecords[0].id,
                name: draggedTaskRecords[0].name,
                diff: diff - 1,
                link_update: true
            }
            Apis.updateTaskDrag(raw).then((res) => {
                console.log(res)
            }).catch((error) => {
                console.log(error)
            })
        } else {
            let date = new Date(newStartDate)
            date = new Date(date.setTime(date.getTime() + 6 * 60 * 60 * 1000))
            const raw = {
                type: draggedTaskRecords[0].type,
                startdate: new Date(date),
                id: draggedTaskRecords[0].id,
                name: draggedTaskRecords[0].name,
                diff: 0,
                link_update: false
            }
            Apis.updateTaskDrag(raw).then((res) => {
                console.log(res)
            }).catch((error) => {
                console.log(error)
            })
        }
    }
},
taskTooltipFeature: {
    disabled: true
},
headerMenuFeature: {
    disabled: true
},
taskEditFeature: {
    disabled: true
},
dependenciesFeature: {
    allowCreate: true,
},
columnLines: true,
projectLinesFeature: {
    disabled: true
},
taskMenuFeature: false,
taskRenderer({ taskRecord }) {
    if (!taskRecord.isMilestone) {
        if (taskRecord.type === 'Task') {
            const date1 = new Date(taskRecord.taskrefdate)
            const date2 = new Date(taskRecord.endDate)

            const getBusinessDatesCount = (startDate, endDate) => {
                let count = 0;
                let curDate = +startDate;
                while (curDate <= +endDate) {
                    const dayOfWeek = new Date(curDate).getDay();
                    const isWeekend = (dayOfWeek === 6) || (dayOfWeek === 0);
                    if (!isWeekend) {
                        count++;
                    }
                    curDate = curDate + 24 * 60 * 60 * 1000
                }
                return count;
            }
            const diff = getBusinessDatesCount(date1, date2)
            if (diff === 0) {
                return [
                    {
                        tag: 'div',
                        class: 'taskName',
                        html: StringHelper.encodeHtml(taskRecord.name)
                    }
                ]
            } else {
                return [
                    {
                        tag: 'div',
                        class: 'taskName',
                        html: StringHelper.encodeHtml(taskRecord.name)
                    },
                    {
                        tag: 'div',
                        class: 'gantt_task_delta_marker',
                        text: diff,
                        role: 'presentation'
                    }
                ]
            }

        } else {
            return [
                {
                    tag: 'div',
                    class: 'taskName',
                    html: StringHelper.encodeHtml(taskRecord.name)
                }
            ]
        }

    }
}
};

in 'rowReorderFeature' ->gridRowDrag function give me wrong parentIndex this function is giving existing parentIndex value not changed position value is there any function can provide me the correct parentIndex or changed parentindex. Please let me know


Post by alex.l »

It won't be available in there, because ProjectModel needs to be recalculated to have these changes.
gantt.project.changes will have these changes, but only on https://bryntum.com/docs/gantt/api/Gantt/model/ProjectModel#event-dataReady

    project : {
        transport      : {
            load : {
                url : '../_datasets/launch-saas.json'
            }
        },
        autoLoad : true,

    // ...

    listeners : {
        dataReady() {
            console.log('dataReady', gantt.project.changes?.tasks?.updated);
        }
    }
},

All the best,
Alex


Post Reply