Creare interfacce admin coerenti

Queste linee guida mirano a creare un’interfaccia di amministrazione coerente, concentrandosi su usabilità, accessibilità e un layout strutturato. Consulta l’indice per vedere cosa è incluso e per navigare facilmente verso ciascuna sezione.

Nota: La terminologia utilizzata qui è definita nel glossario dell’interfaccia di amministrazione.

0. Prefazione - Struttura della pagina di configurazione e collegamenti della barra laterale

Quando si aggiungono nuove pagine di configurazione nell’interfaccia di amministrazione, ogni pagina avrà bisogno di un collegamento per la barra laterale, e ogni pagina avrà bisogno sia di un titolo che di una descrizione dell’intestazione. Questo per garantire coerenza ovunque, e affinché i futuri miglioramenti alla ricerca di amministrazione possano visualizzare l’intero layout dell’interfaccia di amministrazione.

In generale, la struttura dell’interfaccia di amministrazione è la seguente:

  • Interfaccia di amministrazione
    • Pagina di configurazione (visualizzata nella barra laterale)
      • Scheda Impostazioni
      • Eventuali altre schede di terzo livello facoltative
        • Pagina di modifica/nuovo di terzo livello per le risorse

In futuro, una “panoramica della sezione” verrà inserita tra l’interfaccia radice e le pagine di configurazione.

Collegamenti della barra laterale

Tutte le pagine di amministrazione devono essere aggiunte alla ADMIN_NAV_MAP in discourse/frontend/discourse/app/lib/sidebar/admin-nav-map.js at main · discourse/discourse · GitHub . Ogni elemento deve avere almeno queste chiavi:

  • name - Un identificatore univoco per il collegamento, dovrebbe essere in snake_case
  • route OPPURE href - La route è un identificatore di rotta Ember, come adminUsers. Per gli amministratori, queste sono definite nella mappa delle rotte di amministrazione . È possibile utilizzare un href invece, ma route è preferibile.
  • label OPPURE text - Label è una chiave I18n, che dovrebbe generalmente essere admin.config.page_name.title (vedere la sezione traduzioni di seguito). Se viene utilizzato text, sarà già testo tradotto.

Possono essere fornite anche queste chiavi facoltative:

  • description - Si raccomanda di fornirla anche questa. È una chiave I18n, dovrebbe generalmente essere admin.config.page_name.header_description.
  • icon - Anche raccomandato, viene visualizzato accanto al collegamento nella barra laterale.
  • routeModels - Matrice di dati URL per il caso di parametri di rotta. Ad esempio adminCustomizeThemes ha un parametro di rotta :type, quindi puoi passare routeModels: ["components"]. Gli elementi della matrice sono utilizzati nello stesso ordine in cui appaiono i parametri di rotta.
  • moderator: Imposta questo su true se i moderatori dovrebbero vedere questa pagina nella barra laterale.
  • keywords: Una chiave I18n, con una lista di parole chiave separate da | per il collegamento della barra laterale, utilizzata per ulteriore “peso nella ricerca” durante il filtraggio/ricerca delle pagine.
  • links: Una lista di rotte di 3° livello che sono sotto la pagina nella barra laterale. Questi non vengono visualizzati nella barra laterale stessa. Questo verrà utilizzato per future funzionalità di ricerca di amministrazione.
  • settings_area e settings_category: Se la pagina mostra solo un elenco di impostazioni del sito filtrate, allora una di queste dovrebbe essere compilata. Se l’impostazione del sito ha un’area definita, che è utilizzata in AdminAreaSettings, allora dovrebbe essere utilizzata settings_area. Se un’intera categoria di impostazioni è visualizzata nella pagina, e anche utilizzata in AdminAreaSettings, allora dovrebbe essere utilizzata settings_category.
  • multi_tabbed: Se la pagina ha una scheda impostazioni e altre schede, allora questo dovrebbe essere impostato su true. Aiuta a generare collegamenti per il sistema di ricerca di amministrazione.

Traduzioni

