La plupart des modules complémentaires se composent de fiches représentant différentes pages de l'interface. Pour une expérience utilisateur efficace, vous devez utiliser une navigation simple et naturelle entre les cartes de votre module complémentaire.
À l'origine dans les modules complémentaires Gmail, les transitions entre les différentes cartes de l'interface utilisateur étaient gérées en envoyant et en effaçant des cartes vers et depuis une seule pile de cartes, la fiche supérieure de la pile étant affichée par Gmail.
Les modules complémentaires Google Workspace introduisent des pages d'accueil et des fiches non contextuelles. Pour les cartes contextuelles et non contextuelles, les modules complémentaires Google Workspace disposent d'une pile interne pour chacun. Lorsqu'un module complémentaire est ouvert dans un hôte, l'homepageTrigger
correspondante se déclenche pour créer la première fiche de la page d'accueil sur la pile (la carte "page d'accueil" bleu foncé dans le schéma ci-dessous).
Si aucun élément homepageTrigger
n'est défini, une fiche par défaut est créée, affichée et transférée dans la pile non contextuelle. La première est une carte racine.
Votre module complémentaire peut créer des fiches non contextuelles supplémentaires et les envoyer sur la pile (les "cartes push" bleues du diagramme) lorsque l'utilisateur parcourt votre module. L'interface utilisateur du module complémentaire affiche la carte supérieure de la pile. Par conséquent, lorsque vous placez de nouvelles fiches dans la pile, l'écran est modifié et lorsque vous faites apparaître des cartes hors de la pile, l'écran revient aux cartes précédentes.
Si votre module complémentaire est associé à un déclencheur de contexte défini, il est exécuté lorsque l'utilisateur saisit ce contexte. La fonction de déclenchement crée la fiche contextuelle, mais l'interface utilisateur est mise à jour en fonction du DisplayStyle
de la nouvelle carte:
- Si la valeur de
DisplayStyle
est définie surREPLACE
(valeur par défaut), la carte contextuelle (carte "orange" de couleur sombre du diagramme) remplace la carte actuellement affichée. Cela démarre efficacement une nouvelle pile de cartes contextuelles en plus de la pile de cartes non contextuelles. Cette carte contextuelle est la carte racine de la pile contextuelle. - Si la valeur de
DisplayStyle
estPEEK
, l'interface utilisateur crée à la place un en-tête d'aperçu qui apparaît en bas de la barre latérale du module complémentaire et affiche la fiche actuelle. L'en-tête d'aperçu affiche le titre de la nouvelle carte et fournit des commandes permettant à l'utilisateur de décider s'il doit afficher la nouvelle carte ou non. S'il clique sur le bouton Afficher, la fiche remplace la carte actuelle (comme décrit ci-dessus parREPLACE
).
Vous pouvez créer des fiches contextuelles supplémentaires et les transmettre à la pile (les "cartes push" jaunes dans le schéma). La mise à jour de la pile de cartes modifie l'interface utilisateur du module complémentaire pour afficher la fiche du haut. Si l'utilisateur quitte le contexte, les cartes contextuelles de la pile sont supprimées et l'affichage passe à la page d'accueil ou à la carte non contextuelles les plus populaires.
Si l'utilisateur entre dans un contexte que votre module complémentaire ne définit pas de déclencheur contextuel, aucune nouvelle carte n'est créée et la carte actuelle reste affichée.
Les actions Navigation
décrites ci-dessous agissent uniquement sur les fiches du même contexte. Par exemple, popToRoot()
à partir d'une fiche contextuelle n'affiche que les autres fiches contextuelles et n'affecte pas les fiches de la page d'accueil.
En revanche, le bouton
est toujours disponible pour que l'utilisateur puisse passer de vos fiches contextuelles à vos cartes non contextuelles.Méthodes de navigation
Vous pouvez créer des transitions entre des cartes en ajoutant ou en supprimant des fiches de la pile. La classe Navigation
fournit des fonctions permettant d'envoyer et de sortir des cartes depuis les piles. Pour créer une navigation efficace, vous devez configurer vos widgets de manière à utiliser des actions de navigation. Vous pouvez envoyer ou afficher plusieurs fiches simultanément, mais vous ne pouvez pas supprimer la première page de la page d'accueil qui est initialement insérée dans la pile au démarrage du module complémentaire.
Pour accéder à une nouvelle fiche en réponse à une interaction de l'utilisateur avec un widget, procédez comme suit:
- Créez un objet
Action
et associez-le à une fonction de rappel que vous définissez. - Appelez la fonction de gestionnaire de widgets appropriée du widget pour définir le
Action
sur ce widget. - Implémentez la fonction de rappel qui effectue la navigation. Un objet d'événement d'action est attribué à cette fonction en tant qu'argument. Elle doit :
- Créez un objet
Navigation
pour définir le changement de fiche. Un seul objetNavigation
peut contenir plusieurs étapes de navigation, effectuées dans l'ordre dans lequel elles ont été ajoutées à l'objet. - Créez un objet
ActionResponse
à l'aide de la classeActionResponseBuilder
et de l'objetNavigation
. - Renvoyez l'objet
ActionResponse
compilé.
- Créez un objet
Lorsque vous créez des commandes de navigation, vous utilisez les fonctions d'objet Navigation
suivantes:
Fonction | Description |
---|---|
Navigation.pushCard(Card) |
Transférer une carte dans la pile actuelle. Pour cela, vous devez d'abord créer la carte. |
Navigation.popCard() |
Supprime une carte du haut de la pile. Équivaut à cliquer sur la flèche de retour dans la ligne d'en-tête du module complémentaire. Les cartes racine ne sont pas supprimées. |
Navigation.popToRoot() |
Supprime toutes les cartes de la pile, à l'exception de la carte racine. Cette opération réinitialise essentiellement la pile de cartes. |
Navigation.popToNamedCard(String) |
Fait éclater les cartes de la pile jusqu'à ce qu'elles atteignent une carte portant le nom donné ou la carte racine de la pile. Vous pouvez attribuer des noms aux fiches à l'aide de la fonction CardBuilder.setName(String) . |
Navigation.updateCard(Card) |
Remplacement de la carte actuelle en actualisant la carte dans l'interface utilisateur |
Bonnes pratiques de navigation
Si une interaction ou un événement d'un utilisateur doit entraîner l'affichage de cartes dans le même contexte, remplacez les fiches existantes par les méthodes Navigation.pushCard()
, Navigation.popCard()
et Navigation.updateCard()
. Si une interaction ou un événement utilisateur doit entraîner le réaffichage des fiches dans un contexte différent, utilisez ActionResponseBuilder.setStateChanged()
pour forcer la réexécution de votre module complémentaire dans ces contextes.
Voici des exemples de navigation:
- Si une interaction ou un événement modifie l'état de la carte actuelle (par exemple, l'ajout d'une tâche à une liste de tâches), utilisez
updateCard()
. - Si une interaction ou un événement fournit plus de détails ou invite l'utilisateur à effectuer une action supplémentaire (par exemple, cliquer sur le titre d'un élément pour afficher plus de détails, ou appuyer sur un bouton pour créer un événement Agenda), utilisez
pushCard()
pour afficher la nouvelle page tout en permettant à l'utilisateur de quitter la nouvelle page à l'aide du bouton "Retour". - Si une interaction ou un événement est mis à jour dans une fiche précédente (par exemple, si vous modifiez le titre d'un élément dans la vue détaillée), utilisez
popCard()
,popCard()
,pushCard(previous)
etpushCard(current)
pour mettre à jour la carte précédente et la carte actuelle.
Actualiser les fiches
Les modules complémentaires Google Workspace permettent aux utilisateurs d'actualiser votre carte en exécutant à nouveau la fonction de déclenchement Apps Script enregistrée dans votre fichier manifeste. Les utilisateurs déclenchent cette actualisation via un élément de menu complémentaire:
Cette action est automatiquement ajoutée aux cartes générées par les fonctions de déclenchement homepageTrigger
ou contextualTrigger
, comme spécifié dans le fichier manifeste de votre module complémentaire (les "racines" des piles de cartes contextuelles et non contextuelles).
Retour de plusieurs cartes
Les fonctions de page d'accueil ou de déclencheurs contextuels permettent de créer et de renvoyer un seul objet Card
ou un tableau d'objets Card
que l'interface utilisateur de l'application affiche.
S'il n'y a qu'une seule carte, celle-ci est ajoutée à la pile contextuelle et non contextuelle, car la carte racine est affichée dans l'interface utilisateur de l'application hôte.
Si le tableau renvoyé comprend plusieurs objets Card
compilés, l'application hôte affiche une nouvelle fiche, qui contient la liste de l'en-tête de chaque carte. Lorsque l'utilisateur clique sur l'un de ces en-têtes, l'interface utilisateur affiche la fiche correspondante.
Lorsque l'utilisateur sélectionne une carte dans la liste, celle-ci est transmise à la pile actuelle et l'application hôte l'affiche. Le bouton
renvoie l'utilisateur à la liste d'en-tête de la fiche.Cet accord "plat" peut s'avérer efficace si votre module complémentaire ne nécessite aucune transition entre les cartes que vous créez. Toutefois, dans la plupart des cas, il est recommandé de définir directement les transitions de carte, et de faire en sorte que votre page d'accueil et vos fonctions de déclenchement contextuel renvoient un seul objet de carte.
Exemple
Voici un exemple montrant comment créer plusieurs fiches avec des boutons de navigation qui passent de l'une à l'autre. Vous pouvez ajouter ces fiches à la pile contextuelle ou non en les transférant vers createNavigationCard()
dans un contexte particulier ou en dehors.
/**
* Create the top-level card, with buttons leading to each of three
* 'children' cards, as well as buttons to backtrack and return to the
* root card of the stack.
* @return {Card}
*/
function createNavigationCard() {
// Create a button set with actions to navigate to 3 different
// 'children' cards.
var buttonSet = CardService.newButtonSet();
for(var i = 1; i <= 3; i++) {
buttonSet.addButton(createToCardButton(i));
}
// Build the card with all the buttons (two rows)
var card = CardService.newCardBuilder()
.setHeader(CardService.newCardHeader().setTitle('Navigation'))
.addSection(CardService.newCardSection()
.addWidget(buttonSet)
.addWidget(buildPreviousAndRootButtonSet()));
return card.build();
}
/**
* Create a button that navigates to the specified child card.
* @return {TextButton}
*/
function createToCardButton(id) {
var action = CardService.newAction()
.setFunctionName('gotoChildCard')
.setParameters({'id': id.toString()});
var button = CardService.newTextButton()
.setText('Card ' + id)
.setOnClickAction(action);
return button;
}
/**
* Create a ButtonSet with two buttons: one that backtracks to the
* last card and another that returns to the original (root) card.
* @return {ButtonSet}
*/
function buildPreviousAndRootButtonSet() {
var previousButton = CardService.newTextButton()
.setText('Back')
.setOnClickAction(CardService.newAction()
.setFunctionName('gotoPreviousCard'));
var toRootButton = CardService.newTextButton()
.setText('To Root')
.setOnClickAction(CardService.newAction()
.setFunctionName('gotoRootCard'));
// Return a new ButtonSet containing these two buttons.
return CardService.newButtonSet()
.addButton(previousButton)
.addButton(toRootButton);
}
/**
* Create a child card, with buttons leading to each of the other
* child cards, and then navigate to it.
* @param {Object} e object containing the id of the card to build.
* @return {ActionResponse}
*/
function gotoChildCard(e) {
var id = parseInt(e.parameters.id); // Current card ID
var id2 = (id==3) ? 1 : id + 1; // 2nd card ID
var id3 = (id==1) ? 3 : id - 1; // 3rd card ID
var title = 'CARD ' + id;
// Create buttons that go to the other two child cards.
var buttonSet = CardService.newButtonSet()
.addButton(createToCardButton(id2))
.addButton(createToCardButton(id3));
// Build the child card.
var card = CardService.newCardBuilder()
.setHeader(CardService.newCardHeader().setTitle(title))
.addSection(CardService.newCardSection()
.addWidget(buttonSet)
.addWidget(buildPreviousAndRootButtonSet()))
.build();
// Create a Navigation object to push the card onto the stack.
// Return a built ActionResponse that uses the navigation object.
var nav = CardService.newNavigation().pushCard(card);
return CardService.newActionResponseBuilder()
.setNavigation(nav)
.build();
}
/**
* Pop a card from the stack.
* @return {ActionResponse}
*/
function gotoPreviousCard() {
var nav = CardService.newNavigation().popCard();
return CardService.newActionResponseBuilder()
.setNavigation(nav)
.build();
}
/**
* Return to the initial add-on card.
* @return {ActionResponse}
*/
function gotoRootCard() {
var nav = CardService.newNavigation().popToRoot();
return CardService.newActionResponseBuilder()
.setNavigation(nav)
.build();
}