Exercice – ajouter des boutons et des commandes

Effectué

Dans cet exercice, vous allez ajouter des fonctionnalités au complément que vous avez créé dans le cas d’un exercice précédent. Vous allez créer deux nouveaux boutons qui insèrent un contenu Gist spécifique ou par défaut dans un message. Vous allez également implémenter une expérience de première exécution, dans laquelle vous serez invité à entrer votre nom d’utilisateur GitHub pour récupérer vos gists.

Importante

Cet exercice suppose que vous avez créé le projet de complément Office Outlook avec le générateur Yeoman et vérifié qu’il fonctionne dans Outlook dans l’exercice précédent de ce module.

Définir des boutons

Par défaut, le complément définit uniquement les boutons de la fenêtre de lecture de message. Nous allons mettre à jour le manifeste pour supprimer les boutons de la fenêtre de lecture de message et définir deux nouveaux boutons pour la fenêtre composer un message :

  • Insérer un gist: bouton qui ouvre un le volet des tâches
  • Insérer gist par défaut: bouton qui appelle une fonction

Supprimer le point d’extension MessageReadCommandSurface

Ouvrir le fichier manifest.xml et rechercher l’ExtensionPoint élément avec un type MessageReadCommandSurface. Supprimer cet ExtensionPoint élément (y compris sa balise de fermeture) pour supprimer les boutons de la fenêtre de lecture de message.

Supprimer le point d’extension MessageComposeCommandSurface

Recherchez la ligne dans le manifeste qui lit </DesktopFormFactor>. Situé immédiatement avant cette ligne, insérez le balisage XML suivant.

<!-- Message Compose -->
<ExtensionPoint xsi:type="MessageComposeCommandSurface">
  <OfficeTab id="TabDefault">
    <Group id="msgComposeCmdGroup">
      <Label resid="GroupLabel"/>
      <Control xsi:type="Button" id="msgComposeInsertGist">
        <Label resid="TaskpaneButton.Label"/>
        <Supertip>
          <Title resid="TaskpaneButton.Title"/>
          <Description resid="TaskpaneButton.Tooltip"/>
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="ShowTaskpane">
          <SourceLocation resid="Taskpane.Url"/>
        </Action>
      </Control>
      <Control xsi:type="Button" id="msgComposeInsertDefaultGist">
        <Label resid="FunctionButton.Label"/>
        <Supertip>
          <Title resid="FunctionButton.Title"/>
          <Description resid="FunctionButton.Tooltip"/>
        </Supertip>
        <Icon>
          <bt:Image size="16" resid="Icon.16x16"/>
          <bt:Image size="32" resid="Icon.32x32"/>
          <bt:Image size="80" resid="Icon.80x80"/>
        </Icon>
        <Action xsi:type="ExecuteFunction">
          <FunctionName>insertDefaultGist</FunctionName>
        </Action>
      </Control>
    </Group>
  </OfficeTab>
</ExtensionPoint>

Remarque

  • L’élément ExtensionPoint avec xsi:type="MessageComposeCommandSurface" indique que vous définissez des boutons à ajouter à la fenêtre de composition d’un message.
  • En utilisant un élément OfficeTab avec id="TabDefault", vous indiquez que vous voulez ajouter des boutons à l’onglet par défaut dans le ruban.
  • L’élément Group définit le regroupement de nouveaux boutons, avec une étiquette définie par la ressource groupLabel.
  • Le premier élément Control contient un élément Action avec xsi:type="ShowTaskPane", afin que le bouton ouvre un volet des tâches.
  • Le deuxième élément Control contient un élément Action avec xsi:type="ExecuteFunction", afin que le bouton appelle une fonction JavaScript contenue dans le fichier de fonction.

Ressources de mise à jour dans le fichier manifeste