Il titolo e la descrizione dell’intestazione per ogni pagina di configurazione dovrebbero essere sotto:

  • admin
    • config
      • page_name
        • title: “Titolo della pagina”
        • header_description: “Questa pagina è per xyz”

Puoi vedere esempi di questo qui:

1. Breadcrumb

I breadcrumb fungono da strumento di navigazione, aiutando gli utenti a comprendere la loro posizione attuale, la struttura dei contenuti e la gerarchia all’interno dell’interfaccia di amministrazione.

Amministrazione > Breadcrumb > Percorso
Titolo della pagina

:art: Design

Struttura

  1. Amministrazione: prefisso fisso che appare all’inizio di ogni percorso breadcrumb, collegato a /admin
  2. Collegamento: apre la pagina nella stessa finestra
  3. Separatore: un’icona angle-right separa ogni collegamento

Utilizzo

Quando usarli:

  • Presenti su ogni pagina di amministrazione
  • Situati sopra i contenuti (titolo, descrizione, schede)
  • Mostrano la pagina attualmente selezionata

Quando non usarli:

  • Quando si visita una nuova rotta o di modifica

Contenuto

  • Ogni elemento include un collegamento alla sua pagina correlata
  • Mostra la pagina attualmente selezionata

Accessibilità

  • Un elemento nav con aria-label="Breadcrumb" avvolge un elenco ordinato per fornire un punto di riferimento di navigazione
  • Applicare aria-current="page" sull’ultimo collegamento per indicare che è la pagina corrente
  • Per maggiori dettagli, vedere Esempio Breadcrumb delle Pratiche di Autore WAI-ARIA

:hammer_and_wrench: Implementazione

Il componente DBreadcrumbsContainer deve essere posizionato da qualche parte nella pagina:

<DBreadcrumbsContainer />

Quindi, ogni elemento DBreadcrumbsItem aggiunto a qualsiasi componente su una rotta o una rotta figlia verrà renderizzato in questo contenitore. Ogni DBreadcrumbsItem ha un @label e un @path che devono essere forniti:

<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}}
/>

Come appare questo con un esempio visivo, utilizzando il plugin Discourse AI:

2. Intestazione pagina e titolo

La sezione superiore di una pagina di amministrazione, contenente il titolo della pagina, insieme ad azioni e descrizione facoltative.

:art: Design

Struttura

  • Titolo della pagina: Titolo della pagina

  • Descrizione della pagina: Introduzione o descrizione di ciò che i contenuti coprono (facoltativo)

  • Azione primaria: Azione primaria del titolo della pagina (facoltativo)

  • Azione secondaria: Impostazioni del pulsante azione secondaria del titolo della pagina (facoltativo)

Utilizzo e contenuto

  • Titolo della pagina: Utilizzare il livello di intestazione 1 per spiegare l’argomento principale della pagina in maiuscola iniziale. Di solito la traduzione I18n dovrebbe essere sotto admin.config.your_page.title.

  • Descrizione della pagina: Supporta nodi markdown di base come _corsivo_, **grassetto**, e [nome collegamento](url)

  • Azione primaria: Utilizzare btn-primary. Non includere un’icona. Di solito la traduzione I18n dovrebbe essere sotto admin.config.your_page.header_description.

  • Azione secondaria: Utilizzare le impostazioni del pulsante btn-default, visibili solo se esiste un’azione primaria. Non includere un’icona.

    :point_right: Sii chiaro con i pulsanti di azione. Ad esempio, usa etichette descrittive come “Aggiungi emoji” invece di solo “Aggiungi” per ridurre l’ambiguità.

:hammer_and_wrench: Implementazione

