---
title: "Vue Timeline Role-Based Access Example | Mobiscroll"
component: "Timeline"
framework: "Vue"
library_version: "6.1.5"
url: "https://demo.mobiscroll.com/vue/timeline/role-based-views-with-different-permission"
---

# Role-Based Access - Vue Timeline demo

Implement role-based access in a Vue Timeline: managers edit all tasks, employees edit their own, and clients have read-only access. For Vue and Nuxt.

- [Live demo](https://demo.mobiscroll.com/vue/timeline/role-based-views-with-different-permission)
- [View SFC JS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue/tree/main/src/demos/eventcalendar/timeline/role-based-views-with-different-permission)
- [View SFC TS code on GitHub](https://github.com/acidb/mobiscroll-demos-vue-ts/tree/main/src/demos/eventcalendar/timeline/role-based-views-with-different-permission)
- This demo in other frameworks: [JavaScript](https://demo.mobiscroll.com/javascript/timeline/role-based-views-with-different-permission.md), [jQuery](https://demo.mobiscroll.com/jquery/timeline/role-based-views-with-different-permission.md), [Angular](https://demo.mobiscroll.com/angular/timeline/role-based-views-with-different-permission.md), [React](https://demo.mobiscroll.com/react/timeline/role-based-views-with-different-permission.md)

## Description

The following example demonstrates how to implement role-based permissions in a calendar by simulating a logged in user. The selected user determines which role and permissions are applied:

- **Project manager (Full access)** - can manage all tasks
- **Employees (Limited access)** - can only edit their own tasks
- **Clients (Read-only)** - can view the schedule without making changes

The demo uses an outside control to simulate logging in as a specific user. Based on the chosen role, the calendar applies the corresponding permissions conditionally.

This approach shows how you could pass the logged in user's role from your authentication system and dynamically configure what actions are allowed in the timeline.

## What this demo shows

- A desktop weekly timeline for role-based access control, with days arranged horizontally and resources listed as rows on the left.
- **Header navigation** The month and year label opens date navigation, while the previous and next arrows move between weeks and the Today button returns to the current date.
- **Week view** The strip below the header shows the selected week from Sunday to Saturday, with the current date highlighted.
- **Role selection** The demo simulates different logged-in users to show how permissions change by role.
- **Full access role** The Project manager can create, edit, drag, resize, and delete tasks across all resources.
- **Limited access role** Employees can view the full schedule but can only modify tasks assigned to themselves.
- **Employee preview** Selecting different employees shows the editing permissions for each employee.
- **Read-only role** Clients can browse the full schedule but cannot create, edit, move, resize, or delete tasks.
- **Permission handling** Editing capabilities are enabled or disabled automatically according to the active user role.
- **Shared timeline data** The same timeline data is shown with different interaction levels without changing the underlying schedule.
- **Time grid** The timeline displays hourly columns from 8 AM to 8 PM.
- **Resources** Multiple resources are shown as separate timeline rows.
- **Current time** A vertical blue line with a time label marks the current time.
- **Hover behavior** Hovering over the time grid shows a time indicator that follows the cursor in 15-minute increments.
- **Event cards** Events are shown as colored cards with a left color stripe, a bold title, a description, and a bold time range.
- **Date positioning** Events are positioned by their assigned resource and exact date and time range.
- **Event interaction** Editable events highlight on hover and show drag and resize handles for repositioning or changing duration.
- **Event selection** Clicking an event selects and highlights it.
- **Event creation** New events can be created by double-clicking the timeline or by clicking and dragging across a time range when the active role allows it.
- **Scrolling** The timeline supports horizontal and vertical scrolling for navigating through time and resources.

## Best for

- **Frontend permission handling** Demonstrating how to apply role-based editing rules while keeping a shared timeline interface visible to every user.
- **Project management tools** Showing different task management permissions for managers, team members, and external clients.
- **Workforce scheduling** Letting employees view the full team timeline while limiting edits to their own assigned work.
- **Team collaboration apps** Supporting shared planning views where each role has a different level of control over the same timeline.
- **Client-facing timeline** Providing read-only access to project timelines without exposing editing actions.
- **Permission testing** Previewing how the same timeline behaves for full access, limited access, and read-only users.
- **Resource-based timelines** Managing tasks across multiple people or resources in a weekly business-hours timeline.

## Tutorial

### Simulate logged in user

- ( ) Full access - Project manager
- (x) Limited access `Willis Cane`- Employee
- ( ) Read-only access - Client

```vue
<script setup>
const user = {
  id: 2,
  name: 'Willis Cane',
  role: 'limited'
}

const editEvents = ref(false)
const myDefaultEvent = ref(null)
const isToastOpen = ref(false)
const toastMessage = ref('')

const myView = {
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
}

const myEvents = ref([{
  start: '2026-10-23T11:00',
  end: '2026-10-23T15:00',
  title: 'Task 1',
  resource: 1
}, {
  start: '2026-10-23T14:00',
  end: '2026-10-23T17:00',
  title: 'Task 2',
  resource: 3
}, {
  start: '2026-10-23T12:00',
  end: '2026-10-23T14:00',
  title: 'Task 3',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T15:00',
  title: 'Task 4',
  resource: 1
}, {
  start: '2026-10-24T11:00',
  end: '2026-10-24T13:00',
  title: 'Task 5',
  resource: 2
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T17:00',
  title: 'Task 6',
  resource: 2
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T15:00',
  title: 'Task 7',
  resource: 3
}, {
  start: '2026-10-24T17:00',
  end: '2026-10-24T20:00',
  title: 'Task 8',
  resource: 3
}, {
  start: '2026-10-24T08:00',
  end: '2026-10-24T11:30',
  title: 'Task 9',
  resource: 4
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T14:00',
  title: 'Task 10',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T13:00',
  title: 'Task 11',
  resource: 5
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T16:00',
  title: 'Task 12',
  resource: 5
}, {      
  start: '2026-10-24T16:30',
  end: '2026-10-24T19:00',
  title: 'Task 13',
  resource: 5
}, {
  start: '2026-10-25T11:00',
  end: '2026-10-25T14:00',
  title: 'Task 14',
  resource: 2
}, {
  start: '2026-10-25T16:00',
  end: '2026-10-25T20:00',
  title: 'Task 15',
  resource: 5
}])

const myResources = ref([{
  id: 1,
  name: 'Jude Chester',
  color: '#af2ec3'
}, {
  id: 2,
  name: 'Willis Cane',
  color: '#cccc39'
}, {
  id: 3,
  name: 'Derek Austyn',
  color: '#56ca2c'
}, {
  id: 4,
  name: 'Merv Kenny',
  color: '#af2424'
}, {
  id: 5,
  name: 'Fred Waldez',
  color: '#256ebc'
}])

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]
  let defaultColor = ''

  if (user.role === 'readonly') {
    for (const task of newTasks) {
      // Disable editing for all events
      task.editable = false
      // Make event colors uniform
      task.color = '#af2ec3'
    }
  } else if (user.role === 'limited') {
    defaultColor = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        // Disable editing events of other users
        task.editable = false
        // Set disabled event colors to gray
        task.color = '#6a6a6a'
      } else {
        // Make event colors uniform
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {      
        // Disable event creation for other users
        res.eventCreation = false
      }
    }
  }

  // Update events, resources and d&d options
  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  myDefaultEvent.value = function () {
    return {
      color: defaultColor
    }
  }
}

login()
</script>

<template>
  <MbscEventcalendar 
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent" />
</template>
```

With "Full access - Project manager":

```vue
<script setup>
const user = {
  id: 'client'
  name: 'Project manager',
  role: 'full'
}

const editEvents = ref(false)
const myDefaultEvent = ref(null)
const isToastOpen = ref(false)
const toastMessage = ref('')

const myView = {
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
}

const myEvents = ref([{
  start: '2026-10-23T11:00',
  end: '2026-10-23T15:00',
  title: 'Task 1',
  resource: 1
}, {
  start: '2026-10-23T14:00',
  end: '2026-10-23T17:00',
  title: 'Task 2',
  resource: 3
}, {
  start: '2026-10-23T12:00',
  end: '2026-10-23T14:00',
  title: 'Task 3',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T15:00',
  title: 'Task 4',
  resource: 1
}, {
  start: '2026-10-24T11:00',
  end: '2026-10-24T13:00',
  title: 'Task 5',
  resource: 2
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T17:00',
  title: 'Task 6',
  resource: 2
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T15:00',
  title: 'Task 7',
  resource: 3
}, {
  start: '2026-10-24T17:00',
  end: '2026-10-24T20:00',
  title: 'Task 8',
  resource: 3
}, {
  start: '2026-10-24T08:00',
  end: '2026-10-24T11:30',
  title: 'Task 9',
  resource: 4
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T14:00',
  title: 'Task 10',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T13:00',
  title: 'Task 11',
  resource: 5
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T16:00',
  title: 'Task 12',
  resource: 5
}, {      
  start: '2026-10-24T16:30',
  end: '2026-10-24T19:00',
  title: 'Task 13',
  resource: 5
}, {
  start: '2026-10-25T11:00',
  end: '2026-10-25T14:00',
  title: 'Task 14',
  resource: 2
}, {
  start: '2026-10-25T16:00',
  end: '2026-10-25T20:00',
  title: 'Task 15',
  resource: 5
}])

const myResources = ref([{
  id: 1,
  name: 'Jude Chester',
  color: '#af2ec3'
}, {
  id: 2,
  name: 'Willis Cane',
  color: '#cccc39'
}, {
  id: 3,
  name: 'Derek Austyn',
  color: '#56ca2c'
}, {
  id: 4,
  name: 'Merv Kenny',
  color: '#af2424'
}, {
  id: 5,
  name: 'Fred Waldez',
  color: '#256ebc'
}])

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]
  let defaultColor = ''

  if (user.role === 'readonly') {
    for (const task of newTasks) {
      // Disable editing for all events
      task.editable = false
      // Make event colors uniform
      task.color = '#af2ec3'
    }
  } else if (user.role === 'limited') {
    defaultColor = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        // Disable editing events of other users
        task.editable = false
        // Set disabled event colors to gray
        task.color = '#6a6a6a'
      } else {
        // Make event colors uniform
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {      
        // Disable event creation for other users
        res.eventCreation = false
      }
    }
  }

  // Update events, resources and d&d options
  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  myDefaultEvent.value = function () {
    return {
      color: defaultColor
    }
  }
}

login()
</script>

<template>
  <MbscEventcalendar 
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent" />
</template>
```

With "Read-only access - Client":

```vue
<script setup>
const user = {
  id: 'client'
  name: 'Client',
  role: 'readonly'
}

const editEvents = ref(false)
const myDefaultEvent = ref(null)
const isToastOpen = ref(false)
const toastMessage = ref('')

const myView = {
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
}

const myEvents = ref([{
  start: '2026-10-23T11:00',
  end: '2026-10-23T15:00',
  title: 'Task 1',
  resource: 1
}, {
  start: '2026-10-23T14:00',
  end: '2026-10-23T17:00',
  title: 'Task 2',
  resource: 3
}, {
  start: '2026-10-23T12:00',
  end: '2026-10-23T14:00',
  title: 'Task 3',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T15:00',
  title: 'Task 4',
  resource: 1
}, {
  start: '2026-10-24T11:00',
  end: '2026-10-24T13:00',
  title: 'Task 5',
  resource: 2
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T17:00',
  title: 'Task 6',
  resource: 2
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T15:00',
  title: 'Task 7',
  resource: 3
}, {
  start: '2026-10-24T17:00',
  end: '2026-10-24T20:00',
  title: 'Task 8',
  resource: 3
}, {
  start: '2026-10-24T08:00',
  end: '2026-10-24T11:30',
  title: 'Task 9',
  resource: 4
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T14:00',
  title: 'Task 10',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T13:00',
  title: 'Task 11',
  resource: 5
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T16:00',
  title: 'Task 12',
  resource: 5
}, {      
  start: '2026-10-24T16:30',
  end: '2026-10-24T19:00',
  title: 'Task 13',
  resource: 5
}, {
  start: '2026-10-25T11:00',
  end: '2026-10-25T14:00',
  title: 'Task 14',
  resource: 2
}, {
  start: '2026-10-25T16:00',
  end: '2026-10-25T20:00',
  title: 'Task 15',
  resource: 5
}])

const myResources = ref([{
  id: 1,
  name: 'Jude Chester',
  color: '#af2ec3'
}, {
  id: 2,
  name: 'Willis Cane',
  color: '#cccc39'
}, {
  id: 3,
  name: 'Derek Austyn',
  color: '#56ca2c'
}, {
  id: 4,
  name: 'Merv Kenny',
  color: '#af2424'
}, {
  id: 5,
  name: 'Fred Waldez',
  color: '#256ebc'
}])

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]
  let defaultColor = ''

  if (user.role === 'readonly') {
    for (const task of newTasks) {
      // Disable editing for all events
      task.editable = false
      // Make event colors uniform
      task.color = '#af2ec3'
    }
  } else if (user.role === 'limited') {
    defaultColor = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        // Disable editing events of other users
        task.editable = false
        // Set disabled event colors to gray
        task.color = '#6a6a6a'
      } else {
        // Make event colors uniform
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {      
        // Disable event creation for other users
        res.eventCreation = false
      }
    }
  }

  // Update events, resources and d&d options
  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  myDefaultEvent.value = function () {
    return {
      color: defaultColor
    }
  }
}

login()
</script>

<template>
  <MbscEventcalendar 
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent" />
</template>
```

With "Jude Chester":

```vue
<script setup>
const user = {
  id: 1,
  name: 'Jude Chester',
  role: 'limited'
}

const editEvents = ref(false)
const myDefaultEvent = ref(null)
const isToastOpen = ref(false)
const toastMessage = ref('')

const myView = {
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
}

const myEvents = ref([{
  start: '2026-10-23T11:00',
  end: '2026-10-23T15:00',
  title: 'Task 1',
  resource: 1
}, {
  start: '2026-10-23T14:00',
  end: '2026-10-23T17:00',
  title: 'Task 2',
  resource: 3
}, {
  start: '2026-10-23T12:00',
  end: '2026-10-23T14:00',
  title: 'Task 3',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T15:00',
  title: 'Task 4',
  resource: 1
}, {
  start: '2026-10-24T11:00',
  end: '2026-10-24T13:00',
  title: 'Task 5',
  resource: 2
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T17:00',
  title: 'Task 6',
  resource: 2
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T15:00',
  title: 'Task 7',
  resource: 3
}, {
  start: '2026-10-24T17:00',
  end: '2026-10-24T20:00',
  title: 'Task 8',
  resource: 3
}, {
  start: '2026-10-24T08:00',
  end: '2026-10-24T11:30',
  title: 'Task 9',
  resource: 4
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T14:00',
  title: 'Task 10',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T13:00',
  title: 'Task 11',
  resource: 5
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T16:00',
  title: 'Task 12',
  resource: 5
}, {      
  start: '2026-10-24T16:30',
  end: '2026-10-24T19:00',
  title: 'Task 13',
  resource: 5
}, {
  start: '2026-10-25T11:00',
  end: '2026-10-25T14:00',
  title: 'Task 14',
  resource: 2
}, {
  start: '2026-10-25T16:00',
  end: '2026-10-25T20:00',
  title: 'Task 15',
  resource: 5
}])

const myResources = ref([{
  id: 1,
  name: 'Jude Chester',
  color: '#af2ec3'
}, {
  id: 2,
  name: 'Willis Cane',
  color: '#cccc39'
}, {
  id: 3,
  name: 'Derek Austyn',
  color: '#56ca2c'
}, {
  id: 4,
  name: 'Merv Kenny',
  color: '#af2424'
}, {
  id: 5,
  name: 'Fred Waldez',
  color: '#256ebc'
}])

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]
  let defaultColor = ''

  if (user.role === 'readonly') {
    for (const task of newTasks) {
      // Disable editing for all events
      task.editable = false
      // Make event colors uniform
      task.color = '#af2ec3'
    }
  } else if (user.role === 'limited') {
    defaultColor = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        // Disable editing events of other users
        task.editable = false
        // Set disabled event colors to gray
        task.color = '#6a6a6a'
      } else {
        // Make event colors uniform
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {      
        // Disable event creation for other users
        res.eventCreation = false
      }
    }
  }

  // Update events, resources and d&d options
  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  myDefaultEvent.value = function () {
    return {
      color: defaultColor
    }
  }
}

login()
</script>

<template>
  <MbscEventcalendar 
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent" />
</template>
```

With "Derek Austyn":

```vue
<script setup>
const user = {
  id: 3,
  name: 'Derek Austyn',
  role: 'limited'
}

const editEvents = ref(false)
const myDefaultEvent = ref(null)
const isToastOpen = ref(false)
const toastMessage = ref('')

const myView = {
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
}

const myEvents = ref([{
  start: '2026-10-23T11:00',
  end: '2026-10-23T15:00',
  title: 'Task 1',
  resource: 1
}, {
  start: '2026-10-23T14:00',
  end: '2026-10-23T17:00',
  title: 'Task 2',
  resource: 3
}, {
  start: '2026-10-23T12:00',
  end: '2026-10-23T14:00',
  title: 'Task 3',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T15:00',
  title: 'Task 4',
  resource: 1
}, {
  start: '2026-10-24T11:00',
  end: '2026-10-24T13:00',
  title: 'Task 5',
  resource: 2
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T17:00',
  title: 'Task 6',
  resource: 2
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T15:00',
  title: 'Task 7',
  resource: 3
}, {
  start: '2026-10-24T17:00',
  end: '2026-10-24T20:00',
  title: 'Task 8',
  resource: 3
}, {
  start: '2026-10-24T08:00',
  end: '2026-10-24T11:30',
  title: 'Task 9',
  resource: 4
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T14:00',
  title: 'Task 10',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T13:00',
  title: 'Task 11',
  resource: 5
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T16:00',
  title: 'Task 12',
  resource: 5
}, {      
  start: '2026-10-24T16:30',
  end: '2026-10-24T19:00',
  title: 'Task 13',
  resource: 5
}, {
  start: '2026-10-25T11:00',
  end: '2026-10-25T14:00',
  title: 'Task 14',
  resource: 2
}, {
  start: '2026-10-25T16:00',
  end: '2026-10-25T20:00',
  title: 'Task 15',
  resource: 5
}])

const myResources = ref([{
  id: 1,
  name: 'Jude Chester',
  color: '#af2ec3'
}, {
  id: 2,
  name: 'Willis Cane',
  color: '#cccc39'
}, {
  id: 3,
  name: 'Derek Austyn',
  color: '#56ca2c'
}, {
  id: 4,
  name: 'Merv Kenny',
  color: '#af2424'
}, {
  id: 5,
  name: 'Fred Waldez',
  color: '#256ebc'
}])

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]
  let defaultColor = ''

  if (user.role === 'readonly') {
    for (const task of newTasks) {
      // Disable editing for all events
      task.editable = false
      // Make event colors uniform
      task.color = '#af2ec3'
    }
  } else if (user.role === 'limited') {
    defaultColor = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        // Disable editing events of other users
        task.editable = false
        // Set disabled event colors to gray
        task.color = '#6a6a6a'
      } else {
        // Make event colors uniform
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {      
        // Disable event creation for other users
        res.eventCreation = false
      }
    }
  }

  // Update events, resources and d&d options
  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  myDefaultEvent.value = function () {
    return {
      color: defaultColor
    }
  }
}

login()
</script>

<template>
  <MbscEventcalendar 
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent" />
</template>
```

With "Merv Kenny":

```vue
<script setup>
const user = {
  id: 4,
  name: 'Merv Kenny',
  role: 'limited'
}

const editEvents = ref(false)
const myDefaultEvent = ref(null)
const isToastOpen = ref(false)
const toastMessage = ref('')

const myView = {
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
}

const myEvents = ref([{
  start: '2026-10-23T11:00',
  end: '2026-10-23T15:00',
  title: 'Task 1',
  resource: 1
}, {
  start: '2026-10-23T14:00',
  end: '2026-10-23T17:00',
  title: 'Task 2',
  resource: 3
}, {
  start: '2026-10-23T12:00',
  end: '2026-10-23T14:00',
  title: 'Task 3',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T15:00',
  title: 'Task 4',
  resource: 1
}, {
  start: '2026-10-24T11:00',
  end: '2026-10-24T13:00',
  title: 'Task 5',
  resource: 2
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T17:00',
  title: 'Task 6',
  resource: 2
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T15:00',
  title: 'Task 7',
  resource: 3
}, {
  start: '2026-10-24T17:00',
  end: '2026-10-24T20:00',
  title: 'Task 8',
  resource: 3
}, {
  start: '2026-10-24T08:00',
  end: '2026-10-24T11:30',
  title: 'Task 9',
  resource: 4
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T14:00',
  title: 'Task 10',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T13:00',
  title: 'Task 11',
  resource: 5
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T16:00',
  title: 'Task 12',
  resource: 5
}, {      
  start: '2026-10-24T16:30',
  end: '2026-10-24T19:00',
  title: 'Task 13',
  resource: 5
}, {
  start: '2026-10-25T11:00',
  end: '2026-10-25T14:00',
  title: 'Task 14',
  resource: 2
}, {
  start: '2026-10-25T16:00',
  end: '2026-10-25T20:00',
  title: 'Task 15',
  resource: 5
}])

const myResources = ref([{
  id: 1,
  name: 'Jude Chester',
  color: '#af2ec3'
}, {
  id: 2,
  name: 'Willis Cane',
  color: '#cccc39'
}, {
  id: 3,
  name: 'Derek Austyn',
  color: '#56ca2c'
}, {
  id: 4,
  name: 'Merv Kenny',
  color: '#af2424'
}, {
  id: 5,
  name: 'Fred Waldez',
  color: '#256ebc'
}])

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]
  let defaultColor = ''

  if (user.role === 'readonly') {
    for (const task of newTasks) {
      // Disable editing for all events
      task.editable = false
      // Make event colors uniform
      task.color = '#af2ec3'
    }
  } else if (user.role === 'limited') {
    defaultColor = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        // Disable editing events of other users
        task.editable = false
        // Set disabled event colors to gray
        task.color = '#6a6a6a'
      } else {
        // Make event colors uniform
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {      
        // Disable event creation for other users
        res.eventCreation = false
      }
    }
  }

  // Update events, resources and d&d options
  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  myDefaultEvent.value = function () {
    return {
      color: defaultColor
    }
  }
}

login()
</script>

<template>
  <MbscEventcalendar 
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent" />
</template>
```

With "Fred Waldez":

```vue
<script setup>
const user = {
  id: 5,
  name: 'Fred Waldez',
  role: 'limited'
}

const editEvents = ref(false)
const myDefaultEvent = ref(null)
const isToastOpen = ref(false)
const toastMessage = ref('')

const myView = {
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
}

const myEvents = ref([{
  start: '2026-10-23T11:00',
  end: '2026-10-23T15:00',
  title: 'Task 1',
  resource: 1
}, {
  start: '2026-10-23T14:00',
  end: '2026-10-23T17:00',
  title: 'Task 2',
  resource: 3
}, {
  start: '2026-10-23T12:00',
  end: '2026-10-23T14:00',
  title: 'Task 3',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T15:00',
  title: 'Task 4',
  resource: 1
}, {
  start: '2026-10-24T11:00',
  end: '2026-10-24T13:00',
  title: 'Task 5',
  resource: 2
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T17:00',
  title: 'Task 6',
  resource: 2
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T15:00',
  title: 'Task 7',
  resource: 3
}, {
  start: '2026-10-24T17:00',
  end: '2026-10-24T20:00',
  title: 'Task 8',
  resource: 3
}, {
  start: '2026-10-24T08:00',
  end: '2026-10-24T11:30',
  title: 'Task 9',
  resource: 4
}, {
  start: '2026-10-24T12:00',
  end: '2026-10-24T14:00',
  title: 'Task 10',
  resource: 4
}, {
  start: '2026-10-24T10:00',
  end: '2026-10-24T13:00',
  title: 'Task 11',
  resource: 5
}, {
  start: '2026-10-24T14:00',
  end: '2026-10-24T16:00',
  title: 'Task 12',
  resource: 5
}, {      
  start: '2026-10-24T16:30',
  end: '2026-10-24T19:00',
  title: 'Task 13',
  resource: 5
}, {
  start: '2026-10-25T11:00',
  end: '2026-10-25T14:00',
  title: 'Task 14',
  resource: 2
}, {
  start: '2026-10-25T16:00',
  end: '2026-10-25T20:00',
  title: 'Task 15',
  resource: 5
}])

const myResources = ref([{
  id: 1,
  name: 'Jude Chester',
  color: '#af2ec3'
}, {
  id: 2,
  name: 'Willis Cane',
  color: '#cccc39'
}, {
  id: 3,
  name: 'Derek Austyn',
  color: '#56ca2c'
}, {
  id: 4,
  name: 'Merv Kenny',
  color: '#af2424'
}, {
  id: 5,
  name: 'Fred Waldez',
  color: '#256ebc'
}])

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]
  let defaultColor = ''

  if (user.role === 'readonly') {
    for (const task of newTasks) {
      // Disable editing for all events
      task.editable = false
      // Make event colors uniform
      task.color = '#af2ec3'
    }
  } else if (user.role === 'limited') {
    defaultColor = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        // Disable editing events of other users
        task.editable = false
        // Set disabled event colors to gray
        task.color = '#6a6a6a'
      } else {
        // Make event colors uniform
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {      
        // Disable event creation for other users
        res.eventCreation = false
      }
    }
  }

  // Update events, resources and d&d options
  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  myDefaultEvent.value = function () {
    return {
      color: defaultColor
    }
  }
}

login()
</script>

<template>
  <MbscEventcalendar 
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent" />
</template>
```

## API used in this demo

- [`theme`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-theme) - option
- [`themeVariant`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-themeVariant) - option
- [`cssClass`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-cssClass) - option
- [`view`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-view) - option
- [`data`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-data) - option
- [`resources`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-resources) - option
- [`clickToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-clickToCreate) - option
- [`dragToCreate`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToCreate) - option
- [`dragToMove`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToMove) - option
- [`dragToResize`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-dragToResize) - option
- [`eventDelete`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-eventDelete) - option
- [`extendDefaultEvent`](https://mobiscroll.com/docs/vue/eventcalendar/api#opt-extendDefaultEvent) - option
- [`close`](https://mobiscroll.com/docs/vue/notifications/toast#event-onClose) - event

## Code

### SFC JS

```vue
<script setup>
import { MbscEventcalendar, MbscToast, setOptions } from '@mobiscroll/vue'
import { ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const user = { id: 2, name: 'Willis Cane', role: 'limited' }

/* Other user examples
const user = { name: 'Client',  role: 'readonly' }
const user = { name: 'Project Manager', role: 'full' } */

const editEvents = ref(false)
const isToastOpen = ref(false)
const toastMessage = ref('')
const defaultColor = ref('')

const myView = {
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
}

const myEvents = ref([
  {
    start: '2026-10-23T11:00',
    end: '2026-10-23T15:00',
    title: 'Task 1',
    resource: 1
  },
  {
    start: '2026-10-23T14:00',
    end: '2026-10-23T17:00',
    title: 'Task 2',
    resource: 3
  },
  {
    start: '2026-10-23T12:00',
    end: '2026-10-23T14:00',
    title: 'Task 3',
    resource: 4
  },
  {
    start: '2026-10-24T10:00',
    end: '2026-10-24T15:00',
    title: 'Task 4',
    resource: 1
  },
  {
    start: '2026-10-24T11:00',
    end: '2026-10-24T13:00',
    title: 'Task 5',
    resource: 2
  },
  {
    start: '2026-10-24T14:00',
    end: '2026-10-24T17:00',
    title: 'Task 6',
    resource: 2
  },
  {
    start: '2026-10-24T12:00',
    end: '2026-10-24T15:00',
    title: 'Task 7',
    resource: 3
  },
  {
    start: '2026-10-24T17:00',
    end: '2026-10-24T20:00',
    title: 'Task 8',
    resource: 3
  },
  {
    start: '2026-10-24T08:00',
    end: '2026-10-24T11:30',
    title: 'Task 9',
    resource: 4
  },
  {
    start: '2026-10-24T12:00',
    end: '2026-10-24T14:00',
    title: 'Task 10',
    resource: 4
  },
  {
    start: '2026-10-24T10:00',
    end: '2026-10-24T13:00',
    title: 'Task 11',
    resource: 5
  },
  {
    start: '2026-10-24T14:00',
    end: '2026-10-24T16:00',
    title: 'Task 12',
    resource: 5
  },
  {
    start: '2026-10-24T16:30',
    end: '2026-10-24T19:00',
    title: 'Task 13',
    resource: 5
  },
  {
    start: '2026-10-25T11:00',
    end: '2026-10-25T14:00',
    title: 'Task 14',
    resource: 2
  },
  {
    start: '2026-10-25T16:00',
    end: '2026-10-25T20:00',
    title: 'Task 15',
    resource: 5
  }
])

const myResources = ref([
  { id: 1, name: 'Jude Chester', color: '#af2ec3' },
  { id: 2, name: 'Willis Cane', color: '#cccc39' },
  { id: 3, name: 'Derek Austyn', color: '#56ca2c' },
  { id: 4, name: 'Merv Kenny', color: '#af2424' },
  { id: 5, name: 'Fred Waldez', color: '#256ebc' }
])

function myDefaultEvent() {
  return {
    color: defaultColor.value
  }
}

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]

  if (user.role === 'readonly') {
    defaultColor.value = ''
    for (const task of newTasks) {
      task.editable = false
      task.color = '#af2ec3'
    }

    toastMessage.value = 'Client with read-only access logged in'
  } else if (user.role === 'limited') {
    defaultColor.value = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        task.editable = false
        task.color = '#6a6a6a'
      } else {
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {
        res.eventCreation = false
      }
    }
    toastMessage.value = 'User ' + user.name + ' with limited access logged in'
  } else {
    defaultColor.value = ''
    toastMessage.value = 'User with full access logged in'
  }

  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  isToastOpen.value = true
}

login()
</script>

<template>
  <MbscEventcalendar
    cssClass="mds-role-based-timeline"
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent"
  />
  <MbscToast :message="toastMessage" :isOpen="isToastOpen" @close="isToastOpen = false" />
</template>

<style>
.mds-role-based-timeline
  .mbsc-schedule-event:not(.mbsc-readonly-event)
  .mbsc-schedule-event-background {
  border: 2px solid currentColor;
}

.mds-role-based-timeline .mbsc-schedule-event .mbsc-schedule-event-background::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.6);
}
</style>
```

### SFC TS

```vue
<script setup lang="ts">
import { MbscEventcalendar, MbscToast, setOptions } from '@mobiscroll/vue'
import type { MbscCalendarEvent, MbscEventcalendarView, MbscResource } from '@mobiscroll/vue'
import { ref } from 'vue'

setOptions({
  theme: 'ios',
  themeVariant: 'light'
})

const user = { id: 2, name: 'Willis Cane', role: 'limited' }

/* Other user examples
const user = { name: 'Client',  role: 'readonly' }
const user = { name: 'Project Manager', role: 'full' } */

const editEvents = ref<boolean>(false)
const isToastOpen = ref<boolean>(false)
const toastMessage = ref<string>('')
const defaultColor = ref<string>('')

const myView = ref<MbscEventcalendarView>({
  timeline: {
    type: 'week',
    startTime: '08:00',
    endTime: '20:00'
  }
})

const myEvents = ref<MbscCalendarEvent[]>([
  {
    start: '2026-10-23T11:00',
    end: '2026-10-23T15:00',
    title: 'Task 1',
    resource: 1
  },
  {
    start: '2026-10-23T14:00',
    end: '2026-10-23T17:00',
    title: 'Task 2',
    resource: 3
  },
  {
    start: '2026-10-23T12:00',
    end: '2026-10-23T14:00',
    title: 'Task 3',
    resource: 4
  },
  {
    start: '2026-10-24T10:00',
    end: '2026-10-24T15:00',
    title: 'Task 4',
    resource: 1
  },
  {
    start: '2026-10-24T11:00',
    end: '2026-10-24T13:00',
    title: 'Task 5',
    resource: 2
  },
  {
    start: '2026-10-24T14:00',
    end: '2026-10-24T17:00',
    title: 'Task 6',
    resource: 2
  },
  {
    start: '2026-10-24T12:00',
    end: '2026-10-24T15:00',
    title: 'Task 7',
    resource: 3
  },
  {
    start: '2026-10-24T17:00',
    end: '2026-10-24T20:00',
    title: 'Task 8',
    resource: 3
  },
  {
    start: '2026-10-24T08:00',
    end: '2026-10-24T11:30',
    title: 'Task 9',
    resource: 4
  },
  {
    start: '2026-10-24T12:00',
    end: '2026-10-24T14:00',
    title: 'Task 10',
    resource: 4
  },
  {
    start: '2026-10-24T10:00',
    end: '2026-10-24T13:00',
    title: 'Task 11',
    resource: 5
  },
  {
    start: '2026-10-24T14:00',
    end: '2026-10-24T16:00',
    title: 'Task 12',
    resource: 5
  },
  {
    start: '2026-10-24T16:30',
    end: '2026-10-24T19:00',
    title: 'Task 13',
    resource: 5
  },
  {
    start: '2026-10-25T11:00',
    end: '2026-10-25T14:00',
    title: 'Task 14',
    resource: 2
  },
  {
    start: '2026-10-25T16:00',
    end: '2026-10-25T20:00',
    title: 'Task 15',
    resource: 5
  }
])