Le code précédent fait référence aux étiquettes, info-bulles et URL que vous devez définir avant que le manifeste ne soit valide. Spécifiez ces informations dans la section Resources du manifeste.

  1. Recherchez l’élément Resources dans le fichier manifeste, puis supprimez entièrement l’élément (balise de fermeture comprise).

  2. À ce même emplacement, ajoutez le balisage suivant pour remplacer l’élément Resources que vous avez supprimé :

    <Resources>
      <bt:Images>
        <bt:Image id="Icon.16x16" DefaultValue="https://localhost:3000/assets/icon-16.png"/>
        <bt:Image id="Icon.32x32" DefaultValue="https://localhost:3000/assets/icon-32.png"/>
        <bt:Image id="Icon.80x80" DefaultValue="https://localhost:3000/assets/icon-80.png"/>
      </bt:Images>
      <bt:Urls>
        <bt:Url id="Commands.Url" DefaultValue="https://localhost:3000/commands.html"/>
        <bt:Url id="Taskpane.Url" DefaultValue="https://localhost:3000/taskpane.html"/>
      </bt:Urls>
      <bt:ShortStrings>
        <bt:String id="GroupLabel" DefaultValue="Git the gist"/>
        <bt:String id="TaskpaneButton.Label" DefaultValue="Insert gist"/>
        <bt:String id="TaskpaneButton.Title" DefaultValue="Insert gist"/>
        <bt:String id="FunctionButton.Label" DefaultValue="Insert default gist"/>
        <bt:String id="FunctionButton.Title" DefaultValue="Insert default gist"/>
      </bt:ShortStrings>
      <bt:LongStrings>
        <bt:String id="TaskpaneButton.Tooltip" DefaultValue="Displays a list of your gists and allows you to insert their contents into the current message."/>
        <bt:String id="FunctionButton.Tooltip" DefaultValue="Inserts the content of the gist you mark as default into the current message."/>
      </bt:LongStrings>
    </Resources>
    
  3. Enregistrez les modifications dans le manifeste.

Réinstallez le complément.

Puisque vous avez apporté des modifications au manifeste, réinstallez le complément pour que ces modifications prennent effet.

  1. Si le serveur web est en cours d’exécution, fermez la fenêtre de commande de nœud.

  2. Exécutez la commande suivante pour démarrer le serveur web local et charger automatiquement votre complément.

    npm start
    

Une fois le complément réinstallé, vous pouvez vérifier qu’il a été correctement installé en consultant les commandes Insérer gist et Insérer gist par défaut dans le fenêtre de composition du message. Rien ne se produit si vous sélectionnez un des ces éléments, car vous n’avez pas encore terminé la création de ce complément.

  • Si vous exécutez ce complément dans Outlook 2016 ou versions ultérieures sur Windows, vous devriez voir deux nouveaux boutons dans le ruban de la fenêtre de composition d’un message : Insérer gist et Insérer gist par défaut.

    Capture d’écran d’Outlook sur Windows avec les boutons du complément mis en surbrillance dans le menu de dépassement du ruban.

  • Si vous exécutez ce complément dans Outlook sur le web, vous devriez voir apparaître un nouveau bouton en bas de la fenêtre de composition d’un message. Sélectionnez ce bouton pour afficher les options Insérer gist et Insérer gist par défaut.

    Capture d’écran du formulaire de composition de message dans Outlook sur le web avec le bouton de complément et le menu contextuel mis en surbrillance.

Mettre en œuvre une expérience de première exécution

Ce complément doit lire les Gist du compte d’utilisateur GitHub et d’identifier celui que l’utilisateur a choisi en tant que Gist par défaut. Pour atteindre ces objectifs, le complément doit inviter l’utilisateur à fournir son nom d’utilisateur GitHub et choisir un Gist par défaut parmi sa collection de Gist existants. Suivez les étapes décrites dans cette section pour implémenter une expérience de première exécution qui affiche une boîte de dialogue pour collecter ces informations à partir de l’utilisateur.

Collecter les données d’un utilisateur

Commençons par créer l’interface utilisateur pour la boîte de dialogue. Dans le dossier ./src, créez un sous-dossier nommé settings. Dans le dossier ./src/settings, créez un fichier nommé dialog.html et ajoutez le balisage suivant pour définir un formulaire simple avec une entrée de texte pour un nom d’utilisateur GitHub et une liste vide pour Gist qui sera renseignée via JavaScript.

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
  <title>Settings</title>

  <!-- Office JavaScript API -->
  <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>

  <!-- For more information on Fluent UI, visit https://developer.microsoft.com/fluentui. -->
  <link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/9.6.1/css/fabric.min.css"/>

  <!-- Template styles -->
  <link href="dialog.css" rel="stylesheet" type="text/css" />