Qui viene utilizzato il componente DPageHeader. Questo accetta argomenti per @titleLabel, @descriptionLabel, @learnMoreUrl e @shouldDisplay. Utilizza yields nominati in Ember per fornire 5 blocchi nominati per il contenuto:

  1. breadcrumbs - Eventuali componenti aggiuntivi DBreadcrumbsItem per la pagina dovrebbero essere posizionati qui.
  2. actions - Utilizzato per definire i pulsanti a destra del titolo. Questo rende un oggetto chiamato actions che può essere utilizzato per renderizzare pulsanti Default, Primary, Danger e Wrapped.
  3. title - Un’alternativa a @titleLabel, consentendo markup personalizzato all’interno dell’intestazione.
  4. drawer - Una sezione cassetto opzionale collassabile, mostrata quando @showDrawer è true.
  5. tabs - Utilizzato per definire le schede per la pagina utilizzando i componenti NavItem. @hideTabs può essere utilizzato per rimuovere questa parte dell’intestazione se non è necessaria.

Un esempio completo è di seguito:

<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>

I titoli delle pagine per la scheda del browser sono gestiti nelle rotte Ember utilizzando la funzionalità titleToken. Ogni volta che questo viene utilizzato in una rotta aggiunge il token alla fine del titolo della scheda del browser. Tieni presente che devi utilizzare la classe DiscourseRoute per estendere la tua rotta, non la normale Route di ember per far funzionare questo:

titleToken() {
  return i18n("admin.config.backups.title");
}

:point_right: L’intestazione della pagina è nascosta automaticamente per i percorsi /new e /edit per supportare le Rotte di terzo livello. Può essere sovrascritta utilizzando l’argomento @shouldDisplay.

3. Schede

Una navigazione facoltativa che fornisce accesso a livelli più profondi di impostazioni o funzionalità. Ci riferiamo anche a questo come pagine o navigazione di “terzo livello”.

:art: Design

Utilizziamo le schede per passare tra diverse ma correlate visualizzazioni all’interno dello stesso contesto.

Utilizzo

  • Non utilizzato per la navigazione primaria
  • Solo uno attivo alla volta

:hammer_and_wrench: Implementazione

Vedi i dettagli dell’Intestazione Pagina, le schede sono definite nel componente DPageHeader.

:white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square: :white_small_square:

4. Pagina di panoramica/atterraggio della sezione

Consente agli utenti di visualizzare i contenuti di una sezione, specialmente quando la barra laterale è collassata o su mobile.

:art: Design

Struttura
Utilizza un layout a tre colonne uguali utilizzando un sistema a griglia. Su schermi piccoli, queste colonne si impileranno verticalmente.

Design e utilizzo

  • Può essere accessibile tramite breadcrumb (Amministrazione > Comunità > Panoramica)
  • Ogni sezione dovrebbe averne una, tranne per i plugin (che mostrano quelli installati) e i report (solo una pagina)
  • L’elemento ha:
    • nome - uguale al collegamento della sezione
    • descrizione - una breve descrizione di cui tratta la pagina
    • icona - stessa icona utilizzata per la barra laterale

:hammer_and_wrench: Implementazione

Snippet di codice o collegamento a un argomento/GitHub

5. Contenuto della pagina

L’area principale di una pagina di amministrazione dove vengono visualizzati e interagiti impostazioni, configurazioni e altri contenuti.

:art: Design

Struttura
Utilizza un layout 2/3 + 1/3 utilizzando un sistema a griglia. La sezione primaria occupa due terzi e la sezione secondaria occupa un terzo dello spazio. Su schermi piccoli, queste colonne si impileranno verticalmente.

  • Area di configurazione: Una sezione specifica all’interno del contenuto della pagina dedicata a impostazioni e configurazioni.
  • Aiuto/riferimento/inserito: Un’area all’interno del contenuto della pagina che fornisce guide, documentazione o informazioni contestuali aggiuntive. (facoltativo)

Design e utilizzo

  • Raggruppa impostazioni e azioni simili insieme in schede
  • Struttura i layout primari/secondari in modo che la sezione primaria (2/3) sia utilizzata per le impostazioni principali, e la sezione secondaria (1/3) sia per informazioni aggiuntive o contesto utile
  • Se la sezione secondaria non è disponibile, mantieni la stessa larghezza della sezione primaria

Contenuto

:hammer_and_wrench: Implementazione

