Fazendo alterações personalizadas na barra lateral programaticamente

Este é um ótimo recurso, mas e se o conteúdo de uma seção personalizada da barra lateral precisar ser criado programaticamente? Consegui isso de uma forma semelhante à @Olya_Fursova acima, apenas que o conteúdo é gerado consultando a API e, em seguida, renderizando links, alguns para categorias e outros diretamente para tópicos específicos. Dois problemas que encontrei são:

  • Se a barra lateral estiver oculta quando a página for renderizada inicialmente, o conteúdo dinâmico não será exibido, pois o contêiner da barra lateral não está presente. Além disso, quando a barra lateral é exibida inicialmente, mas depois recolhida e exibida novamente, o conteúdo dinâmico desaparece porque o contêiner da barra lateral é renderizado novamente sem que a lógica personalizada seja executada. Pergunta: existe alguma maneira de interceptar o processo de renderização da barra lateral para executar meu código personalizado sempre que a barra lateral for exibida?
  • Quando os links que adiciono à barra lateral programaticamente são clicados, a página inteira é atualizada. Pergunta: existe alguma maneira de evitar uma atualização completa da página quando um dos meus links personalizados na barra lateral é clicado?

Seria fantástico se houvesse uma maneira de modificar a barra lateral programaticamente!

Criamos uma API para adicionar seções personalizadas à barra lateral também

Existem alguns exemplos nos comentários aqui: discourse/app/assets/javascripts/discourse/app/lib/plugin-api.js at 00ab94bf53b784478d0aa7744bf3bb2d5b527580 · discourse/discourse · GitHub

Isso está marcado como experimental, mas deve ser seguro de usar (nós o usamos para adicionar conteúdo de chat à barra lateral quando habilitado, por exemplo)

Isso parece interessante, obrigado! Levará algum tempo para realmente entender, por exemplo, ainda não entendi bem o roteamento. Além disso, parece que os links em uma seção só podem ser uma lista plana, certo? O que estou tentando alcançar no momento é algo assim, ou seja, um nível de indentação:

É algo que posso alcançar com a nova API para seções personalizadas na barra lateral?

Não, não criamos nenhum tipo de recuo na barra lateral por padrão… mas, desde que você consiga organizar suas seções na ordem desejada com a API, acho que o recuo pode ser tratado com estilo em CSS?

Tendo investigado um pouco mais, tenho confiança de que isso funcionará, sim! Meu desafio agora é que a lista de links é dinâmica e pode mudar potencialmente a cada mudança de página. Minha abordagem ingênua de chamar api.addSidebarSection de dentro de api.onPageChange não funciona porque (a) a barra lateral só é atualizada quando é renderizada novamente, escondendo-a e mostrando-a novamente e (b) as seções são repetidas porque api.addSidebarSection não se importa se a chave de nome é reutilizada.

Alguma chance de eu conseguir uma seção de barra lateral que seja atualizada a cada transição de página com a nova API?

Você pode dar uma olhada em como o chat-plugin é integrado à barra lateral:

Neste caso, o estado dos links é mantido no objeto de serviço e sempre que o estado é alterado, a barra lateral é atualizada:

Uma solução potencial seria assinar o evento de mudança de página e atualizar os links. O pseudocódigo pode parecer com:

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

api.addSidebarSection(
  (BaseCustomSidebarSection, BaseCustomSidebarSectionLink) => {
    const TestSectionLink = class extends BaseCustomSidebarSectionLink {
      // defina suas propriedades de link personalizadas aqui
    };

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

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

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

      get newLinksArray() {
        // lista de links com base na URL atual
      }

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

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