Our pure JavaScript Scheduler component


Post by eugenem »

I've got now a single SchedulerPro with 2 resource groups: staff and facilities. Something like this:

    this.projectModel = new ProjectModel({
      resourceStore: {
        // Add some custom fields
        groupers: [
          // type could be 'Machines', 'Operators', etc
          { field: 'type', ascending: true }
        ]
      },
      eventStore: {
        // Add a custom field and redefine durationUnit to default to hours
        //fields: ['dt', { name: 'durationUnit', defaultValue: 'hour' }]
        fields: ['companyId']
      },
      autoLoad: true,
      autoSync: true,
      phantomIdField: 'phantomId',
      transport: {
        load: {
          url: '/api/Scheduler/GetB',
          headers: {
            'Authorization': `Bearer ` + token
          },
        },
        sync: {
          url: '/api/Scheduler/SaveB',
          headers: {
            'Authorization': `Bearer ` + token
          },
        }
      },
      listeners: {
        sync: () => {
          this.loadProject();
        }
      }
    });

I was asked to replace it with two synced schedulers, side by side: one with staff, another with facilities. I'm not sure how to do this. If I give them both the same project, resources will be filtered at both schedulers at once. And if I make 2 projects, how to sync them?


Post by eugenem »


Post by Maxim Gorkovsky »

Hello.
This is an interesting request. Certainly single project is not enough. You could probably do it with 2 projects (or even 3) and chained stores.

In case of 3 projects, you can try having one main project instance with all the data, and for views you can try project with chained stores. Like:

const mainProject = new ProjectModel( /* your project from the first snippet here */)

// next two projects shouldn't have any autoload/autosync or even transport layer
const schedulerProject1 = new ProjectModel({
  eventStore : mainProject.eventStore,
  assignmentStore : mainProject.assignmentStore,
  dependencyStore : mainProject.dependencyStore,
  resourceStore : mainProject.resourceStore.chain(...) // use filter for the resource type
})
const schedulerProject2 = new ProjectModel({
  ...,
  resourceStore : mainProject.resourceStore.chain(...) // use filter for another resource type
})

Chained stores share record instances with the main store, which makes two projects serve as views of the data from the main project. And when you change the data you should load/sync main project only.

2 projects should work too (chained stores do not care about filters in the main store).


Post by eugenem »

I've tried. 3 projects seem to work. But once I add scheduler1.addPartner(scheduler2), it fails in VERTICAL mode. Horizontal is working fine.

There is the error:

TimeAxisBase.js:179 Uncaught TypeError: Cannot read property 'forEach' of undefined
    at VerticalTimeAxis.refresh (TimeAxisBase.js:179)
    at VerticalTimeAxis.render (TimeAxisBase.js:156)
    at VerticalTimeAxisColumn.renderer (vendor.js:226894)
    at Row.renderCell (Row.js:593)
    at Row.render (Row.js:470)
    at RowManager.renderFromRow (RowManager.js:796)
    at RowManager.refresh (RowManager.js:871)
    at SchedulerPro.refreshRows (GridBase.js:2354)
    at SchedulerPro.refreshRows (TimelineBase.js:1428)
    at TimeAxisColumn.onViewModelUpdate (TimeAxisColumn.js:247)

Post by eugenem »

I've tried at your sample: it doesn't fail in vertical mode, but doesn't sync either.


Post by eugenem »

Another thing: it doesn't actually show any events. Can't even add anything. There is init code:

    this.projectModel1 = new ProjectModel({
      eventStore: this.projectModel.eventStore,
      assignmentStore: this.projectModel.assignmentStore,
      dependencyStore: this.projectModel.dependencyStore,
      resourceStore: this.projectModel.resourceStore.chain(x => x.type == "facility", [], {}) // use filter for the resource type
    });

this.projectModel2 = new ProjectModel({
  eventStore: this.projectModel.eventStore,
  assignmentStore: this.projectModel.assignmentStore,
  dependencyStore: this.projectModel.dependencyStore,
  resourceStore: this.projectModel.resourceStore.chain(x => x.type == "staff", [], {}) // use filter for the resource type
});


Post by eugenem »

actually, even if I leave the original scheduler linked to projectModel, this line hides all events:

this.projectModel1 = new ProjectModel({...})

Post by Maxim Gorkovsky »

eugenem wrote: Tue Jul 20, 2021 4:11 pm

I've tried. 3 projects seem to work. But once I add scheduler1.addPartner(scheduler2), it fails in VERTICAL mode. Horizontal is working fine.

There is the error:

TimeAxisBase.js:179 Uncaught TypeError: Cannot read property 'forEach' of undefined
    at VerticalTimeAxis.refresh (TimeAxisBase.js:179)
    at VerticalTimeAxis.render (TimeAxisBase.js:156)
    at VerticalTimeAxisColumn.renderer (vendor.js:226894)
    at Row.renderCell (Row.js:593)
    at Row.render (Row.js:470)
    at RowManager.renderFromRow (RowManager.js:796)
    at RowManager.refresh (RowManager.js:871)
    at SchedulerPro.refreshRows (GridBase.js:2354)
    at SchedulerPro.refreshRows (TimelineBase.js:1428)
    at TimeAxisColumn.onViewModelUpdate (TimeAxisColumn.js:247)

Are you trying to make horizontal and vertical schedulers partners? I don't think we support this config. Partners are meant to sync horizontal scroll and region sizes, I don't see how that would apply to vertical and horizontal schedulers.
What result are you trying to achieve?


Post by eugenem »

I'm trying 2 verticals of course


Post by Maxim Gorkovsky »

Speaking of chaining stores, I tried 3 projects on our partners demo, it worked for me like this:

const project = window.project = new ProjectModel({
    eventsData    : events,
    resourcesData : resources
});

const project1 = new ProjectModel({
    eventStore      : project.eventStore,
    assignmentStore : project.assignmentStore.chain(r => true),
    resourceStore   : project.resourceStore.chain(r => r.name.match(/H/))
});

const project2 = new ProjectModel({
    eventStore      : project.eventStore,
    assignmentStore : project.assignmentStore.chain(r => true),
    resourceStore   : project.resourceStore.chain(r => !r.name.match(/H/))
});

I can see all events, drag them and then read changes from the main project.


Post Reply