Snippet di codice o collegamenti GitHub

5.a. Sottotitolo

Un sottotitolo è un’intestazione secondaria utilizzata per suddividere i contenuti sotto una sezione, di solito sotto le schede.

Struttura

  • Sottotitolo: Sottotitolo di ciò che i contenuti coprono (facoltativo)
  • Azione primaria: Azione primaria del sottotitolo (facoltativo)
  • Azione secondaria: Impostazioni del pulsante azione secondaria del sottotitolo (facoltativo)

Utilizzo e contenuto

  • Sottotitolo: Utilizzare il livello di intestazione 2 per spiegare l’argomento principale dei contenuti correlati. Includi solo se:

    • C’è un pulsante di azione primaria, o
    • C’è una descrizione che spiega la sezione.
  • Azione primaria: Utilizzare btn-primary. Non includere un’icona.

  • Azione secondaria: Utilizzare le impostazioni del pulsante btn-default, visibili solo se esiste un’azione primaria. Non includere un’icona.

    :point_right: Sii chiaro con i pulsanti di azione. Ad esempio, usa etichette descrittive come “Aggiungi emoji” invece di solo “Aggiungi” per ridurre l’ambiguità.

:hammer_and_wrench: Implementazione

Questo è simile a DPageHeader, c’è un componente DPageSubheader. La differenza principale è che c’è solo un singolo yield nominato per actions.

  1. actions - Utilizzato per definire i pulsanti a destra del titolo. Questo rende un oggetto chiamato actions che può essere utilizzato per renderizzare pulsanti Default, Primary, Danger e Wrapped.
<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. Area di configurazione

L’area di configurazione è composta da schede o sezioni. Le schede sono ottime per raggruppare informazioni e attività correlate, aiutando gli utenti a scansionare e prioritizzare i contenuti più facilmente.

:art: Design

Scheda

Le schede sono impostate con un raggio di bordo di 2px e utilizzano uno sfondo di --secondary. Hanno anche un bordo solido di 1px con --primary-low e un padding di 20px intorno al contenuto.

Variazione predefinita

Variazione accordion

Design e utilizzo

  • Raggruppa informazioni correlate
  • Visualizza le informazioni in modo che amministratori e moderatori vedano prima le cose più importanti
  • Utilizza intestazioni che spiegano chiaramente a cosa serve la scheda
  • Suddividi quelle complicate in più sezioni, se necessario

variazione predefinita

  • Limitati a una sola chiamata all’azione primaria per scheda
  • Posiziona la chiamata all’azione primaria in fondo alla scheda per i prossimi passaggi

variazione accordion

  • Utilizza l’angolo in alto a destra della scheda per azioni facoltative come “Visualizza tutto”

Contenuto

  • Tutti i moduli dovrebbero utilizzare i componenti ember FormKit nel core descritti nella documentazione

  • Le intestazioni delle schede dovrebbero essere in maiuscola iniziale

    :white_check_mark: Fai :cross_mark: Non fare
    Impostazioni generali Impostazioni Generali
    Informazioni di contatto INFORMAZIONI DI CONTATTO

:hammer_and_wrench: Implementazione

Abbiamo un componente AdminConfigAreaCard che dovrebbe essere utilizzato per tutte queste schede. Per ora questo ha solo argomenti @translatedHeading e @heading, in futuro possiamo aggiungere azioni e renderle collassabili e così via:

<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>

Impostazioni del sito incorporate

Questa sezione è in fase di sviluppo.

5.c. Inserito di aiuto

Questa sezione fornisce ulteriori linee guida, documentazione o contesto all’interno del contenuto della pagina.

v1

:art: Design

Design e utilizzo

  • Mostra documentazione o guide correlate sui contenuti della pagina per fornire informazioni utili
  • Includi un’icona nell’intestazione per renderla facilmente riconoscibile
  • Posiziona questa sezione nell’area di layout secondaria (1/3)

Contenuto

  • Le intestazioni dovrebbero essere in maiuscola iniziale