</head>

<body class="ms-font-l">
  <main>
    <section class="ms-font-m ms-fontColor-neutralPrimary">
      <div class="not-configured-warning ms-MessageBar ms-MessageBar--warning">
        <div class="ms-MessageBar-content">
          <div class="ms-MessageBar-icon">
            <i class="ms-Icon ms-Icon--Info"></i>
          </div>
          <div class="ms-MessageBar-text">
            Oops! It looks like you haven't configured <strong>Git the gist</strong> yet.
            <br/>
            Please configure your GitHub username and select a default gist, then try that action again!
          </div>
        </div>
      </div>
      <div class="ms-font-xxl">Settings</div>
      <div class="ms-Grid">
        <div class="ms-Grid-row">
          <div class="ms-TextField">
            <label class="ms-Label">GitHub Username</label>
            <input class="ms-TextField-field" id="github-user" type="text" value="" placeholder="Please enter your GitHub username">
          </div>
        </div>
        <div class="error-display ms-Grid-row">
          <div class="ms-font-l ms-fontWeight-semibold">An error occurred:</div>
          <pre><code id="error-text"></code></pre>
        </div>
        <div class="gist-list-container ms-Grid-row">
          <div class="list-title ms-font-xl ms-fontWeight-regular">Choose Default Gist</div>
          <form>
            <div id="gist-list">
            </div>
          </form>
        </div>
      </div>
      <div class="ms-Dialog-actions">
        <div class="ms-Dialog-actionsRight">
          <button class="ms-Dialog-action ms-Button ms-Button--primary" id="settings-done" disabled>
            <span class="ms-Button-label">Done</span>
          </button>
        </div>
      </div>
    </section>
  </main>
  <script type="text/javascript" src="../../node_modules/jquery/dist/jquery.js"></script>
  <script type="text/javascript" src="../helpers/gist-api.js"></script>
  <script type="text/javascript" src="dialog.js"></script>
</body>

</html>

Vous avez peut-être remarqué que le fichier HTML fait référence à un fichier JavaScript, gist-api.js, qui n'existe pas encore. Ce fichier sera créé dans la section Extraire les données de GitHub ci-dessous.

Ensuite, créez un fichier dans le dossier./src/settings nommé dialog.css et ajoutez le code suivant pour spécifier les styles utilisés par dialog.html.

section {
  margin: 10px 20px;
}

.not-configured-warning {
  display: none;
}

.error-display {
  display: none;
}

.gist-list-container {
  margin: 10px -8px;
  display: none;
}

.list-title {
  border-bottom: 1px solid #a6a6a6;
  padding-bottom: 5px;
}

ul {
  margin-top: 10px;
}

.ms-ListItem-secondaryText,
.ms-ListItem-tertiaryText {
  padding-left: 15px;
}

Maintenant que vous avez défini la boîte de dialogue interface utilisateur, vous pouvez écrire du code pour l’utiliser. Créez un fichier dans le dossier ./src/settings nommé dialog.js et ajoutez le code suivant. Ce code utilise jQuery pour enregistrer des événements et la fonction messageParent pour renvoyer les choix de l’utilisateur à l’appelant.