const myResources = ref<MbscResource[]>([
  { id: 1, name: 'Jude Chester', color: '#af2ec3' },
  { id: 2, name: 'Willis Cane', color: '#cccc39' },
  { id: 3, name: 'Derek Austyn', color: '#56ca2c' },
  { id: 4, name: 'Merv Kenny', color: '#af2424' },
  { id: 5, name: 'Fred Waldez', color: '#256ebc' }
])

function myDefaultEvent() {
  return {
    color: defaultColor.value
  }
}

// Simulate login
function login() {
  const newTasks = [...myEvents.value]
  const newResources = [...myResources.value]

  if (user.role === 'readonly') {
    defaultColor.value = ''
    for (const task of newTasks) {
      task.editable = false
      task.color = '#af2ec3'
    }

    toastMessage.value = 'Client with read-only access logged in'
  } else if (user.role === 'limited') {
    defaultColor.value = '#af2424'
    for (const task of newTasks) {
      if (task.resource !== user.id) {
        task.editable = false
        task.color = '#6a6a6a'
      } else {
        task.color = '#af2424'
      }
    }

    for (const res of newResources) {
      if (res.id !== user.id) {
        res.eventCreation = false
      }
    }
    toastMessage.value = 'User ' + user.name + ' with limited access logged in'
  } else {
    defaultColor.value = ''
    toastMessage.value = 'User with full access logged in'
  }

  myEvents.value = newTasks
  myResources.value = newResources
  editEvents.value = user.role != 'readonly'
  isToastOpen.value = true
}