:hammer_and_wrench: Implementazione

Snippet di codice o collegamento a un argomento/GitHub

5.d. Tabella

Le tabelle visualizzano le informazioni in una griglia di celle, colonne e righe, rendendo facile per gli amministratori scansionare rapidamente gli elementi e intraprendere azioni.

:art: Design

Utilizzo

  • Utilizza le tabelle per visualizzare contenuti strutturati dove ogni voce condivide gli stessi attributi.
  • Consenti agli amministratori di rivedere, abilitare/disabilitare, modificare ed eliminare set di dati.
  • Adatto per set di dati che continueranno a crescere nel tempo.

Design

  • Utilizza linee orizzontali tra le righe per separare visivamente i contenuti, inclusa l’ultima riga. Evita di utilizzare bordi o cornici intorno alla tabella per evitare che assomigli a una rete.
  • Non applicare linee verticali tra le colonne. Le tabelle senza linee verticali sono generalmente più facili da scansionare e leggere.

Azioni aggiuntive

  • Azioni riga: Includi azioni aggiuntive nella colonna più a destra di ogni riga della tabella.
    • Se ci sono due o più elementi interattivi, l’azione primaria (ad esempio, “Modifica”) dovrebbe essere un pulsante di testo, e tutte le altre azioni di riga incluse “Elimina” dovrebbero essere raggruppate in un menu a discesa [...]. Le icone nei menu a discesa sono incoraggiate per suddividere visivamente le cose.
    • Se c’è solo un’azione “Elimina” e nessuna azione primaria, utilizza un pulsante di testo “Elimina” inline stilizzato come btn-default.
    • Dovresti avvolgere il testo della colonna principale (generalmente d-table__cell --overview) con un collegamento che porta l’amministratore direttamente alla pagina Mostra/Modifica corrispondente alla riga per un accesso rapido.
  • Conferma eliminazione: Tutti i pulsanti “Elimina” dovrebbero mostrare una conferma prima di eseguire l’azione.

Contenuto

  • Intestazione: L’intestazione della tabella è la riga superiore che identifica le colonne sottostanti. Fornisce chiarezza, specialmente se i dati sono non descrittivi o ambigui. Le intestazioni dovrebbero essere brevi, descrittive e pertinenti, utilizzando la maiuscola iniziale. Evita intestazioni troppo lunghe per i contenuti nelle righe sottostanti.
  • Colonne: Ordina le colonne per priorità o in un modo che racconti una storia coerente con i dati. Dimensiona le colonne in base ai loro contenuti, con colonne strette per contenuti piccoli e colonne più ampie per paragrafi.
  • Righe: Le righe dovrebbero supportare testo, pulsanti, collegamenti e icone per migliorare la presentazione dei dati.
  • Nessun dato: Gli elenchi vuoti dovrebbero utilizzare il componente AdminConfigAreaEmptyList con un pulsante CTA e un’etichetta per guidare l’utente verso la creazione di nuovi record

:hammer_and_wrench: Implementazione

C’è una piccola raccolta di classi CSS che devono essere utilizzate con le tabelle per farle funzionare bene su mobile e desktop.

Gli elementi <table> dovrebbero avere applicata la classe d-table.

Gli elementi <thead> dovrebbero avere applicata la classe d-table__header.

Gli elementi <tr> dovrebbero avere applicata la classe d-table__row.

Gli elementi <td> contenenti molto testo descrittivo (solitamente la colonna più a sinistra) dovrebbero utilizzare le classi d-table__cell --overview. Tutte le altre celle dovrebbero utilizzare d-table__cell --detail.

Gli elementi <td> con le classi d-table__cell --overview possono avvolgere il contenuto interno della riga in un collegamento che porta l’amministratore direttamente alla pagina Modifica/Mostra per la riga. Questo collegamento dovrebbe seguire questa struttura e avere applicata la classe CSS d-table__overview-link. Idealmente dovrebbe essere utilizzato il componente LinkTo ma <a> va bene purché sia utilizzato con getURL.

La classe d-table__overview-name dovrebbe essere applicata alla parte del nome qui, ma non alla descrizione.

<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>

Gli elementi <td> che avvolgono i pulsanti su ogni riga dovrebbero avere applicate le classi CSS d-table-cell --controls. Questo garantisce che i pulsanti siano allineati. Ogni pulsante dovrebbe avere anche applicata la classe btn-small.

Per mobile, ogni elemento <td> tranne il d-table-cell --overview dovrebbe includere anche un <div> con la classe d-table__mobile-label, che contiene un’etichetta I18n che è la stessa di quella nel <th> per quella colonna:

<td class="d-table__cell --detail">
  <div class="d-table__mobile-label">
    {{i18n "chat.incoming_webhooks.emoji"}}
  </div>
  {{replaceEmoji webhook.emoji}}
</td>

Questo visualizza la riga della tabella in un formato basato su schede più facile da leggere su mobile:

Per i menu a discesa [...], dovrebbe essere utilizzato DMenu con DropdownMenu, ecco un esempio:

<DMenu
  @identifier="backup-item-menu"
  @title={{i18n "more_options"}}
  @icon="ellipsis-vertical"
  class="btn-small"
>
  <:content>
    <DropdownMenu as |dropdown|>
      <dropdown.item>
        <DButton ...[argomenti pulsante qui] />
      </dropdown.item>
      <dropdown.item>
        <DButton ...[argomenti pulsante qui] />
      </dropdown.item>
    </DropdownMenu>
  </:content>
</DMenu>

I toggle nella riga della tabella sono gestiti utilizzando il componente DToggleSwitch:

<DToggleSwitch
  @state={{this.enabled}}
  class="admin-flag-item__toggle {{@flag.name_key}}"
  {{on "click" (fn this.toggleFlagEnabled @flag)}}
/>

Mettendo tutto insieme, ecco un esempio minimo di una tabella di amministrazione:

 <table class="d-table">
    <thead class="d-table__header">
      <tr>
        <th>Nome</th>
        <th>Descrizione</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">Elemento Esempio</span>
            <span class="d-table__overview-about">Una breve descrizione</span>
          </LinkTo>
        </td>
        <td class="d-table__cell --detail">
          <span class="d-table__mobile-label">Descrizione</span>
          Qualche contenuto dettagliato qui
        </td>
        <td class="d-table__cell --controls">
          <div class="d-table__cell-actions">
            <button class="btn btn-default btn-small">Modifica</button>
          </div>
        </td>
      </tr>
    </tbody>
  </table>

5.e Rotta di terzo livello

Una rotta di terzo livello è una che può essere raggiunta solo da un’area di configurazione. Queste di solito assumono la forma di rotte di modifica/nuovo come questa per i flag:

È qui che verranno posizionati i moduli utilizzando FormKit nella maggior parte dei casi.

Utilizza le rotte RESTful standard per queste:

Azione Percorso
Nuovo <risorsa>/new
Modifica <risorsa>/:id/edit

e assicurati che le rotte siano anche instradate nel back-end. (Ricaricare la pagina nuova- o modifica non dovrebbe risultare in un errore.)

:art: Design

Utilizzo

  • Preferisci avere queste rotte di terzo livello rispetto ad avere moduli inline sulla rotta principale o all’interno di una tabella. Le rotte di modifica e nuove autonome sono le migliori, poiché possono essere facilmente collegate.
  • Non mostrare la parte superiore dell’interfaccia utente della pagina (breadcrumb, intestazione pagina e sottotitolo)
  • Invece, mostra un singolo collegamento “Torna a X” che permette all’amministratore di raggiungere l’area di configurazione principale
  • Il contenuto della pagina dovrebbe essere avvolto in almeno una AdminConfigAreaCard
  • Qualsiasi sottotitolo nella pagina dovrebbe essere fatto con schede di area di configurazione

:hammer_and_wrench: Implementazione

C’è un semplice componente BackButton che può essere utilizzato in cima alla pagina per tornare indietro:

<BackButton
  @route="adminConfig.flags"
  @label="admin.config_areas.flags.back"
/>

6. Pagine di configurazione impostazioni filtrate

Molte delle nostre pagine di configurazione dell’interfaccia di amministrazione sono semplici elenchi di impostazioni del sito filtrate. Questo permette agli amministratori di trovare gruppi correlati di impostazioni senza essere sopraffatti dall’elenco completo di “Tutte le impostazioni del sito”, finché non creiamo pagine di configurazione più specializzate come /admin/config/about/.

:hammer_and_wrench: Implementazione

Ci sono alcune cose che devi aggiungere per una di queste rotte. Prima, puoi mostrare un’intera category di impostazioni del sito che sono le chiavi di primo livello in site_settings.yml (ad esempio branding:), oppure puoi utilizzare un’area di impostazione.

Le impostazioni del sito possono vivere in più areas, e puoi visualizzarne una o più sulla stessa pagina.

  1. Aggiungi una rotta alla mappa delle rotte di amministrazione sotto adminConfig, ad esempio:
this.route("trustLevels", { path: "/trust-levels" }, function () {
  this.route("settings", {
    path: "/",
  });
});
  1. Aggiungi un nuovo file .js di rotta, il file corrisponderà a un percorso come frontend/discourse/admin/routes/admin-config/localization.js a seconda del nome della tua nuova rotta. Questo dovrebbe ereditare da AdminConfigWithSettingsRoute e includere un titleToken().
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");
  }
}
  1. Aggiungi un controller, questo è principalmente per abilitare la ricerca e il filtraggio delle impostazioni. Deve ereditare da AdminAreaSettingsBaseController:
import AdminAreaSettingsBaseController from "discourse/admin/controllers/admin-area-settings-base";

export default class AdminConfigLocalizationSettingsController extends AdminAreaSettingsBaseController {}
  1. Infine, aggiungi un file di modello di rotta in formato .gjs, a un percorso come frontend/discourse/admin/templates/admin-config/localization/settings.gjs. Questo dovrebbe contenere il normale DPageHeader e i breadcrumb, ma per visualizzare le impostazioni hai bisogno di AdminAreaSettings.
<div class="admin-config-page__main-area">
  <AdminAreaSettings
    @showBreadcrumb={{false}}
    @area="localization"
    @path="/admin/config/localization"
    @filter={{@controller.filter}}
    @adminSettingsFilterChangedCallback={{@controller.adminSettingsFilterChangedCallback}}
  />
</div>

Le cose importanti da cambiare qui sono @path e @area (o in alternativa utilizzare @categories). Come menzionato in precedenza, compila questo con l’area di impostazione del sito che vuoi visualizzare, o le categorie.

7. Linee guida generali

  • Gli slug URL devono utilizzare trattini (-) per indicare gli spazi nelle parole, piuttosto che underscore (_).

  • Tutto il testo nelle interfacce di amministrazione dovrebbe seguire le linee guida di formattazione del testo delineate qui:

8. Plugin

Alcuni plugin hanno bisogno di un’interfaccia utente di configurazione approfondita per il loro plugin (ad esempio AI, Automazione, Gamification) piuttosto che avere solo una raccolta di impostazioni del sito. Ad esempio, ecco Discourse AI:

Alcuni esempi di plugin che utilizzano questo sono:

:art: Design

Utilizzo

  • Le linee guida generali dell’interfaccia utente di amministrazione dovrebbero essere seguite quando si creano interfacce utente indipendenti per i plugin.

:hammer_and_wrench: Implementazione