(function(){
  'use strict';

  // The Office initialize function must be run each time a new page is loaded.
  Office.initialize = function(reason){
    jQuery(document).ready(function(){
      if (window.location.search) {
        // Check if warning should be displayed.
        const warn = getParameterByName('warn');
        if (warn) {
          $('.not-configured-warning').show();
        } else {
          // See if the config values were passed.
          // If so, pre-populate the values.
          const user = getParameterByName('gitHubUserName');
          const gistId = getParameterByName('defaultGistId');

          $('#github-user').val(user);
          loadGists(user, function(success){
            if (success) {
              $('.ms-ListItem').removeClass('is-selected');
              $('input').filter(function() {
                return this.value === gistId;
              }).addClass('is-selected').attr('checked', 'checked');
              $('#settings-done').removeAttr('disabled');
            }
          });
        }
      }

      // When the GitHub username changes,
      // try to load gists.
      $('#github-user').on('change', function(){
        $('#gist-list').empty();
        const ghUser = $('#github-user').val();
        if (ghUser.length > 0) {
          loadGists(ghUser);
        }
      });

      // When the Done button is selected, send the
      // values back to the caller as a serialized
      // object.
      $('#settings-done').on('click', function() {
        const settings = {};

        settings.gitHubUserName = $('#github-user').val();

        const selectedGist = $('.ms-ListItem.is-selected');
        if (selectedGist) {
          settings.defaultGistId = selectedGist.val();

          sendMessage(JSON.stringify(settings));
        }
      });
    });
  };

  // Load gists for the user using the GitHub API
  // and build the list.
  function loadGists(user, callback) {
    getUserGists(user, function(gists, error){
      if (error) {
        $('.gist-list-container').hide();
        $('#error-text').text(JSON.stringify(error, null, 2));
        $('.error-display').show();
        if (callback) callback(false);
      } else {
        $('.error-display').hide();
        buildGistList($('#gist-list'), gists, onGistSelected);
        $('.gist-list-container').show();
        if (callback) callback(true);
      }
    });
  }

  function onGistSelected() {
    $('.ms-ListItem').removeClass('is-selected').removeAttr('checked');
    $(this).children('.ms-ListItem').addClass('is-selected').attr('checked', 'checked');
    $('.not-configured-warning').hide();
    $('#settings-done').removeAttr('disabled');
  }

  function sendMessage(message) {
    Office.context.ui.messageParent(message);
  }

  function getParameterByName(name, url) {
    if (!url) {
      url = window.location.href;
    }
    name = name.replace(/[\[\]]/g, "\\$&");
    const regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
      results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
  }
})();

Mettre à jour les paramètres de configuration webapck

Enfin, ouvrez le fichier webpack.config.js situé dans le répertoire racine du projet et procédez comme suit.

  1. Recherchez l’objet entry dans l’objet config et ajoutez une nouvelle entrée pour dialog.

    dialog: "./src/settings/dialog.js"
    

    Lorsque c’est chose faite, le nouvel objet entry se présente comme suit :

    entry: {
      polyfill: ["core-js/stable", "regenerator-runtime/runtime"],
      taskpane: "./src/taskpane/taskpane.js",
      commands: "./src/commands/commands.js",
      dialog: "./src/settings/dialog.js"
    },
    
  2. Recherchez la matrice plugins au sein de l’objet config. Dans patternsle tableau de new CopyWebpackPluginl'objet, ajoutez de nouvelles entrées pour taskpane.css et dialog.css.

    {
      from: "./src/taskpane/taskpane.css",
      to: "taskpane.css",
    },
    {
      from: "./src/settings/dialog.css",
      to: "dialog.css",
    },
    

    Lorsque c’est chose faite, l’objet new CopyWebpackPlugin se présente comme suit :

    new CopyWebpackPlugin({
      patterns: [
      {
        from: "./src/taskpane/taskpane.css",
        to: "taskpane.css",
      },
      {
        from: "./src/settings/dialog.css",
        to: "dialog.css",
      },
      {
        from: "assets/*",
        to: "assets/[name][ext][query]",
      },
      {
        from: "manifest*.xml",
        to: "[name]." + buildType + "[ext]",
        transform(content) {
          if (dev) {
            return content;
          } else {
            return content.toString().replace(new RegExp(urlDev, "g"), urlProd);
          }
        },
      },
    ]}),
    
  3. Dans le même tableau à pluginsl'intérieur de configl'objet, ajoutez ce nouvel objet à la fin du tableau.

    new HtmlWebpackPlugin({
      filename: "dialog.html",
      template: "./src/settings/dialog.html",
      chunks: ["polyfill", "dialog"]
    })
    

    Lorsque c’est chose faite, la nouvelle matrice plugins se présente comme suit :

    plugins: [
      new HtmlWebpackPlugin({
        filename: "taskpane.html",
        template: "./src/taskpane/taskpane.html",
        chunks: ["polyfill", "taskpane"],
      }),
      new CopyWebpackPlugin({
        patterns: [
        {
          from: "./src/taskpane/taskpane.css",
          to: "taskpane.css",
        },
        {
          from: "./src/settings/dialog.css",
          to: "dialog.css",
        },
        {
          from: "assets/*",
          to: "assets/[name][ext][query]",
        },
        {
          from: "manifest*.xml",
          to: "[name]." + buildType + "[ext]",
          transform(content) {
            if (dev) {
              return content;
            } else {
              return content.toString().replace(new RegExp(urlDev, "g"), urlProd);
            }
          },
        },
      ]}),
      new HtmlWebpackPlugin({
        filename: "commands.html",
        template: "./src/commands/commands.html",
        chunks: ["polyfill", "commands"],
      }),
      new HtmlWebpackPlugin({
        filename: "dialog.html",
        template: "./src/settings/dialog.html",
        chunks: ["polyfill", "dialog"]
      })
    ],
    

