Premium support for our pure JavaScript UI components


Post by jamesb »

Hello,

I believe I'm not using the right mechanism to sync changes, and would be happy to get some advice from you. :)

Our implementation updates our data source by processing crudManager.changes. It works perfectly when this update happens once, after users are done with all their changes.

However, if we update the data source after each transaction, and users undo transactions, then crudManager.crudStoreHasChanges() could return false (as it reverted to the initial state).
In that case, the transaction that initially triggered a data update (Event A start + 1h), doesn't trigger a data update when it is undone (Event A start - 1h).

Could you please point me in the right direction for correctly synching changes after each transaction?

Thank you,
J


Post by alex.l »

Hi J,

What exactly should I do to reproduce that? I see both: 'change' and 'update' events triggered.
Here is the code you can paste into undoredo example to test:

import '../_shared/shared.js'; // not required, our example styling etc.
import Scheduler from '../../lib/Scheduler/view/Scheduler.js';
import '../../lib/Grid/column/TreeColumn.js';
import '../../lib/Grid/column/NumberColumn.js';
import '../../lib/Grid/feature/Tree.js';
import '../../lib/Scheduler/feature/TimeRanges.js';
import '../../lib/Scheduler/feature/Dependencies.js';
import ResourceModel from '../../lib/Scheduler/model/ResourceModel.js';
import EventModel from '../../lib/Scheduler/model/EventModel.js';
import DependencyModel from '../../lib/Scheduler/model/DependencyModel.js';
import StringHelper from '../../lib/Core/helper/StringHelper.js';
import '../../lib/Scheduler/widget/UndoRedo.js';

class Gate extends ResourceModel {
    static get fields() {
        return [
            'capacity'
        ];
    }
}

const scheduler = new Scheduler({
    appendTo : 'container',

features : {
    tree         : true,
    regionResize : true,
    dependencies : true
},

rowHeight : 45,
barMargin : 5,

columns : [
    {
        type  : 'tree',
        text  : 'Name',
        width : 200,
        field : 'name'
    }, {
        type  : 'number',
        text  : 'Capacity',
        width : 80,
        field : 'capacity'
    }
],

startDate          : new Date(2017, 11, 2, 8),
viewPreset         : 'hourAndDay',
enableUndoRedoKeys : true,
crudManager        : {
    autoLoad      : true,
    resourceStore : {
        modelClass : Gate
    },
    transport : {
        load : {
            url : 'data/data.json'
        }
    },
    // This config enables response validation and dumping of found errors to the browser console.
    // It's meant to be used as a development stage helper only so please set it to false for production systems.
    validateResponse : true
},

// Scheduler always has a Project instance internally, we need to configure its internal StateTrackingManager
// so that the UndoRedo widget gets customized titles in its transaction dropdown.
project : {
    stm : {
        autoRecord : true,

        getTransactionTitle(transaction) {
            const lastAction = transaction.queue[transaction.queue.length - 1];

            let { type, model } = lastAction;

            if (lastAction.modelList && lastAction.modelList.length) {
                model = lastAction.modelList[0];
            }

            let title = 'Transaction ' + this.position;

            if (type === 'UpdateAction' && model instanceof EventModel) {
                title = 'Edit flight ' + model.name;
            }
            else if (type === 'UpdateAction' && model instanceof ResourceModel) {
                title = 'Edit gate ' + model.name;
            }
            else if (type === 'RemoveAction' && model instanceof EventModel) {
                title = 'Remove flight ' + model.name;
            }
            else if (type === 'RemoveAction' && model instanceof ResourceModel) {
                title = 'Remove gate ' + model.name;
            }
            else if (type === 'AddAction' && model instanceof EventModel) {
                title = 'Add flight ' + model.name;
            }
            else if (type === 'AddAction' && model instanceof DependencyModel) {
                title = StringHelper.xss`Link ${model.fromEvent.name} -> ${model.toEvent.name}`;
            }

            return title;
        }
    }
},

eventRenderer({ eventRecord, resourceRecord, renderData }) {
    renderData.iconCls = 'b-fa b-fa-plane';

    if (resourceRecord.isLeaf) {
        renderData.eventColor = 'blue';

        return StringHelper.encodeHtml(eventRecord.name);
    }
    else {
        renderData.eventColor = 'orange';
        return '';
    }
},

tbar : [{
    type  : 'undoredo',
    icon  : 'b-fa-undo',
    items : {
        transactionsCombo : {
            width : 250,
            displayValueRenderer(value, combo) {
                const stmPos = combo.up('panel', true).project.stm.position || 0;

                return stmPos + ' undo actions / ' + (this.store.count - stmPos) + ' redo actions';
            }
        }
    }
}]
});


scheduler.eventStore.on('change', ()=>{console.log('changed')});
scheduler.eventStore.on('update', ()=>{console.log('updated')});

Here is the video

Screen Recording 2023-02-03 at 08.59.26.mov
(6.14 MiB) Downloaded 19 times

All the best,
Alex


Post by jamesb »

Hi Alex,

Thank you for your answer!
I realized that I was simply missing a call to cm.acceptChanges(), which correctly re-synchronizes the cm tracking with the state at my last data update.

I'm leveraging this post to raise an issue with the undo-redo example at https://bryntum.com/products/schedulerpro/examples-scheduler/undoredo/:
It is not pretty-printed (all in 10 lines), and any edit (even adding a space) triggers an error. I haven't seen this issue on other examples.

undoredo.png
undoredo.png (123.26 KiB) Viewed 211 times

Thank you,
J


Post by marcio »

Hey James,

Instead of adding that code to the online demo, try to add it to your example source code and run it locally, I tested also and it's working correctly.

Best regards,
Márcio


Post Reply