Ajouter un bouton direct aux réponses prédéfinies dans l'éditeur

2 clics ne représentent pas vraiment beaucoup de travail, mais c’est une bonne occasion de fournir une explication générale documentant comment travailler avec les boutons de l’éditeur, en se concentrant sur ce que vous essayez de réaliser.

L’ajout de boutons à la barre d’outils s’effectue avec une méthode différente de l’API des plugins.

La barre d’outils utilise cette méthode plugin-api.js.es6#L375-L391 tandis que le menu contextuel utilise celle-ci plugin-api.js.es6#L396-L411

Le plugin des réponses préenregistrées utilise la méthode du menu contextuel comme suit :

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L18-L25

Vous ne pouvez pas déplacer le bouton à moins de forker le plugin — fortement déconseillé.

Ce que vous pouvez faire, c’est ajouter un autre bouton dans la barre d’outils qui fait la même chose et masquer l’ancien. Pour créer un bouton dans la barre d’outils, vous devrez examiner comment d’autres boutons sont ajoutés.

Il existe deux types de boutons dans la barre d’outils. Le premier type concerne les boutons qui gèrent le formatage comme le Gras et l’Italique. Comme ils ne sont pas similaires à ce que vous souhaitez réaliser, ignorons-les pour l’instant.

L’autre type regroupe les boutons qui insèrent des éléments tels que des dates et des émojis. Examinons le bouton date - calendrier.

Nous avons maintenant un exemple de référence. Essayons donc de créer le nouveau bouton.

Nous commençons par ceci :

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
  
  });
});

et nous ajoutons les attributs du bouton de réponse préenregistrée un par un. Pour référence, voici ces attributs :

id: "canned_replies_button",
icon: "far-clipboard",
action: "showCannedRepliesButton",
label: "canned_replies.composer_button_text"

id : cela vous permet d’ajouter des classes CSS au bouton — nous utiliserons custom-canned-button.

icon : l’icône utilisée par le bouton — nous la garderons identique.

label : les boutons du menu contextuel ont du texte, tandis que les boutons de l’éditeur n’en ont pas, nous devons donc le changer en title et utiliser la même valeur.

action : c’est ici que vous définissez ce que fait le bouton. Mettons tout cela ensemble :

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
    id: "custom-canned-replies",
    icon: "far-clipboard",
    action: "showCannedRepliesButton",
    title: "canned_replies.composer_button_text"
  });
});

Si vous essayez cela, vous obtiendrez un bouton dans la barre d’outils, mais cliquer dessus ne fera rien. Cela se produit parce que l’action showCannedRepliesButton n’est pas définie. Cela est dû au contexte différent — puisque vous faites cela dans un thème.

Si vous examinez le plugin des réponses préenregistrées, vous remarquerez que cette action est définie dans le contrôleur de l’éditeur :

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L5-L16

La prochaine étape consiste donc à référencer le contrôleur de l’éditeur afin de pouvoir envoyer cette action lors du clic sur le bouton. Vous pouvez le faire ainsi :

const composerController = api.container.lookup("controller:composer");

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
    title: "canned_replies.composer_button_text",
    id: "custom-canned-replies",
    group: "extras",
    icon: "far-clipboard",
    sendAction: () => composerController.send("showCannedRepliesButton")
  });
});

Remarquez que nous avons utilisé le même modèle que pour le bouton calendrier pour sendAction. Les deux seules exceptions sont que, au lieu de toolbar.context.send, nous utilisons composerController.send.

De plus, nous ne passons pas l’événement, car je ne pense pas que cela soit nécessaire.

Cela devrait vous donner un bouton entièrement fonctionnel dans la barre d’outils :

Mais nous n’avons pas encore terminé, car ce bouton est maintenant visible pour tous les membres. Les permissions d’utilisation s’appliquent toujours, et si un utilisateur sans permission tente de cliquer dessus, il obtiendra simplement une erreur. Cependant, un bouton cassé n’est pas acceptable, alors corrigeons cela.

Les permissions pour utiliser les réponses préenregistrées se trouvent ici :

https://github.com/discourse/discourse-canned-replies/blob/master/assets/javascripts/initializers/add-canned-replies-ui-builder.js.es6#L34-L38

Nous devons donc simplement reproduire ces conditions pour l’ajout du bouton. Quelque chose comme ceci :

const currentUser = api.getCurrentUser();
const canUseCannedReplies = currentUser
  ? currentUser.can_use_canned_replies
  : false;

if (!canUseCannedReplies) return;

Cela garantit que le bouton n’est affiché que si vous disposez des permissions requises.

Réunissons donc tout :

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "move-canned-button",
  initialize() {
    withPluginApi("0.8.7", api => {
      const currentUser = api.getCurrentUser();
      const canUseCannedReplies = currentUser
        ? currentUser.can_use_canned_replies
        : false;

      if (!canUseCannedReplies) return;

      const composerController = api.container.lookup("controller:composer");

      api.onToolbarCreate(toolbar => {
        toolbar.addButton({
          title: "canned_replies.composer_button_text",
          id: "custom-canned-replies",
          group: "extras",
          icon: "far-clipboard",
          sendAction: () => composerController.send("showCannedRepliesButton")
        });
      });
    });
  }
};

Ceci doit être placé dans ce fichier dans un composant de thème :

javascripts/discourse/initializers/move-canned-button.js.es6

si vous utilisez la nouvelle fonctionnalité Split up theme Javascript into multiple files — fortement recommandée.

Ou vous pouvez simplement ajouter ce script dans l’onglet En-tête de votre thème si vous le faites via l’administration.

Ancienne syntaxe
<script type="text/discourse-plugin"
        version="0.8">
const currentUser = api.getCurrentUser();
const canUseCannedReplies = currentUser
  ? currentUser.can_use_canned_replies
  : false;

if (!canUseCannedReplies) return;

const composerController = api.container.lookup("controller:composer");

api.onToolbarCreate(toolbar => {
  toolbar.addButton({
    title: "canned_replies.composer_button_text",
    id: "custom-canned-replies",
    group: "extras",
    icon: "far-clipboard",
    sendAction: () => composerController.send("showCannedRepliesButton")
  });
});
</script>

La dernière chose dont vous avez besoin est de masquer l’ancien bouton, ce que vous pouvez faire ainsi :

.toolbar-popup-menu-options {
  [data-name="Canned replies"] {
    display: none;
  }
}