Dynamic Resource Availability

The options of the timeline can be dynamically changed. That applies to both the color and invalid options which control the resource track background colors and their valid state.

Based on the type of event someone wants to add or create we can highlight resources that support that type of event and invalidate resources that don't.

In the following example we have two types of tasks/events: HW for Hardware and SW for Software tasks. We also have two teams or two groups of resources: HW Team and SW Team. What we want to do is enforce event creation for teams based on the type of event: HW for the hardware team and SW for the software team.

We'll use the onEventDragStart and onEventDragEnd lifecycle events to highlight & invalidate and then set everything back to the default state. We have access to the event.category through the lifecycle event's args.

Get started with this example

Demo

Loading the live demo

Preview in full screen

Color-code resource rows and restrict drop zones by task type on a Timeline — compatible resources turn green, incompatible ones gray during drag.

Code

import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import {
  MbscCalendarColor,
  MbscCalendarEvent,
  MbscEventcalendarOptions,
  MbscModule,
  MbscResource,
  Notifications,
  setOptions ,
} from '@mobiscroll/angular';

setOptions({
  locale:  ,
  theme: ' ',
  themeVariant: ' '
});

const hwInvalids: MbscCalendarEvent[] = [
  {
    recurring: {
      repeat: 'daily',
    },
    resource: ['res4', 'res5', 'res6'],
  },
];
const swInvalids: MbscCalendarEvent[] = [
  {
    recurring: {
      repeat: 'daily',
    },
    resource: ['res1', 'res2', 'res3'],
  },
];
const hwColors: MbscCalendarColor[] = [
  {
    recurring: {
      repeat: 'daily',
    },
    resource: ['res1', 'res2', 'res3'],
    background: '#1ad4041a',
  },
];
const swColors: MbscCalendarColor[] = [
  {
    recurring: {
      repeat: 'daily',
    },
    resource: ['res4', 'res5', 'res6'],
    background: '#1ad4041a',
  },
];

@Component({
  selector: 'app-root', 
  templateUrl: './app.component.html',
  providers: [Notifications],
  standalone: true,
  imports: [CommonModule, MbscModule],
})
export class AppComponent {
  constructor(private notify: Notifications) {}

  myResources: MbscResource[] = [
    {
      id: 'hwt',
      name: 'HW Team',
      eventCreation: false,
      children: [
        {
          id: 'res1',
          name: 'Resource 1',
          color: '#0e9ea5',
        },
        {
          id: 'res2',
          name: 'Resource 2',
          color: '#0e9ea5',
        },
        {
          id: 'res3',
          name: 'Resource 3',
          color: '#0e9ea5',
        },
      ],
    },
    {
      id: 'swt',
      name: 'SW Team',
      eventCreation: false,
      children: [
        {
          id: 'res4',
          name: 'Resource 4',
          color: '#c3b726',
        },
        {
          id: 'res5',
          name: 'Resource 5',
          color: '#c3b726',
        },
        {
          id: 'res6',
          name: 'Resource 6',
          color: '#c3b726',
        },
      ],
    },
  ];

  myTasks: MbscCalendarEvent[] = [
    {
      taskId: 1,
      title: 'Task 1',
      start: '08:00',
      end: '12:00',
      category: 'hw',
      color: '#0e9ea5',
    },
    {
      taskId: 2,
      title: 'Task 2',
      start: '08:00',
      end: '12:00',
      category: 'hw',
      color: '#0e9ea5',
    },
    {
      taskId: 3,
      title: 'Task 3',
      start: '08:00',
      end: '12:00',
      category: 'hw',
      color: '#0e9ea5',
    },
    {
      taskId: 4,
      title: 'Task 4',
      start: '08:00',
      end: '12:00',
      category: 'sw',
      color: '#c3b726',
    },
    {
      taskId: 5,
      title: 'Task 5',
      start: '08:00',
      end: '12:00',
      category: 'sw',
      color: '#c3b726',
    },
    {
      taskId: 6,
      title: 'Task 6',
      start: '08:00',
      end: '12:00',
      category: 'sw',
      color: '#c3b726',
    },
  ];

  myColors: MbscCalendarColor[] = [];
  myInvalids: MbscCalendarEvent[] = [];

  calendarOptions: MbscEventcalendarOptions = {
    dragToMove: true,
    externalDrop: true,
    view: {
      timeline: { type: 'day' },
    },
    extendDefaultEvent: (event: any) => {
      const res = event.resource;

      if (res) {
        if (res === 'res1' || res === 'res2' || res === 'res3') {
          return {
            category: 'hw',
          };
        } else {
          return {
            category: 'sw',
          };
        }
      } else {
        return {};
      }
    },
    onEventDragStart: (args) => {
      const event = args.event;

      if (event) {
        if (event['category'] === 'hw') {
          this.myInvalids = hwInvalids;
          this.myColors = hwColors;
        } else {
          this.myInvalids = swInvalids;
          this.myColors = swColors;
        }
      }
    },
    onEventDragEnd: () => {
      this.myInvalids = [];
      this.myColors = [];
    },
    onEventCreated: () => {
      this.notify.toast({
        message: 'Event created',
      });
    },
    onEventUpdated: () => {
      this.notify.toast({
        message: 'Event moved',
      });
    },
    onEventCreateFailed: () => {
      this.notify.toast({
        message: "Can't create event",
      });
    },
    onEventUpdateFailed: () => {
      this.notify.toast({
        message: "Can't move event",
      });
    },
  };
}

Duplicate Session

You have signed in on a different machine. To keep everything in sync, you have been signed out of this session.

If you need to invite team members, manage seats and accounts you can do it from the licenses page.

Duplicate Session

We noticed you are logged in on a different machine and have closed your old session.

If you need to invite team members, manage seats and accounts you can do it from the licenses page.