Overview

  • In this tutorial, we will configure the Vue Scheduler component to accept tasks dragged from an ordered queue of unscheduled tasks.

  • The Queue component displays a list of unscheduled tasks. Users can change the task position/priority using drag and drop.

  • Tasks that have already been scheduled can be moved back to the queue using drag and drop.

License

Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript.

How to configure the Vue Scheduler for external drag and drop?

vue scheduler timeline grid

In the first step, we will add the Vue Scheduler component (from DayPilot Pro for JavaScript) to our application. To see an introduction to using the Scheduler component is Vue, please see the basic tutorial - Vue Scheduler: Build a Reservation Application in 5 Minutes. You’ll learn how to install the NPM package with Vue support, add the Scheduler component to the Vue application, load the data and set the configuration properties.

Our Scheduler component uses standard configuration generated by the UI Builder. To ensure interoperability with the Queue component, we need to make a few changes.

How to remove the tasks from the queue when they are dropped in the Scheduler?

You need to extend the onEventMoved event handler to cover the external drag and drop. In case that the tasks was dragged from the queue (args.external is set to true) we need to remove the task object from the source component using events.remove().

How to enable dragging the tasks back to queue?

By default, the tasks can only be moved to another location in the Vue Scheduler grid. To enable dragging tasks outside of the Scheduler, add dragOutAllowed: true to the config properties. The dragOutAllowed property will let users drag the tasks that have been already scheduled back to the queue. The queue always accepts the external item and there is no need to enable it.

What is needed to activate the Vue Scheduler?

Here are the important parts of the source code that make the Vue Scheduler working.

Template:

<template>
  <DayPilotScheduler id="scheduler" :config="config" ref="scheduler" />
  // ...
</template>

TypeScript:

<script lang="ts">
import {Component, Prop, Ref, Vue} from 'vue-property-decorator';
import {DayPilot, DayPilotQueue, DayPilotScheduler} from "daypilot-pro-vue";

@Component({
  components: {
    DayPilotScheduler,
    DayPilotQueue
  },
})
export default class Scheduler extends Vue {

  @Ref('scheduler') scheduler!: DayPilotScheduler;

  config: DayPilot.SchedulerConfig = {
    timeHeaders: [{"groupBy": "Month"}, {"groupBy": "Day", "format": "d"}],
    scale: "Day",
    days: DayPilot.Date.today().daysInMonth(),
    startDate: DayPilot.Date.today().firstDayOfMonth(),
    timeRangeSelectedHandling: "Enabled",
    onTimeRangeSelected: this.schedulerOnTimeRangeSelected,
    onEventMoved: this.schedulerOnEventMoved,
    dragOutAllowed: true,
    treeEnabled: true,
  };

  async schedulerOnTimeRangeSelected(args:DayPilot.SchedulerTimeRangeSelectedArgs): Promise<void> {
    const dp = this.scheduler.control;
    const modal = await DayPilot.Modal.prompt("Create a new event:", "Event 1");
    dp.clearSelection();
    if (modal.canceled) {
      return;
    }
    dp.events.add({
      start: args.start,
      end: args.end,
      id: DayPilot.guid(),
      resource: args.resource,
      text: modal.result
    });
  }

  schedulerOnEventMoved(args:DayPilot.SchedulerEventMovedArgs): void {
    if (args.external) {
      this.queue.control.events.remove(args.e.data.id);
    }
  }

  loadSchedulerEvents(): void {
    const events = [
      { id: 2, start: DayPilot.Date.today().addDays(2), end: DayPilot.Date.today().addDays(5), text: "Event 1", resource: "R2"}
    ];
    this.scheduler.control.update({events});
  }

  loadSchedulerResources(): void {
    const resources = [
      {name: "Resource 1", id: "R1"},
      {name: "Resource 2", id: "R2"},
      {name: "Resource 3", id: "R3"}
    ];
    this.scheduler.control.update({resources});
  }


  mounted() {
    this.loadSchedulerResources();
    this.loadSchedulerEvents();

    this.scheduler.control.message("Welcome!");
    
    // ...
  }

}
</script>

How to add a Queue of unscheduled tasks?

vue scheduler queue of unscheduled tasks

The queue is implemented using <DayPilotQueue> component. It provides a convenient way of implementing the queue:

  • The tasks data format is shared with the Scheduler.

  • The built-in CSS theme styles the events to look the same way.

  • You can reorder tasks using drag and drop.

  • The queue items are automatically activated as external items that can be moved to the Scheduler.

  • The tasks can be moved back to the queue.

Instead of using the Vue Queue component, it’s also possible to implement your own queue using DayPilot.Scheduler.makeDraggable() and DayPilot.Scheduler.registerDropTarget() methods.

How to load the queue items?

We use the direct API to load the event/task data:

loadQueueEvents(): void {
  const events = [
    {text: "Task 1", id: 1, duration: DayPilot.Duration.ofDays(3)}
  ];

  this.queue.control.update({events});
}

Instead using the direct API, you can also modify the config object. Just make sure that the change is detected by Vue:

loadQueueEvents(): void {
  const events = [
    {text: "Task 1", id: 1, duration: DayPilot.Duration.ofDays(3)}
  ];

  this.queueConfig = {
    ...this.queueConfig,
    events
  };
}

How to handle external drag and drop?

The queue component lets users drag events to a different position in the queue and it also accepts items dragged from the Vue Scheduler. In order to detect the source of the task, you need to check the args.external value in onEventMoved event handler.

  • Tasks moved from the Scheduler will have the args.external value set to true.

  • The target position is stored as a zero-based index in args.position property.

queueOnEventMoved(args: any): void {
  if (args.external) {
    this.scheduler.control.events.remove(args.e.data.id);
  }

  console.log("target position", args.position);
 
}

What is needed to activate the Queue component?

Here is the source code of the queue logic implementation:

Template:

<template>
  <DayPilotQueue id="queue" :config="queueConfig" ref="queue" />
  <!-- ... -->
</template>

TypeScript:

<script lang="ts">
import {Component, Prop, Ref, Vue} from 'vue-property-decorator';
import {DayPilot, DayPilotQueue, DayPilotScheduler} from "daypilot-pro-vue";

@Component({
  components: {
    DayPilotQueue,
    // ...
  },
})
export default class Scheduler extends Vue {

  @Ref('queue') queue!: DayPilotQueue;

  queueConfig: DayPilot.QueueConfig = {
    onEventMoved: this.queueOnEventMoved
  }

  queueOnEventMoved(args: any): void {
    if (args.external) {
      this.scheduler.control.events.remove(args.e.data.id);
    }
  }

  loadQueueEvents(): void {
    const events = [
      {text: "Task 1", id: 1, duration: DayPilot.Duration.ofDays(3)}
    ];

    this.queue.control.update({events});
  }

  mounted() {
    this.loadQueueEvents();
  }
  
  // ...

}
</script>