Récupérer des données à partir de GitHub

Le fichier dialog.js que vous avez créé spécifie que le complément doit charger des gists lorsque l’événement modification se déclenche pour le champ de nom d’utilisateur GitHub. Pour récupérer les gists de l’utilisateur à partir de GitHub, vous utiliserez le API GitHub Gists.

Dans le dossier ./src, créez un nouveau sous-dossier nommé helpers. Dans le dossier ./src/helpers, créez un fichier nommé gist-api.js et ajoutez le code suivant pour récupérer les gists de l’utilisateur à partir de GitHub et créer la liste des gists.

function getUserGists(user, callback) {
  const requestUrl = 'https://api.github.com/users/' + user + '/gists';

  $.ajax({
    url: requestUrl,
    dataType: 'json'
  }).done(function(gists){
    callback(gists);
  }).fail(function(error){
    callback(null, error);
  });
}

function buildGistList(parent, gists, clickFunc) {
  gists.forEach(function(gist) {

    const listItem = $('<div/>')
      .appendTo(parent);

    const radioItem = $('<input>')
      .addClass('ms-ListItem')
      .addClass('is-selectable')
      .attr('type', 'radio')
      .attr('name', 'gists')
      .attr('tabindex', 0)
      .val(gist.id)
      .appendTo(listItem);

    const desc = $('<span/>')
      .addClass('ms-ListItem-primaryText')
      .text(gist.description)
      .appendTo(listItem);

    const desc = $('<span/>')
      .addClass('ms-ListItem-secondaryText')
      .text(' - ' + buildFileList(gist.files))
      .appendTo(listItem);

    const updated = new Date(gist.updated_at);

    const desc = $('<span/>')
      .addClass('ms-ListItem-tertiaryText')
      .text(' - Last updated ' + updated.toLocaleString())
      .appendTo(listItem);

    listItem.on('click', clickFunc);
  });
}

function buildFileList(files) {

  let fileList = '';

  for (let file in files) {
    if (files.hasOwnProperty(file)) {
      if (fileList.length > 0) {
        fileList = fileList + ', ';
      }

      fileList = fileList + files[file].filename + ' (' + files[file].language + ')';
    }
  }

  return fileList;
}

Exécutez la commande suivante pour regénérer le projet.

npm run build

Implémentation d’un bouton sans interface utilisateur

Le bouton Insérer gist par défaut de ce complément est un bouton sans interface utilisateur qui appelera une fonction JavaScript, plutôt que d’ouvrir un volet des tâches comme de nombreux boutons de complément le font. Lorsque l’utilisateur sélectionne le bouton Insérer gist par défaut, la fonction JavaScript correspondante vérifie si le complément a été configuré.

  • Si le complément a déjà été configuré, la fonction chargera le contenu du gist que l’utilisateur a sélectionné par défaut et l’insérera dans le corps du message.
  • Si le complément n'a pas encore été configuré, la boîte de dialogue Paramètres invitera l’utilisateur à fournir les informations nécessaires.

Mettre à jour le fichier de fonction (HTML)

Une fonction appelée par un bouton sans interface utilisateur doit être définie dans le fichier de fonction spécifié par l’élément FunctionFile dans le manifeste pour le facteur de formulaire correspondant. Le manifeste de ce complément spécifie https://localhost:3000/commands.html comme fichier de fonction.

