Estas diretrizes visam criar uma interface de administração coesa, focando na usabilidade, acessibilidade e um layout estruturado. Consulte o índice para ver o que está incluído e navegar facilmente para cada seção.
Nota: A terminologia usada aqui é definida no glossário da interface de administração.
0. Prefácio - Estrutura da página de configuração e links da barra lateral
Ao adicionar novas páginas de configuração na interface de administração, cada página precisará de um link para a barra lateral, e cada página precisará de um título e uma descrição de cabeçalho. Isso é para que sejamos consistentes em todos os lugares, e melhorias futuras na pesquisa de administração possam exibir todo o layout da interface de administração.
Geralmente, a estrutura da interface de administração parece com isso:
- Interface de administração
- Página de configuração (exibida na barra lateral)
- Aba de configurações
- Abas opcionais de terceiro nível
- Editar/Novo recurso de terceiro nível
- Página de configuração (exibida na barra lateral)
Eventualmente, uma “visão geral da seção” será inserida entre a interface raiz e as páginas de configuração.
Links da barra lateral
Todas as páginas de administração devem ser adicionadas ao ADMIN_NAV_MAP em discourse/frontend/discourse/app/lib/sidebar/admin-nav-map.js at main · discourse/discourse · GitHub . Cada item deve ter, no mínimo, estas chaves:
name- Um identificador único para o link, deve estar emsnake_caserouteOUhref- Orouteé um identificador de rota Ember, comoadminUsers. Para administradores, estes são definidos no mapa de rotas de administração . Umhrefpode ser usado no lugar, masrouteé preferível.labelOUtext- Label é uma chave I18n, que geralmente deve seradmin.config.page_name.title(veja a seção de traduções abaixo). Setextfor usado, será texto já traduzido.
Estas chaves opcionais também podem ser fornecidas:
description- É recomendado que você também forneça isso. É uma chave I18n, geralmente deve seradmin.config.page_name.header_description.icon- Também recomendado, isso é exibido ao lado do link na barra lateral.routeModels- Matriz de dados de URL para o caso de parâmetros de rota. Por exemplo,adminCustomizeThemestem um parâmetro de rota:type, então você pode passarrouteModels: ["components"]. Os itens da matriz são usados na mesma ordem em que os parâmetros de rota aparecem.moderator: Defina isso comotruese moderadores devem ver esta página na barra lateral.keywords: Uma chave I18n, com uma lista de palavras-chave separadas por|para o link da barra lateral, usada para “peso extra de pesquisa” ao filtrar/pesquisar páginas.links: Uma lista de rotas de 3º nível que estão abaixo da página na barra lateral. Estes não são exibidos na própria barra lateral. Isso será usado para recursos futuros de pesquisa de administração.settings_areaesettings_category: Se a página mostrar apenas uma lista de configurações do site filtradas, então uma destas deve ser preenchida. Se a configuração do site tiver umaareadefinida, que é usada emAdminAreaSettings, entãosettings_areadeve ser usada. Se uma categoria inteira de configurações for exibida na página, e também usada emAdminAreaSettings, entãosettings_categorydeve ser usada.multi_tabbed: Se a página tiver uma aba de configuração e outras abas, então isso deve ser definido como true. Ajuda a gerar links para o sistema de pesquisa de administração.
Traduções
O título e a descrição do cabeçalho para cada página de configuração devem estar sob:
- admin
- config
- page_name
- title: “Título da página”
- header_description: “Esta página é para xyz”
- page_name
- config
Você pode ver exemplos disso aqui:
1. Migalhas (Breadcrumbs)
As migalhas servem como uma ferramenta de navegação, ajudando os usuários a entender sua localização atual, estrutura de conteúdo e hierarquia dentro da interface de administração.
Admin > Migalha > Rastro
Título da página
Design
Estrutura
- Admin: prefixo fixo que aparece no início de cada rastro de migalhas, vinculando a
/admin - Link: abre a página na mesma janela
- Separador: um ícone
angle-rightsepara cada link
Uso
Quando usar:
- Presente em todas as páginas de administração
- Situado acima do conteúdo (título, descrição, abas)
- Mostra a página atualmente selecionada
Quando não usar:
- Ao visitar uma nova rota ou de edição
Conteúdo
- Cada item inclui um link para sua página relacionada
- Mostra a página atualmente selecionada
Acessibilidade
- Um elemento
navcomaria-label="Breadcrumb"envolve uma lista ordenada para fornecer um marco de navegação - Aplique
aria-current="page"no último link para indicar que é a página atual - Para mais detalhes, veja Exemplo de Migalhas das Práticas de Autoria WAI-ARIA
Implementação
O componente DBreadcrumbsContainer deve ser colocado em algum lugar na página:
<DBreadcrumbsContainer />
Em seguida, cada elemento DBreadcrumbsItem adicionado a qualquer componente em uma rota ou rota filha será renderizado neste container. Cada DBreadcrumbsItem tem um @label e @path que devem ser fornecidos:
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
<DBreadcrumbsItem
@path="/admin/plugins"
@label={{i18n "admin.plugins.title"}}
/>
<DBreadcrumbsItem
@path="/admin/plugins/{{@plugin.name}}"
@label={{@plugin.nameTitleized}}
/>
Como isso parece com um exemplo visual, usando o plugin Discourse AI:
2. Cabeçalho e título da página
A seção superior de uma página de administração, contendo o título da página, junto com ações e descrição opcionais.
Design
Estrutura
-
Título da página: Título da página
-
Descrição da página: Introdução ou descrição do que o conteúdo abrange (opcional)
-
Ação primária: Ação primária do título da página (opcional)
-
Ação secundária: Configurações do botão de ação secundária do título da página (opcional)
Uso e conteúdo
-
Título da página: Utilize o nível de cabeçalho 1 para explicar o assunto principal da página em caixa de frases. Geralmente, a tradução I18n deve estar sob
admin.config.your_page.title. -
Descrição da página: Suporta nós básicos de markdown como
_itálico_,**negrito**e[nome do link](url) -
Ação primária: Utilize
btn-primary. Não inclua um ícone. Geralmente, a tradução I18n deve estar sobadmin.config.your_page.header_description. -
Ação secundária: Utilize as configurações do botão
btn-default, visível apenas se existir uma ação primária. Não inclua um ícone.
Seja claro com os botões de ação. Por exemplo, use rótulos descritivos como “Adicionar emoji” em vez de apenas “Adicionar” para reduzir a ambiguidade.
Implementação
O componente DPageHeader é usado aqui. Isso aceita argumentos para @titleLabel, @descriptionLabel, @learnMoreUrl e @shouldDisplay. Isso usa yields nomeados no Ember para fornecer 5 blocos nomeados para o conteúdo:
breadcrumbs- Quaisquer componentes adicionaisDBreadcrumbsItempara a página devem ser colocados aqui.actions- Usado para definir os botões à direita do título. Isso rende um objeto chamadoactionsque pode ser usado para renderizar botõesDefault,Primary,DangereWrapped.title- Uma alternativa ao@titleLabel, permitindo marcação personalizada dentro do cabeçalho.drawer- Uma seção de gaveta colapsável opcional, exibida quando@showDraweré true.tabs- Usado para definir as abas da página usando componentesNavItem.@hideTabspode ser usado para remover esta parte do cabeçalho se não for necessária.
Um exemplo completo está abaixo:
<DPageHeader
@titleLabel={{i18n "admin.config.backups.title"}}
@descriptionLabel={{i18n "admin.config.backups.header_description"}}
@learnMoreUrl="https://meta.discourse.org/t/create-download-and-restore-a-backup-of-your-discourse-database/122710"
>
<:breadcrumbs>
<DBreadcrumbsItem
@path="/admin/backups"
@label={{i18n "admin.backups.title"}}
/>
</:breadcrumbs>
<:actions as |actions|>
<actions.Primary
@action={{routeAction "showStartBackupModal"}}
@title="admin.backups.operations.backup.title"
@label="admin.backups.operations.backup.label"
class="admin-backups__start"
/>
</:actions>
<:tabs>
<NavItem
@route="admin.backups.settings"
@label="settings"
class="admin-backups-tabs__settings"
/>
<NavItem
@route="admin.backups.index"
@label="admin.backups.menu.backup_files"
class="admin-backups-tabs__files"
/>
<NavItem
@route="admin.backups.logs"
@label="admin.backups.menu.logs"
class="admin-backups-tabs__logs"
/>
<PluginOutlet @name="downloader" @connectorTagName="div" />
</:tabs>
</DPageHeader>
Os títulos das páginas para a aba do navegador são tratados nas rotas Ember usando a funcionalidade titleToken. Cada vez que isso é usado em uma rota, ele adiciona o token ao final do título da aba do navegador. Esteja ciente de que você deve usar a classe DiscourseRoute para estender sua rota, não a Route normal do ember para que isso funcione:
titleToken() {
return i18n("admin.config.backups.title");
}
O cabeçalho da página é automaticamente ocultado para caminhos
/newe/editpara suportar Rotas de terceiro nível. Pode ser substituído usando o argumento@shouldDisplay.
3. Abas
Uma navegação opcional que fornece acesso a níveis mais profundos de configurações ou recursos. Também nos referimos a isso como páginas ou navegação de “terceiro nível”.
Design
Estamos usando abas para alternar entre visualizações diferentes, mas relacionadas, dentro do mesmo contexto.
Uso
- Não usado para navegação primária
- Apenas uma ativa por vez
Implementação
Veja os detalhes do Cabeçalho da Página, as abas são definidas no componente DPageHeader.
![]()
4. Página de destino de visão geral/seção
Permite que os usuários vejam o conteúdo de uma seção, especialmente quando a barra lateral está recolhida ou em dispositivos móveis.
Design
Estrutura
Use um layout de três colunas iguais usando um sistema de grade. Em telas pequenas, essas colunas serão empilhadas verticalmente.
Design e uso
- Pode ser acessado através de migalhas (Admin > Comunidade > Visão geral)
- Cada seção deve ter uma, exceto plugins (que mostram instalados) e relatórios (apenas uma página)
- O item tem:
- nome - igual ao link da seção
- descrição - uma breve descrição do que a página trata
- ícone - mesmo ícone usado para a barra lateral
Implementação
Fragmentos de código ou link para um tópico/GitHub
5. Conteúdo da página
A área principal de uma página de administração onde configurações, configurações e outros conteúdos são exibidos e interagidos.
Design
Estrutura
Use um layout 2/3 + 1/3 usando um sistema de grade. A seção primária ocupa dois terços e a seção secundária ocupa um terço do espaço. Em telas pequenas, essas colunas serão empilhadas verticalmente.
- Área de configuração: Uma seção específica dentro do conteúdo da página dedicada a configurações e ajustes.
- Ajuda/referência/inserção: Uma área dentro do conteúdo da página fornecendo guias, documentação ou informações contextuais adicionais. (opcional)
Design e uso
- Agrupe configurações e ações semelhantes em cartões
- Estruture layouts primário/secundário para que a seção primária (2/3) seja usada para configurações principais, e a seção secundária (1/3) seja para informações adicionais ou contexto útil
- Se a seção secundária não estiver disponível, mantenha a largura da seção primária a mesma
Conteúdo
- Siga as diretrizes para área de configuração ao adicionar conteúdo
- Siga as diretrizes para conteúdo de inserção de ajuda
Implementação
Fragmentos de código ou links do GitHub
5.a. Subcabeçalho
Um subcabeçalho é um cabeçalho secundário usado para dividir o conteúdo sob uma seção, geralmente abaixo das abas.
Estrutura
- Subcabeçalho: Subcabeçalho do que o conteúdo abrange (opcional)
- Ação primária: Ação primária do subcabeçalho (opcional)
- Ação secundária: Configurações do botão de ação secundária do subcabeçalho (opcional)
Uso e conteúdo
-
Subcabeçalho: Utilize o nível de cabeçalho 2 para explicar o assunto principal do conteúdo relacionado. Inclua apenas se:
- Houver um botão de ação primário, ou
- Houver uma descrição explicando a seção.
-
Ação primária: Utilize
btn-primary. Não inclua um ícone. -
Ação secundária: Utilize as configurações do botão
btn-default, visível apenas se existir uma ação primária. Não inclua um ícone.
Seja claro com os botões de ação. Por exemplo, use rótulos descritivos como “Adicionar emoji” em vez de apenas “Adicionar” para reduzir a ambiguidade.
Implementação
Isso é semelhante ao DPageHeader, há um componente DPageSubheader. A principal diferença é que há apenas um yield nomeado para actions.
actions- Usado para definir os botões à direita do título. Isso rende um objeto chamadoactionsque pode ser usado para renderizar botõesDefault,Primary,DangereWrapped.
<DPageSubheader @titleLabel="admin.config.backups.subheader.title">
<:actions>
<actions.Primary
@action={{routeAction "showStartBackupModal"}}
@title="admin.backups.operations.backup.title"
@label="admin.backups.operations.backup.label"
class="admin-backups__start"
/>
</:actions>
</DPageSubheader>
5.b. Área de configuração
A área de configuração é composta por cartões ou seções. Os cartões são ótimos para agrupar informações e tarefas relacionadas, ajudando os usuários a escanear e priorizar o conteúdo mais facilmente.
Design
Cartão
Os cartões são configurados com um raio de borda de 2px e usam um fundo de --secondary. Eles também têm uma borda sólida de 1px com --primary-low e 20px de preenchimento ao redor do conteúdo.
Variação padrão
Variação de acordeão
Design e uso
- Agrupe informações relacionadas
- Exiba informações para que administradores e moderadores vejam as coisas mais importantes primeiro
- Use cabeçalhos que expliquem claramente para que serve o cartão
- Divida os complicados em várias seções, se necessário
variação padrão
- Mantenha uma chamada primária para ação por cartão
- Coloque a chamada primária para ação na parte inferior do cartão para próximos passos
variação de acordeão
- Use o canto superior direito do cartão para ações opcionais como “Ver tudo”
Conteúdo
-
Todos os formulários devem usar os componentes ember FormKit no núcleo descritos na documentação
-
Os cabeçalhos dos cartões devem estar em caixa de frases
Faça
Não façaConfigurações gerais Configurações Gerais Informações de contato INFORMAÇÕES DE CONTATO
Implementação
Temos um componente AdminConfigAreaCard que deve ser usado para todos esses cartões. Por enquanto, isso só tem argumentos @translatedHeading e @heading, no futuro podemos adicionar ações e torná-los colapsáveis e assim por diante:
<AdminConfigAreaCard
@heading="admin.config_areas.about.general_settings"
class="admin-config-area-about__general-settings-section"
>
<AdminConfigAreasAboutGeneralSettings
@generalSettings={{this.generalSettings}}
@setGlobalSavingStatus={{this.setSavingStatus}}
@globalSavingStatus={{this.saving}}
/>
</AdminConfigAreaCard>
Configurações do site embutidas
Esta seção está em andamento.
5.c. Inserção de ajuda
Esta seção fornece orientação adicional, documentação ou contexto dentro do conteúdo da página.
v1
Design
Design e uso
- Mostre documentação ou guias relacionados ao conteúdo da página para fornecer informações úteis
- Inclua um ícone no cabeçalho para torná-lo facilmente reconhecível
- Coloque esta seção na área de layout secundário (1/3)
Conteúdo
- Os cabeçalhos devem estar em caixa de frases
Implementação
Fragmentos de código ou link para um tópico/GitHub
5.d. Tabela
As tabelas exibem informações em uma grade de células, colunas e linhas, facilitando para os administradores escanear rapidamente itens e tomar medidas.
Design
Uso
- Use tabelas para exibir conteúdo estruturado onde cada entrada compartilha os mesmos atributos.
- Permita que os administradores revisem, habilitem/desabilitem, editem e excluam conjuntos de dados.
- Adequado para conjuntos de dados que continuarão a crescer com o tempo.
Design
- Use linhas horizontais entre as linhas para separar visualmente o conteúdo, incluindo a última linha. Evite usar bordas ou molduras ao redor da tabela para evitar que pareça uma rede.
- Não aplique linhas verticais entre as colunas. Tabelas sem linhas verticais são geralmente mais fáceis de escanear e ler.
Ações adicionais
- Ações de linha: Inclua ações adicionais na coluna mais à direita de cada linha da tabela.
- Se houver dois ou mais elementos interativos, a ação primária (por exemplo, “Editar”) deve ser um botão de texto, e todas as outras ações de linha, incluindo “Excluir”, devem ser agrupadas em uma lista suspensa
[...]. Ícones nos menus suspensos são encorajados para separar visualmente as coisas. - Se houver apenas uma ação “Excluir” e nenhuma ação primária, use um botão de texto “Excluir” em linha estilizado como
btn-default. - Você deve envolver o texto da coluna principal (geralmente
d-table__cell --overview) com um link levando o administrador diretamente à página Mostrar/Editar correspondente à linha para acesso rápido.
- Se houver dois ou mais elementos interativos, a ação primária (por exemplo, “Editar”) deve ser um botão de texto, e todas as outras ações de linha, incluindo “Excluir”, devem ser agrupadas em uma lista suspensa
- Confirmação de exclusão: Todos os botões “Excluir” devem mostrar uma confirmação antes de executar a ação.
Conteúdo
- Cabeçalho: O cabeçalho da tabela é a linha superior que identifica as colunas abaixo. Ele fornece clareza, especialmente se os dados forem não descritivos ou ambíguos. Os cabeçalhos devem ser curtos, descritivos e relevantes, usando caixa de título. Evite cabeçalhos que sejam muito longos para o conteúdo nas linhas abaixo.
- Colunas: Ordene as colunas por prioridade ou de uma maneira que conte uma história coerente com os dados. dimensione as colunas de acordo com seu conteúdo, com colunas estreitas para conteúdo pequeno e colunas mais largas para parágrafos.
- Linhas: As linhas devem suportar texto, botões, links e ícones para aprimorar a apresentação de dados.
- Sem dados: Listas vazias devem usar o componente
AdminConfigAreaEmptyListcom um botão CTA e rótulo para orientar o usuário a criar novos registros
Implementação
Há uma pequena coleção de classes CSS que devem ser usadas com tabelas para fazê-las funcionar bem em dispositivos móveis e desktop.
Elementos <table> devem ter a classe d-table aplicada.
Elementos <thead> devem ter a classe d-table__header aplicada.
Elementos <tr> devem ter a classe d-table__row aplicada.
Elementos <td> contendo muito texto descritivo (geralmente a coluna mais à esquerda) devem usar as classes d-table__cell --overview. Todas as outras células devem usar d-table__cell --detail.
Elementos <td> com as classes d-table__cell --overview podem envolver o conteúdo interno da linha em um link levando o administrador diretamente à página Editar/Mostrar para a linha. Este link deve seguir esta estrutura e ter a classe CSS d-table__overview-link aplicada. Idealmente, o componente LinkTo deve ser usado, mas <a> também é aceitável, desde que getURL seja usado com ele.
A classe d-table__overview-name deve ser aplicada à parte do nome aqui, mas não à descrição.
<td class="d-table__cell --overview">
<LinkTo
class="d-table__overview-link"
@route="adminPlugins.show.explorer.details"
@model={{query.id}}
>
<strong class="query-name d-table__overview-name">{{query.name}}</strong>
{{#if query.is_default}}
<span class="query-badge">{{i18n
"explorer.default_query"
}}</span>
{{/if}}
<div class="query-desc">{{query.description}}</div>
</LinkTo>
</td>
<td class="d-table__cell --overview">
<a class="d-table__overview-name admin-flag-item__name d-table__overview-link" href={{this.editUrl}}>
{{@flag.name}}
</a>
</td>
Elementos <td> que envolvem os botões em cada linha devem ter as classes CSS d-table-cell --controls aplicadas. Isso garante que os botões estejam alinhados. Cada botão também deve ter a classe btn-small aplicada.
Para dispositivos móveis, cada elemento <td> exceto o d-table-cell --overview deve também incluir um <div> com a classe d-table__mobile-label, que contém um rótulo I18n que é o mesmo do <th> para essa coluna:
<td class="d-table__cell --detail">
<div class="d-table__mobile-label">
{{i18n "chat.incoming_webhooks.emoji"}}
</div>
{{replaceEmoji webhook.emoji}}
</td>
Isso exibe a linha da tabela em um formato baseado em cartões mais fácil de ler em dispositivos móveis:
Para menus suspensos [...], DMenu deve ser usado com DropdownMenu, aqui está um exemplo:
<DMenu
@identifier="backup-item-menu"
@title={{i18n "more_options"}}
@icon="ellipsis-vertical"
class="btn-small"
>
<:content>
<DropdownMenu as |dropdown|>
<dropdown.item>
<DButton ...[args do botão aqui] />
</dropdown.item>
<dropdown.item>
<DButton ...[args do botão aqui] />
</dropdown.item>
</DropdownMenu>
</:content>
</DMenu>
As alternâncias na linha da tabela são tratadas usando o componente DToggleSwitch:
<DToggleSwitch
@state={{this.enabled}}
class="admin-flag-item__toggle {{@flag.name_key}}"
{{on "click" (fn this.toggleFlagEnabled @flag)}}
/>
Juntando tudo, aqui está um exemplo mínimo de uma tabela de administração:
<table class="d-table">
<thead class="d-table__header">
<tr>
<th>Nome</th>
<th>Descrição</th>
<th></th>
</tr>
</thead>
<tbody>
<tr class="d-table__row">
<td class="d-table__cell --overview">
<LinkTo @route="admin.exampleRoute" class="d-table__overview-link">
<span class="d-table__overview-name">Item de Exemplo</span>
<span class="d-table__overview-about">Uma breve descrição</span>
</LinkTo>
</td>
<td class="d-table__cell --detail">
<span class="d-table__mobile-label">Descrição</span>
Algum conteúdo detalhado aqui
</td>
<td class="d-table__cell --controls">
<div class="d-table__cell-actions">
<button class="btn btn-default btn-small">Editar</button>
</div>
</td>
</tr>
</tbody>
</table>
5.e Rota de terceiro nível
Uma rota de terceiro nível é aquela que só pode ser acessada a partir de uma área de configuração. Estas geralmente vêm na forma de rotas de edição/nova como esta para bandeiras:
É aqui que os formulários usando FormKit serão colocados na maioria dos casos.
Use as rotas RESTful padrão para estas:
| Ação | Caminho |
|---|---|
| Novo | <recurso>/new |
| Editar | <recurso>/:id/edit |
e certifique-se de que as rotas também sejam roteadas no back-end. (Recarregar a página nova ou de edição não deve resultar em erro.)
Design
Uso
- Prefira ter essas rotas de terceiro nível em vez de ter formulários inline na rota principal ou dentro de uma tabela. Rotas de edição e nova independentes são as melhores, pois podem ser facilmente vinculadas.
- Não mostre a parte superior da UI da página (migalhas, cabeçalho da página e subcabeçalho)
- Em vez disso, mostre um único link “Voltar para X” que permita ao administrador chegar à área de configuração principal
- O conteúdo da página deve ser envolvido em pelo menos um
AdminConfigAreaCard - Quaisquer subtítulos na página devem ser feitos com cartões de área de configuração
Implementação
Há um simples componente BackButton que pode ser usado no topo da página para voltar:
<BackButton
@route="adminConfig.flags"
@label="admin.config_areas.flags.back"
/>
6. Páginas de configuração de configurações filtradas
Muitas de nossas páginas de configuração da interface de administração são listas simples de configurações do site filtradas. Isso permite que os administradores encontrem grupos relacionados de configurações sem serem sobrecarregados pela lista completa de “Todas as configurações do site”, até que criemos páginas de configuração mais especializadas como /admin/config/about/.
Implementação
Há algumas coisas que você precisa adicionar a uma dessas rotas. Primeiro, você pode exibir uma category inteira de configurações do site que são as chaves de nível superior em site_settings.yml (por exemplo, branding:), ou você pode usar uma area de configuração.
As configurações do site podem viver em várias areas, e você pode exibir uma ou mais na mesma página.
- Adicione uma rota ao mapa de rotas de administração abaixo de
adminConfig, por exemplo:
this.route("trustLevels", { path: "/trust-levels" }, function () {
this.route("settings", {
path: "/",
});
});
- Adicione um novo arquivo .js de rota, o arquivo corresponderá a um caminho como
frontend/discourse/admin/routes/admin-config/localization.jsdependendo do nome da sua nova rota. Isso deve herdar deAdminConfigWithSettingsRoutee incluir umtitleToken().
import { i18n } from "discourse-i18n";
import AdminConfigWithSettingsRoute from "../admin-config-with-settings-route";
export default class AdminConfigLocalizationRoute extends AdminConfigWithSettingsRoute {
titleToken() {
return i18n("admin.config.localization.title");
}
}
- Adicione um controlador, isso é principalmente para habilitar a pesquisa e filtragem de configurações. Deve herdar de
AdminAreaSettingsBaseController:
import AdminAreaSettingsBaseController from "discourse/admin/controllers/admin-area-settings-base";
export default class AdminConfigLocalizationSettingsController extends AdminAreaSettingsBaseController {}
- Finalmente, adicione um arquivo de modelo de rota no formato
.gjs, em um caminho comofrontend/discourse/admin/templates/admin-config/localization/settings.gjs. Isso deve conter oDPageHeadere migalhas normais, mas para exibir as configurações você precisa deAdminAreaSettings.
<div class="admin-config-page__main-area">
<AdminAreaSettings
@showBreadcrumb={{false}}
@area="localization"
@path="/admin/config/localization"
@filter={{@controller.filter}}
@adminSettingsFilterChangedCallback={{@controller.adminSettingsFilterChangedCallback}}
/>
</div>
As coisas importantes a mudar aqui são o @path e @area (ou alternativamente use @categories). Como mencionado anteriormente, preencha isso com a área de configuração do site que você deseja exibir, ou as categorias.
7. Orientação geral
-
Os slugs de URL devem usar hífens (
-) para indicar espaços em palavras, em vez de underscores (_). -
Todo o texto nas interfaces de administração deve seguir as diretrizes de formatação de texto descritas aqui:
8. Plugins
Alguns plugins precisam de uma UI de configuração aprofundada para seu plugin (por exemplo, AI, Automação, Gamificação) em vez de apenas ter uma coleção de configurações do site. Por exemplo, aqui está o Discourse AI:
Alguns exemplos de plugins usando isso são:
- Discourse AI GitHub - discourse/discourse-ai: Discourse AI now lives in the discourse/discourse repo · GitHub
- Discourse Gamification GitHub - discourse/discourse-gamification · GitHub
- Discourse Chat (núcleo)
Design
Uso
- As diretrizes gerais da UI de administração devem ser seguidas ao criar UIs de plugin independentes.
Implementação
Roteamento Ember
- Todos os modelos de rota estarão sob
admin/assets/javascripts/discourse/templates/admin-plugins/show/ - Todos os arquivos js de rota estarão sob
admin/assets/javascripts/discourse/routes/e
prefixados comadmin-plugins-show- - O mapa de rotas de administração deve estar em um arquivo como
admin-NOME-DO-PLUGIN-plugin-route-map.js - O mapa de rotas deve ter uma estrutura como esta. A parte importante é que
usamosadmin.adminPlugins.showcomoresource.
export default {
resource: "admin.adminPlugins.show",
path: "/plugins",
map() {
this.route("discourse-ai-personas", { path: "ai-personas" }, function () {
this.route("new");
this.route("show", { path: "/:id" });
});
},
};
- O exemplo atual de como tudo isso funciona é visto no plugin Discourse AI, se você for para
/admin/plugins/discourse-ai/ai-personas - Se você tiver apenas uma rota de “nível superior”, por exemplo, uma que não define sub-rotas, então o caminho do modelo será algo como
admin/assets/javascripts/discourse/templates/admin-plugins/show/seu-nome-de-rota.gjs. Se houver sub-rotas, então você entra no território de precisar de modelosindex.gjs,show.gjsenew.gjse assim por diante.
Navegação
Os plugins podem mostrar sua navegação em uma barra lateral interna, ou na barra de navegação por abas no topo. Esta última é altamente recomendada, e no futuro o suporte à barra lateral interna pode ser descartado.
- Quaisquer links que serão exibidos na barra superior ou na barra lateral interna para
a página de exibição do plugin devem ser definidos em um inicializador (por exemplo,
assets/javascripts/initializers/admin-plugin-configuration-nav.js) usando
api.addAdminPluginConfigurationNav. Os links precisam de umlabel,routeedescription(que é usado para pesquisa de administração) - Este inicializador deve ser executado apenas se o usuário for administrador.
- O link de configurações do site para o plugin é gerado automaticamente, não é necessário incluí-lo aqui.
- Um exemplo pode ser visto aqui discourse-ai/assets/javascripts/initializers/admin-plugin-configuration-nav.js at ab4544d8977ec0e9d6aa42b4551df8317aa9b365 · discourse/discourse-ai · GitHub .
Lado do Servidor
add_admin_routeainda é usado para mostrar as rotas de administração personalizadas na barra lateral de administração e do índice /plugins com as abas ao longo do topo. Basicamente, isso define a página raiz da UI do seu plugin.use_new_show_route: truedeve ser passado como um argumento adicional aqui para que a nova página de exibição do plugin seja usada.
Convenções de UI
- Cada rota de índice para o plugin deve exibir um componente
DPageSubheaderpara descrever a intenção dessa rota e adicionar quaisquer botões de ação relacionados. - Botões de ação que precisam ser renderizados no cabeçalho principal da página do plugin devem usar o outlet
admin-plugin-config-page-actionscom um componente dedicado. O melhor lugar para fazer isso é no mesmo inicializador ondeaddAdminPluginConfigurationNavé usado.plugineactionssão passados comooutletArgs.pluginé a representação do modelo do plugin atual, então o nome do plugin e outras coisas podem ser acessados,actionssão os componentes de botão de ação renderizados deDPageHeader.
api.renderInOutlet(
"admin-plugin-config-page-actions",
ChatAdminPluginActions
);
Tópicos relacionados:















