Our state of the art Gantt chart


Post by glcark »

I am currently running into an issue with the undo implementation.
Initially this task is added.

{"type":"sync","requestId":16063416098701,"tasks":{"added":[{"parentIndex":0,"startDate":"2020-11-10T00:00:00-05:00","endDate":"2020-11-19T06:00:00-05:00","duration":9.25,"durationUnit":"day","cls":"","name":"New task 1","direction":"Forward","manuallyScheduled":false,"constraintType":null,"constraintDate":null,"percentDone":0,"effort":222,"effortUnit":"hour","effortDriven":false,"schedulingMode":"Normal","baselines":[],"parentId":28167,"type":"task","$PhantomId":"_generatedClassDefEx1"}]}}

Here is the response from the server:

{"type":"sync","requestId":16063416098701,"revision":0,"tasks":{"rows":[{"$PhantomId":"_generatedClassDefEx1","id":28169,"parentId":28167,"type":"task"}]},"success":true}

All works well until I try to undo the add. The id is still relying on the old phantomid, not the new generated id that the server responded with.

{"type":"sync","requestId":16063416162634,"revision":2,"tasks":{"removed":[{"id":"_generatedClassDefEx1"}]}}

Is this the expected behaviour?


Post by pmiklashevich »

STM cannot revert saved records. Once you sync changes with backend please resetQueue. Please check out how we handle it in our PHP demo
Gantt/examples/php/lib/BackendTools.js

        gantt.project.on({
            load       : me.onAfterLoadSync,
            sync       : me.onAfterLoadSync,
            
...... onAfterLoadSync() { // since we load all the stores data from the server // we reset undo/redo queue (it no longer makes sense) this.stm.disable(); this.stm.resetQueue(); this.stm.enable(); }

We will update STM docs.

Pavlo Miklashevych
Sr. Frontend Developer


Post by pmiklashevich »

I've opened a feature request to improve the STM: https://github.com/bryntum/support/issues/1976

Pavlo Miklashevych
Sr. Frontend Developer


Post by glcark »

That's disappointing. I am using autosync, so according to your response I am unable to use undo/redo at all.
It seems like the majority of the undo/redo functionality works with my setup however.

Is there anyway for me to update the phantom ids in the stm after a sync response?


Post by arcady »

You can debug the code to implement any custom behaviour you need. That's doable for sure.
I would start with checking State Tracking Manager (STM) code in lib/Core/data/stm folder.

In this case as far as I understand you just need to tell STM to ignore id field changes to avoid undoing identifier back to its phantom state.
Unfortunately there is no easy public way of doing this at the moment.

Here is an example of how it could be done w/ private methods overriding:

export default class Task extends TaskModel {

    // Override beforeSet() method used by STM to collect model changes when model.set() is called
    beforeSet() {
        const result = super.beforeSet(...arguments);

        // sanitize id changes
        result.forEach(entry => {
            delete entry[0].id;
            delete entry[1].id;
        });

        return result;
    }

    // Override afterSet() method that is used by STM to process data collected in beforeSet()
    afterSet(field, value, silent, fromRelationUpdate, beforeResult, wasSet) {
        const
            stm = this.stm,
            // changes collected in beforeSet()
            preResult = beforeResult[beforeResult.length - 1];

        let stmDisabled;

        // if STM is enabled and there was a change and changes collected in beforeSet() is not empty
        if (stm && !stm.disabled && wasSet && ObjectHelper.isEmpty(preResult[0])) {
            // disable STM
            stm.disabled = true;
            stmDisabled = true;
        }

        const result = super.afterSet(field, value, silent, fromRelationUpdate, beforeResult, wasSet);

        // re-enable STM back
        if (stmDisabled) {
            stm.disabled = false;
        }

        return result;
    }
    ...

Since the above workaround uses private methods I'd still recommend you to wait till the ticket is resolved.


Post by glcark »

Would it be possible to update the STM after a sync has happened and replace all occurrences of phantom ids with the returned id from the server?


Post by arcady »

STM is updated when the response comes ..that's the problem. It records that id-change operation.
And when you request to undo it changes the record id back to its old phantom value.
The patch I've posted solves that ..yet it needs polishing of course.


Post Reply