Как отобразить виджет в меню-гамбургере?

Привет,

Я хочу отобразить виджет в меню-бургере. Я посмотрел на (Deprecated) Display a "Discord Widget" in a dropdown button, чтобы разобраться, но не могу показать кнопку в меню-бургере.
Вот мой код:

const showModal = require("discourse/lib/show-modal").default;

api.createWidget("modal-button", {
  tagName: "a.test",

  html() {
    return "Открыть модальное окно";
  },

  click() {
    showModal("fareharbor");
  }
});

api.decorateWidget("hamburger-menu:generalLinks", function(helper) {
  return [helper.attach('modal-button')];
});

Что я делаю не так?

Насколько я могу судить, единственная ваша проблема заключается в том, что helper.attach() не существует.

Вам следует использовать helper.widget.attach()

Спасибо за быстрый ответ!
Я попробовал ваше предложение, но это тоже не сработало :man_shrugging:

Я попытался добавить простой HTML-элемент вот так:

api.decorateWidget("hamburger-menu:generalLinks", function(helper) {
  return helper.h("div", "test text");
});

Но это не сработало :thinking:

Вы делаете это внутри withPluginApi()?

Насколько мне известно, нет. А должен?

Этот код работает, так как он корректно добавляет элемент в гамбургер-меню:

api.decorateWidget("hamburger-menu:generalLinks", function(helper) {
  return {href: "", rawLabel: "test"}
});

Но я не знаю, можно ли вызвать showModal("fareharbor"); без использования виджета.

И с днём рождения! :slight_smile:

редактирование:
Вот мой полный код:

const showModal = require("discourse/lib/show-modal").default;

api.createWidget("modal-button", {
  tagName: "a.test",

  html() {
    return "Open Modal";
  },

  click() {
    showModal("fareharbor");
  }
});

// не работает
api.decorateWidget("hamburger-menu:generalLinks", function(helper) {
  return [helper.widget.attach('modal-button')];
});

// работает
api.decorateWidget("hamburger-menu:generalLinks", function(helper) {
  return {href: "", rawLabel: "test"}
});

Часть return [helper.widget.attach('modal-button')]; создаёт пустую ссылку:

<li><a class="widget-link" href="" title=""><span class="d-label"></span></a></li>

Где находится этот код? Вы используете пользовательское меню администратора для его добавления?

Также попробуйте добавить console.log(showModal) внутрь блока html() { } и посмотрите, что будет выведено в консоль.

Да, использую.

Да, выводится какая-то обычная информация, кажется (когда я вызываю модальное окно):
(e,t){t=t||{};var n=(0,c.getOwner)(this),s=n.lookup("route:application"),a=s.controllerFor("modal");a.set("modalClass",t.modalClass||"".concat((0,u.dasherize)(e).toLowerCase(),"-modal"));var i=t.admi…

Но, если я что-то не так понимаю, моя проблема не во взаимодействии с модальным окном (оно работает), а в размещении моего виджета в гамбургер-меню.

Я следовал этому уроку по созданию модальных окон, и он работает идеально: пользовательская кнопка открывает модальное окно.



Модальное окно работает.
Добавление кнопки виджета в шаблон работает и вызывает модальное окно.
Добавление обычной ссылки в гамбургер-меню работает.
…Но добавление кнопки виджета в гамбургер не работает и создаёт пустую ссылку. Существуют ли какие-то ограничения при использовании decorateWidget с “hamburger-menu”? :thinking:

Я передал это в соответствующий канал, и вопрос скоро рассмотрят. Возможно, что-то мешает этому работать корректно.

Спасибо, что подняли эту тему :smile:

С днём рождения, Джордан!

API был спроектирован с идеей, что всё в generalLinks будет виджетом link:

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/app/widgets/hamburger-menu.js#L189

Таким образом, приведённый выше пример возвращает другой экземпляр Widget, тогда как на самом деле нужно возвращать один или несколько литералов объектов JavaScript, как в вашем рабочем примере. Эти объекты являются аргументами для виджета link, чтобы ссылки отображались корректно.

Похоже, что ваша цель — открыть модальное окно. Это можно реализовать с помощью action. Попробуйте следующее:

const showModal = require("discourse/lib/show-modal").default;

api.reopenWidget('hamburger-menu', {
  openThing(e) {
     showModal('thing-modal');
  }
});

api.decorateWidget("hamburger-menu:generalLinks", function(helper) {
  return { action: 'openThing', label: 'open.thing' };
});

В этом случае я добавляю новое действие openThing к гамбургер-меню, а затем запускаю его через мою ссылку.