Our pure JavaScript Scheduler component


Post by probo »

Hello everyone,

I was wondering if it's possible to "refresh" the resourceStore with a new set of data without losing any connection to the events.

So let's say we start with a list of resources, change it trough some ajax call and use the response to give the resourceStore a new dataset, like this:

scheduler.resourceStore.data = response;

.. and let's say you have like a button which resets to the original resourceStore dataset, by again using:

scheduler.resourceStore.data = originalDataSet

In my project, the connection between the events and it's resources are now gone using this method. Is there any solution to make this work?

Thanks in advance,
probo


Post by mats »

So let's say we start with a list of resources, change it trough some ajax call and use the response to give the resourceStore a new dataset, like this:

Try setting https://bryntum.com/docs/scheduler/api/Core/data/mixin/StoreSync#config-syncDataOnLoad on your resource store?


Post by probo »

Unfortunately this did not work for me. This is the code i'm working with:

project: {
    assignmentStore: {
    },
    eventStore: {
    },
    resourceStore: {
    },
    validateResponse: true,
    transport: {
        load: {
            url: 'print-planning/plannable-items' // <-- initial assignments, events and resources are loaded here
        },
        sync: {
            url: 'print-planning/plannable-items/sync',
        },
    },
    autoLoad: true,
    autoSync: true,
}

And a change listener on combo

listeners: {
    change(data) {
        const scheduler = this.parent.parent;
        const resourceStore = scheduler.resourceStore;
        const id = data.value;

    AjaxHelper.get('/print-planning/production-unit/' + id).then(response => {
        response.json().then(output => {
            resourceStore.data = output.data;
        });
    });
}
}

