disable "resourceField" which is used by default for all resources
create 2 new combos
chain the resources and get just machines for one combo and operators for the other combo
Select corresponding resources on load
Save selected resources in both combos as multiassignment
Have you managed to do this? If no, please let me know what exactly is hard to do and I'll try to help you.
But at calendar I want to have one column with groups, like at sample
You probably mean locked part of the scheduler (left side). You just need to group resource store by the field which is responsible for the resource type. For example:
new SchedulerPro({
resourceStore : {
groupers : [
// type could be 'Machines', 'Operators', etc
{ field : 'type', ascending : false }
]
}
})
I think there is some confusion. Your sample has a single list of resources of different types. But my data structure has 2 types of resources, and they have the same ids.
Yes, sorry. I was confused by the event editor configuration you requested. Now, when you revealed the data structure, it's clear what you're trying to achieve. Unfortunately, Scheduler does not support having multiple resource stores. So you need to merge the data of 2 sources in one resource store. You can create simple AjaxStore for each entity: machines and operators. Load the data and then merge it in one dataset by mapping the IDs to a prefix + id. For example:
// Machine "{ id : 1, name : 'Assembly station' }" to "{ id : 'M_1', type : 'machines', name : 'Assembly station' }"
// Operator "{ id : 1, name : 'Celia' }" to "{ id : 'O_1', type : 'operators', name : 'Celia' }"
Since you need multi assignment, you need to create an AssignmentStore and describe connections between events and resources (mapped machines and mapped operators).
Here is a small example showing the combination of machines and operators, and customized event editor which has 2 different pickers for machines and resources. I made machines with single select assuming that one machine can work for a task, and I made operators with multi select assuming more than one specialist can operate one machine. But that could be easily changed. I made it this way to show you different options. Please try the following code in "scheduler/examples/multiassign/" demo locally (Scheduler/examples/multiassign/app.js):
import '../_shared/shared.js'; // not required, our example styling etc.
import Scheduler from '../../lib/Scheduler/view/Scheduler.js';
import ResourceStore from '../../lib/Scheduler/data/ResourceStore.js';
import '../../lib/Scheduler/column/ResourceInfoColumn.js';
//region Data
const
machines = [
{ id : 1, name : 'Assembly station' },
{ id : 2, name : 'Workstation' }
],
operators = [
{ id : 1, name : 'Celia' },
{ id : 2, name : 'Lee' },
{ id : 3, name : 'Macy' }
],
resources = [
...machines.map(m => ({ ...m, id : 'M_' + m.id, type : 'machines' })),
...operators.map(m => ({ ...m, id : 'O_' + m.id, type : 'operators' }))
],
events = [
{
id : 1,
startDate : new Date(2017, 0, 1, 10),
endDate : new Date(2017, 0, 1, 12),
name : 'Multi operators',
iconCls : 'b-fa b-fa-users'
},
{
id : 2,
startDate : new Date(2017, 0, 1, 13),
endDate : new Date(2017, 0, 1, 15),
name : 'Single operator',
iconCls : 'b-fa b-fa-user',
eventColor : 'indigo'
}
],
assignments = [
{ id : 1, resourceId : 'O_1', eventId : 1 },
{ id : 2, resourceId : 'M_1', eventId : 1 },
{ id : 3, resourceId : 'O_2', eventId : 1 },
{ id : 4, resourceId : 'O_8', eventId : 1 },
{ id : 5, resourceId : 'O_3', eventId : 2 },
{ id : 6, resourceId : 'M_2', eventId : 2 }
];
const resourceStore = new ResourceStore({
data : resources
});
const machineStore = resourceStore.makeChained(
record => !record.isSpecialRow && record.type === 'machines',
null,
{
// Need to show all records in the combo. Required in case resource store is a tree.
excludeCollapsedRecords : false
}
);
const operatorStore = resourceStore.makeChained(
record => !record.isSpecialRow && record.type === 'operators',
null,
{
// Need to show all records in the combo. Required in case resource store is a tree.
excludeCollapsedRecords : false
}
);
//endregion
const scheduler = new Scheduler({
features : {
group : 'type',
eventEdit : {
editorConfig : {
align : 't-b'
},
items : {
resourceField : false,
machines : {
label : 'Machines',
type : 'combo',
store : machineStore,
name : 'machines',
valueField : 'id',
displayField : 'name',
multiSelect : false,
weight : 210,
highlightExternalChange : false
},
operators : {
label : 'Operators',
type : 'combo',
store : operatorStore,
name : 'operators',
valueField : 'id',
displayField : 'name',
multiSelect : true,
weight : 220,
highlightExternalChange : false
}
}
}
},
listeners : {
// load values to the machines and to the operators manually
beforeEventEditShow({ eventRecord, editor }) {
const { machines, operators } = editor.widgetMap;
machines.value = eventRecord.resources.filter(r => r.type === 'machines');
operators.value = eventRecord.resources.filter(r => r.type === 'operators');
},
// save values manually
beforeEventSave({ eventRecord, values, resourceRecords }) {
const selectedMachines = [values.machines]; // single select
const selectedOperators = values.operators; // multi select
const selectedResourceIds = [...selectedMachines, ...selectedOperators];
// Assigning resources to event does not work here, because event editor reassigns the resources internally.
// Therefore mutate the resourceRecords param which is used internally.
const selectedResources = eventRecord.resourceStore.query(record => selectedResourceIds.includes(record.id), true);
resourceRecords.splice(0, resourceRecords.length, ...selectedResources);
}
},
appendTo : 'container',
minHeight : '20em',
startDate : new Date(2017, 0, 1, 6),
endDate : new Date(2017, 0, 1, 20),
viewPreset : 'hourAndDay',
eventStyle : 'border',
resourceImagePath : '../_shared/images/users/',
columns : [
{ type : 'resourceInfo', text : 'Name', field : 'name', width : 130 }
],
resourceStore,
events,
assignments
});
Here is the result:
Снимок экрана 2021-01-20 в 12.55.57.png (347.01 KiB) Viewed 1401 times
Please let me know if this solves your issue. If you have any further questions, fell free to ask and we will try to help you.
Indeed, I didn't take into account drag creating events. Please try out this code:
listeners : {
// load values to the machines and to the operators manually
beforeEventEditShow({ eventRecord, resourceRecord, editor }) {
const { machines, operators } = editor.widgetMap;
// if there is no resources assigned to event fall back to the passed resource which is set on drag create
const resources = eventRecord.resources?.length ? eventRecord.resources : (resourceRecord ? [resourceRecord] : []);
machines.value = resources.filter(r => r.type === 'machines');
operators.value = resources.filter(r => r.type === 'operators');
},
// save values manually
beforeEventSave({ source : scheduler, eventRecord, values, resourceRecords }) {
const selectedMachines = [values.machines]; // single select
const selectedOperators = values.operators; // multi select
const selectedResourceIds = [...selectedMachines, ...selectedOperators];
// Assigning resources to event does not work here, because event editor reassigns the resources internally.
// Therefore mutate the resourceRecords param which is used internally.
const selectedResources = scheduler.resourceStore.query(record => selectedResourceIds.includes(record.id), true);
resourceRecords.splice(0, resourceRecords.length, ...selectedResources);
}
},