Ouvrez le fichier ./src/commands/commands.html et remplacez tout le contenu par le balisage suivant.

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=Edge" />

  <!-- Office JavaScript API -->
  <script type="text/javascript" src="https://appsforoffice.microsoft.com/lib/1.1/hosted/office.js"></script>

  <script type="text/javascript" src="../../node_modules/jquery/dist/jquery.js"></script>
  <script type="text/javascript" src="../../node_modules/showdown/dist/showdown.min.js"></script>
  <script type="text/javascript" src="../../node_modules/urijs/src/URI.min.js"></script>
  <script type="text/javascript" src="../helpers/addin-config.js"></script>
  <script type="text/javascript" src="../helpers/gist-api.js"></script>
</head>

<body>
  <!-- NOTE: The body is empty by design. Since functions in commands.js are invoked using a button, there is no UI to render. -->
</body>

</html>

Vous avez peut-être remarqué que le fichier HTML fait référence à un fichier JavaScript, addin-config.js , qui n'existe pas encore. Ce fichier sera créé dans la section Créer un fichier pour gérer les paramètres plus tard dans ce tutoriel.

Mettre à jour le fichier de fonction (JavaScript)

Ouvrez le fichier ./src/commands/commands.js et remplacez tout le contenu par le code suivant. Si la fonction insertDefaultGist() détermine que le complément n'a pas encore été configuré, elle ajoute le ?warn=1 paramètre à l’URL de la boîte de dialogue. Cette opération permet à la boîte de dialogue Paramètres de restituer la barre des messages définie dans./settings/dialog.html, pour transmettre à l’utilisateur pourquoi il voit la boîte de dialogue.

let config;
let btnEvent;

// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
};

// Add any UI-less function here.
function showError(error) {
  Office.context.mailbox.item.notificationMessages.replaceAsync('github-error', {
    type: 'errorMessage',
    message: error
  }, function(result){
  });
}

let settingsDialog;

function insertDefaultGist(event) {

  config = getConfig();

  // Check if the add-in has been configured.
  if (config && config.defaultGistId) {
    // Get the default gist content and insert.
    try {
      getGist(config.defaultGistId, function(gist, error) {
        if (gist) {
          buildBodyContent(gist, function (content, error) {
            if (content) {
              Office.context.mailbox.item.body.setSelectedDataAsync(content,
                {coercionType: Office.CoercionType.Html}, function(result) {
                  event.completed();
              });
            } else {
              showError(error);
              event.completed();
            }
          });
        } else {
          showError(error);
          event.completed();
        }
      });
    } catch (err) {
      showError(err);
      event.completed();
    }

  } else {
    // Save the event object so we can finish up later.
    btnEvent = event;
    // Not configured yet, display settings dialog with
    // warn=1 to display warning.
    const url = new URI('../src/settings/dialog.html?warn=1').absoluteTo(window.location).toString();
    const dialogOptions = { width: 20, height: 40, displayInIframe: true };

    Office.context.ui.displayDialogAsync(url, dialogOptions, function(result) {
      settingsDialog = result.value;
      settingsDialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogMessageReceived, receiveMessage);
      settingsDialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogEventReceived, dialogClosed);
    });
  }
}

// Register the function.
Office.actions.associate("insertDefaultGist", insertDefaultGist);

function receiveMessage(message) {
  config = JSON.parse(message.message);
  setConfig(config, function(result) {
    settingsDialog.close();
    settingsDialog = null;
    btnEvent.completed();
    btnEvent = null;
  });
}

function dialogClosed(message) {
  settingsDialog = null;
  btnEvent.completed();
  btnEvent = null;
}

Créer un fichier pour gérer les paramètres de configuration

Le fichier fonction HTML fait référence à un fichier nommé addin-config.js, qui n’existe pas encore. Dans le dossier ./src/helpers, créez un fichier nommé addin-config.js et ajoutez le code suivant. Ce code utilise l’objet RoamingSettings pour obtenir et définir les valeurs de configuration.