In the code section mentioned above, i just want everything to be in sync when i update my resources (so my events linked to the current loaded resources and it's assignments etc..). But it ain't loading my events when i use the combo box to switch resources. When using syncDataOnLoad it also did not work. How can i solve this?

Follow up:

resourceStore.removeAll();
resourceStore.add(output.data);

When using removeAll() and add(), it essentialy starts a new sync and does what it's suppose to do, but just partially, because removeAll() also removes all the events that are related to the resource and this is just what i want to prevent, it needs to keep the events intact.

Thanks in advance.

probo


Post by johan.isaksson »

Hi,

Which version are you using? I recommend trying on the newest version, there has been some fixes released for the syncDataOnLoad behaviour recently.

Normally when you remove a resource, its assignments and events are also removed. But when stores are configured with syncDataOnLoad that should not happen when you assign to resourceStore.data (it should still happen if you call resourceStore.removeAll().

Best regards,
Johan Isaksson

Post by probo »

johan.isaksson wrote: Wed May 04, 2022 10:16 am

Hi,

Which version are you using? I recommend trying on the newest version, there has been some fixes released for the syncDataOnLoad behaviour recently.

Normally when you remove a resource, its assignments and events are also removed. But when stores are configured with syncDataOnLoad that should not happen when you assign to resourceStore.data (it should still happen if you call resourceStore.removeAll().

So i was using 5.0.1 and upgraded it on your advice, it works a bit better, but it seems like the assignmentstore isn't updating even on initial load (at least in 5.0.1 the data in the assignment store seems empty).

Using the code below and moving back and forth between values in the combo box, the assignment store seems to lose it's data... it seems like unexpected behaviour.

AjaxHelper.get('/print-planning/production-unit/' + id, {
    parseJson: true
}).then(output => {
    resourceStore.data = output.parsedJson.data;
});

I solved this by using the following piece of code

{
    type: 'combo',
    displayField: 'name',
    valueField: 'id',
    store: new AjaxStore({
        readUrl: '/print-planning/production-lines',
        autoLoad: true,
    }),
    listeners: {
        change(data) {
            const scheduler = this.parent.parent;
            const assignmentStore = scheduler.assignmentStore;
            const resourceStore = scheduler.resourceStore;
            const id = data.value;

        resourceStore.readUrl = '/print-planning/production-unit/' + id;
        resourceStore.load().then(() => {
            const initialData = JSON.parse(localStorage.getItem('probo.scheduler.initial_data'));
            if (initialData && initialData.hasOwnProperty('assignments')) {
                assignmentStore.data = initialData.assignments.rows;
            }
        });
    }
}
},

Could you confirm that this thing with the assignment store is a bug? I don't particularly like my solution.

Thanks in advance.

probo


Post by johan.isaksson »

Have you got all the stores configured with syncDataOnLoad: true?

Best regards,
Johan Isaksson

Post by probo »

johan.isaksson wrote: Wed May 04, 2022 11:25 am

Have you got all the stores configured with syncDataOnLoad: true?

I tried it with the following code:

project: {
    resourceModelClass: ProductionUnit,
    assignmentStore: {
        syncDataOnLoad: true,
        readUrl: 'print-planning/assignments',
        autoLoad: true
    },
    eventStore: {
        syncDataOnLoad: true,
        fields: [
            'dt',
            {
                name: 'durationUnit',
                defaultValue: 'minute'
            },
            {
                name: 'sourceData',
                defaultValue: {}
            },
            'type',
        ]
    },
    resourceStore: {
        syncDataOnLoad: true,
        modelClass: ProductionUnit
    },
    validateResponse: true,
    transport: {
        load: {
            url: 'print-planning/plannable-items'
        },
        sync: {
            url: 'print-planning/plannable-items/sync',
        },
    },
    autoLoad: true,
    autoSync: true,
},

and

{
    type: 'combo',
    displayField: 'name',
    valueField: 'id',
    store: new AjaxStore({
        readUrl: '/print-planning/production-lines',
        autoLoad: true,
    }),
    listeners: {
        change(data) {
            const scheduler = this.parent.parent;
            const resourceStore = scheduler.resourceStore;
            const id = data.value;

        AjaxHelper.get('/print-planning/production-unit/' + id, {
            parseJson: true
        }).then(output => {
            resourceStore.data = output.parsedJson.data;
        });
    }
}
},

This did not work for me. Maybe worth mentioning that the first time the combo box is called it works fine. So let's say you have the following case:

Load Resources 1
Load Resources 2

First click on Load Resources 1, it loads resources 1, click on load resources 2, it loads resources 2, click on load resources 1 again, then all events are gone. If you update the assignment store with new data, the events return.

Kind regards,
probo


Post by johan.isaksson »

Only strange thing I am seeing in your code is that you are using a combination of CrudManager and AjaxStore, that is unexpected (you have a readUrl in the assignmentStore config, intention for CrudManager is to load data to all stores when it is used).

If you try without that and it does not work you might have run into some bug with syncDataOnLoad. It would help us to track it down if you could supply a test case that reproduces the issue. You could perhaps add your custom code to one of our examples and use two inline datasets for resources or similar.

Best regards,
Johan Isaksson

Post by probo »

johan.isaksson wrote: Wed May 04, 2022 1:21 pm

Only strange thing I am seeing in your code is that you are using a combination of CrudManager and AjaxStore, that is unexpected (you have a readUrl in the assignmentStore config, intention for CrudManager is to load data to all stores when it is used).

If you try without that and it does not work you might have run into some bug with syncDataOnLoad. It would help us to track it down if you could supply a test case that reproduces the issue. You could perhaps add your custom code to one of our examples and use two inline datasets for resources or similar.

Hello, i've prepared a test case, this is scheduler pro 5.0.3.
My project settings:

project: {
    resourceModelClass: ProductionUnit,
    assignmentStore: {
        syncDataOnLoad: true
    },
    eventStore: {
        syncDataOnLoad: true,
    },
    resourceStore: {
        syncDataOnLoad: true
    },
    validateResponse: true,
    transport: {
        load: {
            url: 'print-planning/plannable-items'
        },
        sync: {
            url: 'print-planning/plannable-items/sync',
        },
    },
    autoLoad: true,
    autoSync: true,
},

Here is the output from the plannable items load:

{
  "assignments": {
    "rows": [
      {
        "id": 4,
        "resourceId": 39,
        "eventId": 4
      }
    ]
  },
  "events": {
    "rows": [
      {
        "dt": "2022-05-06 09:28:36",
        "id": 4,
        "duration": 30.5,
        "name": "131213876543_1649941726338",
        "type": "nest",
        "startDate": "2022-05-06 09:32:00"
      }
    ]
  },
  "resources": {
    "rows": []
  },
  "success": true,
  "timeRanges": {
    "rows": []
  }
}

And then i have a combo box in the tbar, which switches between resources

{
    type: 'combo',
    displayField: 'name',
    valueField: 'id',
    store: [
        {
            id: 3,
            name: 'Sublimation'
        },
        {
            id: 5,
            name: 'Sheet'
        }
    ],
    listeners: {
        change(data) {
            const resourceStore = this.parent.parent.resourceStore;
            resourceStore.readUrl = '/print-planning/production-unit/' + data.value;
            resourceStore.load();
        }
    }
},

Here are the outputs between of ID 3 and 5

[
  {
    "unit": 2,
    "production_lines": [
      3
    ],
    "groups": [
      1
    ],
    "id": 8,
    "code": "eurolaser-1",
    "name": "Eurolaser #1",
    "resource_id": 8
  },
  {
    "unit": 2,
    "production_lines": [
      3
    ],
    "groups": [
      1
    ],
    "id": 9,
    "code": "eurolaser-2",
    "name": "Eurolaser #2",
    "resource_id": 9
  }
]

and 5

[
  {
    "unit": 1,
    "production_lines": [
      5
    ],
    "groups": [
      8
    ],
    "id": 39,
    "code": "durst-p5-210-1",
    "name": "Durst P5 210 -1",
    "resource_id": 39
  },
  {
    "unit": 1,
    "production_lines": [
      5
    ],
    "groups": [
      8
    ],
    "id": 40,
    "code": "durst-p5-210-2",
    "name": "Durst P5 210 -2",
    "resource_id": 40
  }
]

If you switch between submilation and sheet in the combo box, you want be able to see the event that is linked to resource 39.

Kind regards,
probo


Post by alex.l »

Hi probo,

I don't see you removed load/sync URLs from crudManager as Johan adviced and use AjaxStore together with crudManager load calls, so this is one of potential problems.
You used custom field names (resource_id) so please post Resource model code as well (I mean ProductionUnit).
It will be great if you just zip and attach a runnable test case with JSON examples you used for it. We need to reproduce the problem to help you with that. For now it just works in case we update resources using our examples.

Thank you!

All the best,
Alex


Post Reply