Angular & Microsoft Graph [Part 4] : Evènements dans le calendrier avec données personnalisées

Nous avons vu dans les précédents articles comment s'identifier auprès de Microsoft Graph et récupérer la liste de ses calendriers.

Dans notre application, nous voulons pouvoir ajouter des évènements dans ce calendrier pour enregistrer nos interventions chez nos clients. Personnellement, je facture à la demi journée. Donc on va obliger l'application a ne créer des rendez-vous que d'une demi-journée (matin et/ou après-midi).

Si l'on regarde dans Outlook, cela donnera cela :

Mais dans notre application, cela apparaitra comme cela :

Il n'y a pas d'infos sur les heures de début/fin, juste un code couleur qui indique que c'est le matin et l'après-midi.

Mais le plus important, c'est que chaque rendez-vous/évènement possède des informations complémentaires importantes comme le nom du client et le coût de l'intervention sur la demi-journée. Ces informations supplémentaires, Office365 nous propose plusieurs façon de procéder. Ici, j'ai choisi les SingleValueLegacyExtendedProperty (doc sur le site de MS).

On peut ainsi ajouter des propriétés qui nous sont propres à un évènement. Elles peuvent être de type String, Integer ou String Array ou Integer Array.

Ici, j'ai choisi de n'ajouter qu'une seule propriété personnalisé de type String, qui sera en réalité une sérialisation JSON de mon objet contenant les prorpiétés supplémentaires.

Pour gérer cette propriété supplémentaire vous aurez besoin d'un String qui aura cet aspect là :

const MyTjmProperty = 'String {7F477958-DE03-4B4F-89FC-284980AF6C92} Name MyTjmProperties';

On a donc le type suivi d'un Guid suivi de son nom (MyTjmProperties).

Pour créer un évènement dans un calendrier, il suffit d'appeler la méthode POST de l'URL /me/calendars/{id du calendar}/events avec dans le body, les propriétés de notre évènement. c'est là que l'on va ajouter les données spécifiques :

  private createEventImpl(startDate: Date, endDate: Date, tjmEvent: ITjmEventData) {
    const parameters = this.parametersService.load();

    // on utilise le calendrier par défaut ou le calendrier spécifié dans les paramètres
    const url = parameters == null ?
      'me/events' :
      GraphUrl + '/me/calendars/' + parameters.calendar.id + '/events';

      // on est en France que diable !
    const body = {
      subject: tjmEvent.client.name,
      start: {
        dateTime: startDate.toISOString(),
        timeZone: 'Europe/Paris'
      },
      end: {
        dateTime: endDate.toISOString(),
        timeZone: 'Europe/Paris'
      },
      isReminderOn: false,
      categories: ['myTjm'],
      singleValueExtendedProperties: [{
        id: MyTjmProperty,
        value: JSON.stringify(tjmEvent) // les données JSON sérialisées
      }
      ]
    };
    return this.httpClient.post(url, body);
  }

On voit que l'on spécifie la propriété singleValueExtendedProperties avec comme id notre MyTjmProperty définie plus haut.

Pour récupérer que les events du calendrier qui possède cette propriété spécifique, on récupère l'ensemble des évènements du calendrier avec la méthode GET de l'URL /me/calendars/{id du calendrier}/calendarView et on filtre sur ceux possédant cette propriété :

getEvents(startDate: moment.Moment, endDate: moment.Moment): Observable<ITjmEvent[]> {
    const parameters = this.parametersService.load();

    const url = parameters == null ?
      'me/calendarView' :
      '/me/calendars/' + parameters.calendar.id + '/calendarView';

    return this.getClientArray<MicrosoftGraph.Event>(
      url,
      null,
      [
        'startdatetime=' + startDate.toISOString(),
        'enddatetime=' + endDate.toISOString(),
        '$expand=singleValueExtendedProperties($filter= id eq \'' + MyTjmProperty + '\')',
        '$top=100'
      ]).pipe(
        map(r => {
          const result: ITjmEvent[] = [];
          r.value.forEach(item =&gt: {
            const tjmDatas = this.getTjmDatas(item);
            if (item != null && tjmDatas != null) {

              result.push({
                outlookEvent: item,
                datas: tjmDatas
              });
            }
          });
          return result;
        })
      );
  }

  private getTjmDatas(event: any): ITjmEventData {
    const instance = event as ISingleValueExtendedPropertiesOwner;
    if (instance == null) { return null; }
    const props = instance.singleValueExtendedProperties;
    if (props == null || props.length === 0 || props[0].value == null) { return null; }

    return <ITjmEventData>JSON.parse(props[0].value);
  }

Vous remarquerez que j'ai utilisé la composition pour la récupération des données, c'est à dire que l'on a une entité qui a deux propriété, l'une de type Event de Microsoft, l'autre de type spécifique à mes données propres.

blog comments powered by Disqus