function getConfig() {
  const config = {};

  config.gitHubUserName = Office.context.roamingSettings.get('gitHubUserName');
  config.defaultGistId = Office.context.roamingSettings.get('defaultGistId');

  return config;
}

function setConfig(config, callback) {
  Office.context.roamingSettings.set('gitHubUserName', config.gitHubUserName);
  Office.context.roamingSettings.set('defaultGistId', config.defaultGistId);

  Office.context.roamingSettings.saveAsync(callback);
}

Créer de nouvelles fonctions pour traiter les gists

Ouvrez le fichier ./src/helpers/gist-api.js et ajoutez les fonctions suivantes.

function getGist(gistId, callback) {
  const requestUrl = 'https://api.github.com/gists/' + gistId;

  $.ajax({
    url: requestUrl,
    dataType: 'json'
  }).done(function(gist){
    callback(gist);
  }).fail(function(error){
    callback(null, error);
  });
}

function buildBodyContent(gist, callback) {
  // Find the first non-truncated file in the gist
  // and use it.
  for (let filename in gist.files) {
    if (gist.files.hasOwnProperty(filename)) {
      const file = gist.files[filename];
      if (!file.truncated) {
        // We have a winner.
        switch (file.language) {
          case 'HTML':
            // Insert as-is.
            callback(file.content);
            break;
          case 'Markdown':
            // Convert Markdown to HTML.
            const converter = new showdown.Converter();
            const html = converter.makeHtml(file.content);
            callback(html);
            break;
          default:
            // Insert contents as a <code> block.
            let codeBlock = '<pre><code>';
            codeBlock = codeBlock + file.content;
            codeBlock = codeBlock + '</code></pre>';
            callback(codeBlock);
        }
        return;
      }
    }
  }
  callback(null, 'No suitable file found in the gist');
}

Remarque

  • Si le gist contient du HTML, le complément insère le code HTML tel quel dans le corps du message.
  • Si le gist contient Markdown, le complément utilise la bibliothèqueShowdown pour convertir le Markdown en HTML, et insère le code HTML qui en résulte dans le corps du message.
  • Si le gist contient autre chose que du HTML ou Markdown, le complément l’insère dans le corps du message comme un extrait de code.

Tester le bouton d'insertion par défaut du gist

Si le serveur n’est pas déjà en cours d’exécution, enregistrez toutes vos modifications et exécutez npm start à partir de l’invite de commandes. Effectuez les étapes suivantes pour tester le bouton Insérer un gist par défaut.

  1. Ouvrez Outlook et rédigez un nouveau message.

  2. Dans la fenêtre composer un message, sélectionnez le boutonInsérer gist par défaut. Vous devriez être invité à configurer le complément.

    Capture d’écran de l’invite du complément à configurer.

  3. Dans la boîte de dialogue Paramètres, entrez votre nom d’utilisateur GitHub, puis appuyez sur Tab ou sélectionnez un autre emplacement dans la boîte de dialogue pour appeler l’événement modification, qui doit charger votre liste de gists. Sélectionnez un gist par défaut, puis cliquez surTerminer.

    Capture d’écran de la boîte de dialogue paramètres du complément.

  4. Cliquez de nouveau sur le bouton Insérer un gist par défaut. Cette fois, le contenu du gist est inséré dans le corps du courrier électronique.

    Remarque

    Outlook sur Windows : pour récupérer les paramètres les plus récents, vous devrez peut-être fermer et rouvrir la fenêtre de composition d’un message.

Synthèse

Dans cet exercice, vous avez ajouté des fonctionnalités additionnelles au complément que vous avez créé lors d’un exercice précédent. Vous avez créé deux nouveaux boutons qui insèrent un contenu Gist spécifique ou par défaut dans un message. Vous avez également implémenté une expérience de première exécution, où vous avez été invité à entrer votre nom d’utilisateur GitHub pour récupérer vos gists.

Testez vos connaissances

1.

Pour ajouter un bouton à un complément de rédaction de message Outlook, vous devez ajouter le contrôle à quel type de point d’extension dans le fichier manifeste du complément ?

2.

Pour appeler une fonction JavaScript à partir d’un bouton du ruban de l’application Office défini dans le manifeste du complément, vous devez effectuer laquelle des opérations suivantes ?