Plugin: access to toolbarEvent from modal

AI-generated summary

The discussion revolves around accessing the toolbarEvent from a modal in a Discourse plugin. sirdavidoff is struggling to pass the toolbarEvent to a modal when a button is clicked on the top level of the toolbar, but it works when the button is under a menu.

pmusaraj suggests that the toolbarEvent should be available in the modal controller and recommends looking at how other modals handle this. However, sirdavidoff found that in the discourse-calendar plugin, the toolbarEvent is passed through setProperties().

keegan provides a solution by passing the event as a parameter to the action using action: (event) =>. This allows accessing the toolbarEvent in the modal. Joshua_Soileau confirms that this solution works and provides another example of how to implement it.

In summary, the solution involves passing the toolbarEvent as a parameter to the action, allowing it to be accessed in the modal.

My plugin inserts a button in the composer toolbar. This toolbar opens a modal, and when the modal is closed I want to add text to the post. Everything works perfectly except the last step, because I’m struggling to give the modal access to the composer.

If I put the button under a menu in the toolbar, everything works fine:

      api.modifyClass("controller:composer", {
        pluginId: "discourse-n8n-wf",
        actions: {
          showWfModal2() {
            showModal("discourse-n8n-wf").setProperties({"toolbarEvent": this.toolbarEvent});
          },
        },
      });
      api.addToolbarPopupMenuOptionsCallback(() => {
        return {
          action: "showWfModal2",
          icon: "network-wired",
          label: "n8n workflow"
        };
      });

But if I put it on the top level, I don’t seem to have access to the toolbarEvent to pass to the modal

      Composer.reopen({
        actions: {
          showWfModal: function () {
            console.log(this.toolbarEvent); // undefined
            showModal('discourse-n8n-wf', {title:'Insert n8n workflow'});
          }
        }
      });

      api.onToolbarCreate(toolbar => {
        toolbar.addButton({
          id: 'discourse-n8n-wf',
          group: 'extras',
          icon: 'network-wired',
          action: 'showWfModal',
          title: 'Insert workflow'
        });
      });

Any tips?

The toolbarEvent should be available in your modal controller (discourse-n8n-wf), you don’t need to pass it. You can also look at how other modals do this, for example, see discourse-post-event-builder.js.es6 in the poll plugin.

Thanks, Penar! I’m not quite there yet though:

I found the file you referenced in the discourse-calendar plugin (couldn’t find it in the poll one), but there it seems like the toolbarEvent is indeed being passed in the action (through setProperties())?

Was just wondering whether you had any more thoughts here, @pmusaraj?

Hey @sirdavidoff

Not sure if you’re still stuck on this but I’ve went down the rabbit hole of trying to figure out how to access the toolbar event from a modal as well, and I found you can pass the event as a parameter like this:

action: (event) =>

So I used it like this:

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

  api.onToolbarCreate((toolbar) => {
    toolbar.addButton({
      id: 'math-editor',
      group: 'extras',
      icon: 'square-root-alt',
      sendAction: (event) => composerController.send('showMathEditor', event),
      title: themePrefix('insert_equation'),
    });
  });

and then you can use it in your action: {} method like so:

@action
showMathEditor(event) {
   showModal('matheditor-modal').set('toolbarEvent', event);
}

Want to pile on – years later, I had the same issue (didn’t have access to toolbarEvent inside a modal), and this solution also worked for me.

      api.onToolbarCreate((toolbar) => {
        toolbar.addButton({
          ...
          sendAction: (event) =>
            toolbar.context.send("triggerMyModal", event),
          ...
        });
      });

      api.modifyClass("component:d-editor", {
        modal: service(),
        pluginId: "poll",
        actions: {
          triggerMyModal(toolbarEvent) {
            this.modal.show(MyCustomModal, {
              model: {
                toolbarEvent,
              },
            });
          },
        },
      });

Thanks for the help, Keegan.