Our pure JavaScript Scheduler component


Post by jk@datapult.dk »

Sure, thanks. Devs and consumers are in a team effort to improve the product..

My issues doesn't stop as laid out over the course of my two threads because if I give each scheduler a separate crudmanager, upon dragging an event from one scheduler to another the first crudmanager send a "removed" to the backend while the second does nothing.

Can someone kindly advise or exsmplify how to work around this?


Post by jk@datapult.dk »

This is actually what this thread was about as pr my initial post on the thread..


Post by alex.l »

while the second does nothing.

Did you use different dataset initially loaded or same with different filters applied? In second case it might be that event you dropped already exists in a store. Filtered not equal removed.

Please check an example, I briefly applied basic changes to example you posted to have crudManger for bottom scheduler to emulate your case.
Try to drag event from top scheduler and drop to bottom one.

In your case you'll be needed to add crudManager for top instance too, I don't have API with different data so I used static dataset for second instance.

import { Scheduler, Splitter, CrudManager} from '../../build/scheduler.module.js?463519';
import shared from '../_shared/shared.module.js?463519';

const cookie = 'PHPSESSID=scheduler-crudmanager';
if (!(document.cookie.includes(cookie))) {
    document.cookie = `${cookie}-${Math.random().toString(16).substring(2)}`;
}



const scheduler = new Scheduler({
    appendTo   : 'container',
    startDate  : new Date(2018, 4, 21, 6),
    endDate    : new Date(2018, 4, 21, 18),
    viewPreset : 'hourAndDay',
    eventColor : 'orange',
    eventStyle : 'colored',
features: {
eventDrag : {
            // Allow drag outside of this Scheduler
            constrainDragToTimeline : false
        },
},
    syncMask : null,
    loadMask : null,
    columns : [{ text : 'Car', field : 'car', width : 150 },],
    events: [{dt: "2022-11-27 06:59:00", 

duration: 2,

id: 44,
resourceId : 1,
name: "Serve engine",

startDate: "2018-05-21 08:00"

}],
    resources: [{car: "Volvo V90",dt: "2022-11-27 06:59:00",id: 1

}]
});

new Splitter({appendTo : 'container'});

const scheduler2 = new Scheduler({
    ref               : 'bottom-scheduler',
    cls               : 'bottom-scheduler',
    appendTo          : 'container',
    flex              : '1 1 50%',
    partner           : scheduler,
    hideHeaders       : true,
    resourceImagePath : '../_shared/images/users/',
    columns : [{ text : 'Car', field : 'car', width : 150 },],
    crudManager : {
        resourceStore : {
            fields : ['car', 'dt']
        },

    eventStore : {
        fields : ['dt', { name : 'durationUnit', defaultValue : 'hour' }]
    },

    validateResponse : true,

    transport : {
        load : {
            url       : 'php/read.php',
            paramName : 'data'
        },
        sync : {
            url : 'php/sync.php'
        }
    },

    autoLoad      : true,
    autoSync      : true,
}
});window.scheduler2 = scheduler2; window.cm = cm;


All the best,
Alex


Post by jk@datapult.dk »

Thanks, Alex.

alex.l wrote: Sun Nov 27, 2022 10:15 am

Did you use different dataset initially loaded or same with different filters applied? In second case it might be that event you dropped already exists in a store. Filtered not equal removed.

As you can see in the working example of my original post on this thread, I am using two separate (but identical) CrudManagers for each scheduler. Just try my code by pasting into https://bryntum.com/products/scheduler/examples/crudmanager/.

alex.l wrote: Sun Nov 27, 2022 10:15 am

Please check an example, I briefly applied basic changes to example you posted to have crudManger for bottom scheduler to emulate your case. Try to drag event from top scheduler and drop to bottom one.

As you can see in the working example of my original post on this thread, I dumping the sync requests from each CrudManager in the console. I have also described what is wrong with that behavior and what is expected behavior. Needless to say, I should be able to drag from any one scheduler to the other and what I am still asking for is: Which events do I listen to and how do I intercept/change so that no "removed" request is sent but just one "changed" request. Just try my code by pasting into https://bryntum.com/products/scheduler/examples/crudmanager/.

alex.l wrote: Sun Nov 27, 2022 10:15 am

In your case you'll be needed to add crudManager for top instance too, I don't have API with different data so I used static dataset for second instance.

I have added CurdManagers to each instance ever since the first post on this thread.. Fortunately, I shared a working example of my original post on this thread that you can test on your own. Just try my code by pasting into https://bryntum.com/products/scheduler/examples/crudmanager/


Post by jk@datapult.dk »

For anyone who wants to use the same CrudManager with partnered schedulers that filter to different resources:

  1. You cannot share the same crudManager instance in 2 schedulers, since you can only filter the resources once (even with chained stores): https://github.com/bryntum/support/issues/5668
  2. If you, in turn, create a crudManager for each, you will A. incur the cost of two requests two the backend and B. Not be able to drag events between them as I laid in the first post on this thread.

I have made a solution to 2.B for anyone interested:

import type {Scheduler} from "@bryntum/scheduler";

const schedulers: Scheduler[] = [/* List of the partnered schedulers here*/]
const eventsToRegisterOnEachScheduler = {
        eventDragStart: ({source, eventRecords, assignmentRecords, startDate, endDate, newResource, context}) => {
            source.crudManager.on({
                beforeSync: ({pack}) => {
                    // Since the schedulers have their own CrudManager, the original
                    // scheduler wants to delete events dragged to the other scheduler
                    // This prevents that HTTP request from being sent
                    const cancelRequest = pack?.events?.removed?.length > 0 ?? false
                    if (cancelRequest) {
                        return false
                    }
                }
            })
        },
        eventDrop: ({context, eventRecords, source}) => {
            source.disableScrollingCloseToEdges(source.timeAxisSubGrid);
            const dragProxy = context.context.element
            dragProxy.remove()
            const events = []
            for (let i = 0; i < eventRecords.length; i++) {
                const event = eventRecords[i]
                event.startDate = context.startDate
                event.endDate = context.endDate
                event.assign(context.newResource)
                source.eventStore.add(event)
                console.log("Added", event)
            }
            schedulers.forEach(s => {
                // Reset the eventListener so that deletes can be issued again after disabling it on eventDragStart
                s.crudManager.listeners?.beforeload?.forEach(l => s.crudManager.un({beforeSync: l}))
            })
        }
    }

Post by marcio »

Thanks for sharing that solution jk!

Best regards,
Márcio


Post by Animal »

When that ticket is fixed, the incantation will be

        secondScheduler = t.getScheduler({
            id            : 'secondScheduler',
            partner       : firstScheduler,
            project : {
                eventStore    : firstScheduler.eventStore.chain(),
                resourceStore : firstScheduler.resourceStore.chain(r => r.id > 1)
            },
            ...config,
        });

The stores must be configured in the project, and both should be chained.

The fix will be in the next release, so your code will be much simpler soon.


Post by jk@datapult.dk »

Thanks, man! I'll update once released and let you know. Appreciate it! Wish you and the team a happy Monday!


Post Reply