Instradamento Ember

  • Tutti i modelli di rotta saranno sotto
    admin/assets/javascripts/discourse/templates/admin-plugins/show/
  • Tutti i file js di rotta saranno sotto admin/assets/javascripts/discourse/routes/ e
    prefissati con admin-plugins-show-
  • La mappa delle rotte di amministrazione dovrebbe essere in un file come admin-PLUGIN-NAME-plugin-route-map.js
  • La mappa delle rotte dovrebbe avere una struttura come questa. La parte importante è che
    utilizziamo admin.adminPlugins.show come resource.
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" });
    });
  },
};
  • L’esempio attuale di come funziona tutto questo si vede nel plugin Discourse AI, se vai a /admin/plugins/discourse-ai/ai-personas
  • Se hai solo una rotta “di primo livello”, ad esempio una che non definisce sotto-rotte, allora il percorso del modello sarà qualcosa come admin/assets/javascripts/discourse/templates/admin-plugins/show/your-route-name.gjs. Se ci sono sotto-rotte allora entri nel territorio di aver bisogno di modelli index.gjs, show.gjs e new.gjs e così via.

Navigazione

I plugin possono mostrare la loro navigazione in una barra laterale interna, o sulla barra di navigazione a schede in alto. Quest’ultimo è altamente raccomandato, e in futuro il supporto per la barra laterale interna potrebbe essere rimosso.

  • Tutti i collegamenti che verranno mostrati nella barra superiore o nella barra laterale interna per
    la pagina di visualizzazione del plugin dovrebbero essere definiti in un initializer (ad esempio
    assets/javascripts/initializers/admin-plugin-configuration-nav.js) utilizzando
    api.addAdminPluginConfigurationNav . I collegamenti hanno bisogno di un label, route e description (che è utilizzato per la ricerca di amministrazione)
  • Questo initializer dovrebbe eseguirsi solo se l’utente è amministratore.
  • Il collegamento alle impostazioni del sito per il plugin è generato automaticamente, non c’è bisogno di includerlo qui.
  • Un esempio può essere visto qui discourse-ai/assets/javascripts/initializers/admin-plugin-configuration-nav.js at ab4544d8977ec0e9d6aa42b4551df8317aa9b365 · discourse/discourse-ai · GitHub .

Server-Side

  • add_admin_route è ancora utilizzato per mostrare le rotte di amministrazione personalizzate nella barra laterale di amministrazione e dall’indice /plugins con le schede in alto. Fondamentalmente, questo definisce la pagina radice della tua interfaccia utente del plugin.
    • use_new_show_route: true dovrebbe essere passato come argomento aggiuntivo qui in modo che venga utilizzata la nuova pagina di visualizzazione del plugin.

Convenzioni UI

  • Ogni rotta indice per il plugin dovrebbe mostrare un componente DPageSubheader per descrivere l’intento di quella rotta e per aggiungere eventuali pulsanti di azione correlati.
  • I pulsanti di azione che devono essere renderizzati nell’intestazione principale della pagina del plugin devono utilizzare l’outlet admin-plugin-config-page-actions con un componente dedicato. Il posto migliore per farlo è nello stesso initializer dove viene utilizzato addAdminPluginConfigurationNav.
    • plugin e actions sono passati come outletArgs. plugin è la rappresentazione del modello del plugin corrente in modo che il nome del plugin e altre cose possano essere accessibili, actions sono i componenti dei pulsanti di azione resi da DPageHeader.
api.renderInOutlet(
  "admin-plugin-config-page-actions",
  ChatAdminPluginActions
);

Argomenti correlati:

10 Mi Piace

E

ancora non funzionano. Penso che il secondo sia -23 invece di -24

5 Mi Piace

Sono così felice di vedere questo finalmente su meta. Mesi di lavoro sono stati dedicati a questo e lo useremo per standardizzare l’interfaccia utente e la navigazione di ogni pagina nell’interfaccia di amministrazione.

Dovremmo forse rimuovere quella tabella dei contenuti e fare affidamento su discotoc invece? Penso che sarebbe meno fragile, anche se mi piace vedere la tabella dei contenuti in cima al post.

7 Mi Piace

Grazie @Moin, tutto risolto!

Ho apportato questa modifica, altrimenti si tratta semplicemente di una tabella dei contenuti duplicata.

4 Mi Piace

Un post è stato diviso in un nuovo argomento: Mostra il nome utente nella scheda del browser quando sei nell’amministrazione utente