Realizando cambios personalizados en la barra lateral mediante programación

Esta es una gran característica, pero ¿qué pasa si el contenido de una sección personalizada de la barra lateral necesita ser creado mediante programación? Lo he logrado de una manera similar a @Olya_Fursova arriba, solo que el contenido se genera consultando la API y luego renderizando enlaces, algunos a categorías y otros directamente a temas específicos. Dos problemas que encontré son:

  • Si la barra lateral está oculta cuando la página se renderiza inicialmente, el contenido dinámico no se mostrará ya que el contenedor de la barra lateral no está presente. Además, cuando la barra lateral se muestra inicialmente pero luego se colapsa y se muestra nuevamente, el contenido dinámico desaparece porque el contenedor de la barra lateral se vuelve a renderizar sin que se ejecute la lógica personalizada. Pregunta: ¿Hay alguna forma de engancharse al proceso de renderizado de la barra lateral para ejecutar mi código personalizado cada vez que se muestra la barra lateral?
  • Cuando se hace clic en los enlaces que agrego a la barra lateral mediante programación, la página completa se actualiza. Pregunta: ¿Hay alguna forma de evitar una actualización completa de la página cuando se hace clic en uno de mis enlaces personalizados en la barra lateral?

¡Sería fantástico si hubiera una manera de modificar la barra lateral mediante programación!

2 Me gusta

También hemos creado una API para añadir secciones personalizadas a la barra lateral.

Hay algunos ejemplos en los comentarios aquí: discourse/app/assets/javascripts/discourse/app/lib/plugin-api.js at 00ab94bf53b784478d0aa7744bf3bb2d5b527580 · discourse/discourse · GitHub

Esto está marcado como experimental, pero debería ser seguro de usar (lo usamos para añadir contenido de chat a la barra lateral cuando está habilitado, por ejemplo).

6 Me gusta

¡Esto parece interesante, gracias! Sin embargo, me llevará tiempo entenderlo realmente, por ejemplo, todavía no capto bien el enrutamiento. Además, parece que los enlaces de una sección solo pueden ser una lista plana, ¿verdad? Lo que estoy intentando lograr actualmente es algo como esto, es decir, un nivel de sangría:

¿Es esto algo que puedo lograr con la nueva API para secciones personalizadas de la barra lateral?

1 me gusta

No, no hemos implementado ningún tipo de sangría en la barra lateral por defecto… pero mientras puedas ordenar tus secciones como quieras con la API, creo que la sangría se puede manejar con estilos en CSS.

Después de investigarlo un poco más, ¡estoy seguro de que esto funcionará, sí! Mi desafío ahora es que la lista de enlaces es dinámica y puede cambiar potencialmente con cada cambio de página. Mi enfoque ingenuo de llamar a api.addSidebarSection desde dentro de api.onPageChange no funciona porque (a) la barra lateral solo se actualiza cuando se vuelve a renderizar ocultándola y volviéndola a mostrar, y (b) las secciones se repiten porque api.addSidebarSection no se preocupa si la clave del nombre se reutiliza.

¿Hay alguna posibilidad de que pueda lograr una sección de barra lateral que se actualice en cada transición de página con la nueva API?

1 me gusta

Puedes echar un vistazo a cómo se integra el plugin de chat con la barra lateral:

En este caso, el estado de los enlaces se mantiene en el objeto de servicio y, siempre que cambia el estado, se actualiza la barra lateral:

Una solución potencial sería suscribirse al evento de cambio de página y actualizar los enlaces. El pseudocódigo podría parecerse a:

import { tracked } from "@glimmer/tracking";

api.addSidebarSection(
  (BaseCustomSidebarSection, BaseCustomSidebarSectionLink) => {
    const TestSectionLink = class extends BaseCustomSidebarSectionLink {
      // define tus propiedades de enlace personalizadas aquí
    };

    const SidebarTestSection = class extends BaseCustomSidebarSection {
      @tracked links = [];

      constructor() {
        super(...arguments);

        this.#updateLinks();
        this.onAppEvent("page:changed", () => this.#updateLinks());
      }

      get newLinksArray() {
        // lista de enlaces basada en la URL actual
      }

      #updateLinks() {
        this.links = this.newLinksArray.map(
          (link) =>
            new TestSectionLink({
              link,
            })
        );
      }

      get sectionLinks() {
        return this.links;
      }
    };
    return SidebarTestSection;
  }
);
6 Me gusta