Outlook Calendar Sync

The event calendar comes with third party calendar integration support through the integration plugin. This needs to be added to the download package or installed separately from a dedicated NPM package.

It includes everything you need to authenticate your users, get their Outlook calendars and provides functions for CRUD operations. It takes care of loading the events and converts them to the required format so that they can be displayed on the Mobiscroll calendar separately or mixed with other calendars and events.

Customizing the interaction, event workflows, whether the events are read-only is up to you. In this live demo, newly created events will land in the primary calendar of the authenticated user.

This example uses the integration plugin to connect to and load events from Outlook Calendars and it is not available in the trial. Give the live demo a try and see how it can be configured.
Get started with the agenda

Demo

Loading the live demo

Preview in full screen

Use the event calendar integration plugin to authenticate users, load their Outlook calendars, and display events in an agenda view.

Code

<script setup>
import { outlookCalendarSync } from '@mobiscroll/calendar-integration'
import {
  MbscButton,
  MbscCalendarNav,
  MbscCalendarNext,
  MbscCalendarPrev,
  MbscEventcalendar,
  MbscPopup,
  MbscSwitch,
  MbscToast,
  setOptions 
} from '@mobiscroll/vue'
import { onMounted, ref } from 'vue'

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

const calendarData = ref({})
const calendarIds = ref([])
const isLoggedIn = ref(false)
const isLoading = ref(false)
const isPopupOpen = ref(false)
const isToastOpen = ref(false)
const myAnchor = ref()
const myCalendars = ref([])
const myEvents = ref([])
const mySelectedDate = ref(new Date())
const myView = { agenda: { type: 'month' } }
const toastMessage = ref('')

const buttonRef = ref()
const startDate = ref()
const endDate = ref()
const timer = ref()

function handleError(resp) {
  toastMessage.value = resp.error ? resp.error : resp.result.error.message
  isToastOpen.value = true
}

function handlePageLoading(args) {
  clearTimeout(timer.value)
  startDate.value = args.viewStart
  endDate.value = args.viewEnd
  timer.value = setTimeout(() => {
    if (outlookCalendarSync.isSignedIn()) {
      isLoading.value = true
      outlookCalendarSync
        .getEvents(calendarIds.value, startDate.value, endDate.value)
        .then((events) => {
          myEvents.value = events
          isLoading.value = false
        })
        .catch(handleError)
    }
  }, 200)
}

function toggleCalendar(ev, calendarId) {
  const checked = ev.target.checked
  calendarData.value[calendarId].checked = checked
  if (checked) {
    isLoading.value = true
    calendarIds.value = [...calendarIds.value, calendarId]
    outlookCalendarSync
      .getEvents([calendarId], startDate.value, endDate.value)
      .then((events) => {
        isLoading.value = false
        myEvents.value = [...myEvents.value, ...events]
      })
      .catch(handleError)
  } else {
    calendarIds.value = calendarIds.value.filter((id) => id !== calendarId)
    myEvents.value = myEvents.value.filter((item) => item.outlookCalendarId !== calendarId)
  }
}

function openPopup() {
  myAnchor.value = buttonRef.value.instance.nativeElement
  isPopupOpen.value = true
}

function navigate() {
  mySelectedDate.value = new Date()
}

function signIn() {
  if (!outlookCalendarSync.isSignedIn()) {
    outlookCalendarSync.signIn().catch(handleError)
  }
}

function signOut() {
  outlookCalendarSync.signOut().catch(handleError)
}

onMounted(() => {
  function onSignedIn() {
    isLoggedIn.value = true
    outlookCalendarSync
      .getCalendars()
      .then((calendars) => {
        const newCalendarIds = []
        const newCalendarData = {}

        calendars.sort((c) => (c.isDefaultCalendar ? -1 : 1))

        for (const c of calendars) {
          newCalendarIds.push(c.id)
          newCalendarData[c.id] = { checked: true }
        }

        calendarIds.value = newCalendarIds
        calendarData.value = newCalendarData
        myCalendars.value = calendars
        isLoading.value = true

        return outlookCalendarSync.getEvents(newCalendarIds, startDate.value, endDate.value)
      })
      .then((events) => {
        myEvents.value = events
        isLoading.value = false
      })
      .catch(handleError)
  }

  const onSignedOut = () => {
    calendarIds.value = []
    calendarData.value = {}
    isLoggedIn.value = false
    isPopupOpen.value = false
    myCalendars.value = []
    myEvents.value = []
  }

  // Init Outlook Client
  outlookCalendarSync.init({
    redirectUri: '<YOUR_OUTLOOK_REDIRECT_URI>',
    clientId: '<YOUR_OUTLOOK_CLIENT_ID>',
    onSignedIn: onSignedIn,
    onSignedOut: onSignedOut
  })
})
</script>

<template>
  <MbscEventcalendar
    :data="myEvents"
    :exclusiveEndDates="true"
    :selectedDate="mySelectedDate"
    :view="myView"
    @page-loading="handlePageLoading"
    @selected-date-change="mySelectedDate = $event.date"
  >
    <template #header>
      <MbscCalendarNav />
      <div :class="'mds-loader' + (isLoading ? ' mds-loader-visible' : '')"></div>
      <div class="mbsc-flex mbsc-flex-1-0 mbsc-justify-content-end">
        <MbscButton v-if="isLoggedIn" ref="buttonRef" @click="openPopup"> My Calendars </MbscButton>
        <MbscButton v-if="!isLoggedIn" @click="signIn">Sync my outlook calendars</MbscButton>
        <MbscButton @click="navigate">Today</MbscButton>
      </div>
      <MbscCalendarPrev />
      <MbscCalendarNext />
    </template>
  </MbscEventcalendar>
  <MbscPopup
    display="anchored"
    :anchor="myAnchor"
    :contentPadding="false"
    :isOpen="isPopupOpen"
    :scrollLock="false"
    :showOverlay="false"
    :touchUi="false"
    :width="400"
    @close="isPopupOpen = false"
  >
    <div class="mbsc-form-group-inset">
      <div class="mbsc-form-group-title">My Calendars</div>
      <MbscSwitch
        v-for="cal in myCalendars"
        :key="cal.id"
        :label="cal.name"
        v-model="calendarData[cal.id].checked"
        @change="toggleCalendar($event, cal.id)"
      />
    </div>
    <div class="mbsc-form-group-inset">
      <MbscButton cssClass="mbsc-button-block" @click="signOut">Log out of my account</MbscButton>
    </div>
  </MbscPopup>
  <MbscToast :message="toastMessage" :isOpen="isToastOpen" @close="isToastOpen = false" />
</template>

<style>
.mds-loader {
  width: 32px;
  height: 32px;
  border: 4px solid #8c8c8c;
  border-bottom-color: transparent;
  border-radius: 50%;
  display: inline-block;
  box-sizing: border-box;
  animation: mds-loader-rotation 1s linear infinite;
  visibility: hidden;
}

.mds-loader-visible {
  visibility: visible;
}

@keyframes mds-loader-rotation {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
</style>

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.