login()
</script>

<template>
  <MbscEventcalendar
    cssClass="mds-role-based-timeline"
    :view="myView"
    :data="myEvents"
    :resources="myResources"
    :clickToCreate="editEvents"
    :dragToCreate="editEvents"
    :dragToMove="editEvents"
    :dragToResize="editEvents"
    :eventDelete="editEvents"
    :extendDefaultEvent="myDefaultEvent"
  />
  <MbscToast :message="toastMessage" :isOpen="isToastOpen" @close="isToastOpen = false" />
</template>

<style>
.mds-role-based-timeline
  .mbsc-schedule-event:not(.mbsc-readonly-event)
  .mbsc-schedule-event-background {
  border: 2px solid currentColor;
}

.mds-role-based-timeline .mbsc-schedule-event .mbsc-schedule-event-background::after {
  content: '';
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.6);
}
</style>
```

## Implementation notes

- Use `timeline: { type: 'week', startTime: '08:00', endTime: '20:00' }` to show a week view restricted to business hours.
- Define 5 named employee resources (Jude Chester, Willis Cane, Derek Austyn, Merv Kenny, Fred Waldez), each with a distinct `color`.
- Prepare 15 tasks using `dyndatetime` offsets spread across today-1, today, and today+1. Each task has a single `resource` ID. Store them as the initial (unmodified) event array.
- Represent the current user as an object with `id`, `name`, and `role` (`'full'` / `'limited'` / `'readonly'`). The demo hard-codes Willis Cane with `role: 'limited'` as the default logged-in user.
- **Run the login simulation on mount.** It works on shallow copies of the event and resource arrays to avoid mutating the originals, then applies role logic:
  - **`'readonly'`**: Set `editable: false` and `color: '#af2ec3'` on every event.
  - **`'limited'`**: For each event, if `task.resource !== user.id` set `editable: false` and `color: '#6a6a6a'`; otherwise set `color: '#af2424'` (the user's own color). For each resource other than the user's own, set `eventCreation: false` to block creating events on foreign rows.
  - **`'full'`**: Leave all events and resources unmodified.
- Derive an `editEvents` boolean: `true` for `'full'` and `'limited'`, `false` for `'readonly'`. Pass this single value to `clickToCreate`, `dragToCreate`, `dragToMove`, `dragToResize`, and `eventDelete` simultaneously.
- Pass `extendDefaultEvent` returning `{ color: defaultColor }` where `defaultColor` is `'#af2424'` for `'limited'` and `''` for the other roles. This ensures newly drag-created events inherit the user's own color in limited mode.

## Run it in your project

1. If not signed up yet, or don't own a license, you can [start a free trial](https://mobiscroll.com/starttrial).

2. Clone the repository:

   ```
   git clone https://github.com/acidb/mobiscroll-demos-vue.git
   ```

3. If not installed yet, install the Mobiscroll CLI from NPM:

   ```
   npm install -g @mobiscroll/cli
   ```

4. Config Mobiscroll - open a terminal window in the root directory and run:

   ```
   mobiscroll config vue
   ```

5. Install dependencies - open a terminal window in the root directory and run:

   ```
   npm install
   ```

6. Run the project:

   ```
   npm run dev
   ```

On a trial, add `--trial` to the config command: `mobiscroll config vue --trial`.

Running a demo locally requires a Mobiscroll trial or a license; setup is per framework at https://mobiscroll.com/docs/vue/getting-started/installation

## Related demos

- Previous: [External Date Navigation](https://demo.mobiscroll.com/vue/timeline/navigate-view-from-external-calendar.md) - Use a two-panel Vue Timeline navigated by an external date picker — selecting a date syncs the timeline and the picker instantly.
