Erstellen konsistenter Admin-Oberflächen

Diese Richtlinien zielen darauf ab, eine kohärente Admin-Oberfläche zu schaffen, mit Fokus auf Benutzerfreundlichkeit, Barrierefreiheit und ein strukturiertes Layout. Sehen Sie sich das Inhaltsverzeichnis an, um zu sehen, was enthalten ist, und navigieren Sie einfach zu jedem Abschnitt.

Hinweis: Die hier verwendete Terminologie ist im Glossar der Admin-Oberfläche definiert.

0. Vorwort – Struktur der Konfigurationsseite und Sidebar-Links

Wenn neue Konfigurationsseiten in der Admin-Oberfläche hinzugefügt werden, benötigt jede Seite einen Link für die Sidebar, und jede Seite benötigt sowohl einen Titel als auch eine Header-Beschreibung. Dies gewährleistet Konsistenz überall und ermöglicht es zukünftigen Verbesserungen der Admin-Suche, das gesamte Layout der Admin-Oberfläche anzuzeigen.

Im Allgemeinen sieht die Struktur der Admin-Oberfläche wie folgt aus:

  • Admin-Oberfläche
    • Konfigurationsseite (in der Sidebar angezeigt)
      • Einstellungen-Tab
      • Optional weitere Tabs der dritten Ebene
        • Bearbeiten/Neue Seite der dritten Ebene für Ressourcen

Irgendwann wird eine “Sektionsübersicht” zwischen der Root-Oberfläche und den Konfigurationsseiten eingefügt.

Sidebar-Links

Alle Admin-Seiten sollten in der ADMIN_NAV_MAP unter discourse/frontend/discourse/app/lib/sidebar/admin-nav-map.js at main · discourse/discourse · GitHub hinzugefügt werden. Jeder Eintrag sollte mindestens diese Schlüssel haben:

  • name – Ein eindeutiger Bezeichner für den Link, sollte snake_case sein
  • route ODER href – Der route ist ein Ember-Route-Bezeichner, wie z. B. adminUsers. Für Admins sind diese in der Admin-Route-Map definiert. Ein href kann stattdessen verwendet werden, aber route ist bevorzugt.
  • label ODER text – Label ist ein I18n-Schlüssel, der im Allgemeinen admin.config.page_name.title sein sollte (siehe Übersetzungsabschnitt unten). Wenn text verwendet wird, handelt es sich um bereits übersetzten Text.

Diese optionalen Schlüssel können ebenfalls angegeben werden:

  • description – Es wird empfohlen, dies ebenfalls anzugeben. Es ist ein I18n-Schlüssel, der im Allgemeinen admin.config.page_name.header_description sein sollte.
  • icon – Ebenfalls empfohlen, dies wird neben dem Link in der Sidebar angezeigt.
  • routeModels – Array von URL-Daten für den Fall von Route-Parametern. Zum Beispiel hat adminCustomizeThemes einen :type-Route-Parameter, sodass Sie routeModels: ["components"] übergeben können. Die Array-Elemente werden in derselben Reihenfolge verwendet, wie die Route-Parameter erscheinen.
  • moderator: Setzen Sie dies auf true, wenn Moderatoren diese Seite in der Sidebar sehen sollen.
  • keywords: Ein I18n-Schlüssel, mit einer durch | getrennten Liste von Schlüsselwörtern für den Sidebar-Link, verwendet für zusätzlichen “Such-Saft” beim Filtern/Suchen von Seiten.
  • links: Eine Liste von Routen der 3. Ebene, die sich unter der Seite in der Sidebar befinden. Diese werden nicht in der Sidebar selbst angezeigt. Dies wird für zukünftige Admin-Suchfunktionen verwendet.
  • settings_area und settings_category: Wenn die Seite nur eine Liste gefilterter Site-Einstellungen anzeigt, sollte eines davon ausgefüllt sein. Wenn die Site-Einstellung eine area definiert hat, die in AdminAreaSettings verwendet wird, sollte settings_area verwendet werden. Wenn eine gesamte Kategorie von Einstellungen auf der Seite angezeigt wird und auch in AdminAreaSettings verwendet wird, sollte settings_category verwendet werden.
  • multi_tabbed: Wenn die Seite einen Einstellungen-Tab und andere Tabs hat, sollte dies auf true gesetzt werden. Es hilft, Links für das Admin-Suchsystem zu generieren.

Übersetzungen

Der Titel und die Header-Beschreibung für jede Konfigurationsseite sollten unter:

  • admin
    • config
      • page_name
        • title: “Seitentitel”
        • header_description: “Diese Seite ist für xyz”

Sie können Beispiele dafür hier sehen:

1. Breadcrumbs (Navigationspfade)

Breadcrumbs dienen als Navigationshilfe und unterstützen Benutzer dabei, ihren aktuellen Standort, die Inhaltsstruktur und die Hierarchie innerhalb der Admin-Oberfläche zu verstehen.

Admin > Breadcrumb > Pfad
Seitentitel

:art: Design

Struktur

  1. Admin: Fester Präfix, der am Anfang jedes Breadcrumb-Pfads erscheint und auf /admin verlinkt
  2. Link: Öffnet die Seite im gleichen Fenster
  3. Separator: Ein angle-right-Icon trennt jeden Link

Verwendung

Wann verwenden:

  • Auf jeder Admin-Seite vorhanden
  • Situiert über dem Inhalt (Titel, Beschreibung, Tabs)
  • Zeigt die aktuell ausgewählte Seite

Wann nicht verwenden:

  • Beim Besuch einer neuen oder Bearbeitungsroute

Inhalt

  • Jedes Element enthält einen Link zur zugehörigen Seite
  • Zeigt die aktuell ausgewählte Seite

Barrierefreiheit

  • Ein nav-Element mit aria-label="Breadcrumb" umschließt eine geordnete Liste, um ein Navigationslandmark zu bieten
  • Wenden Sie aria-current="page" auf den letzten Link an, um anzuzeigen, dass es die aktuelle Seite ist
  • Für weitere Details siehe WAI-ARIA Authoring Practices Breadcrumb Example

:hammer_and_wrench: Implementierung

Die DBreadcrumbsContainer-Komponente muss irgendwo auf der Seite platziert werden:

<DBreadcrumbsContainer />

Dann wird jedes DBreadcrumbsItem-Element, das zu einer beliebigen Komponente auf einer Route oder einer untergeordneten Route hinzugefügt wird, in diesen Container gerendert. Jedes DBreadcrumbsItem hat ein @label und ein @path, die angegeben werden müssen:

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

Wie dies mit einem visuellen Beispiel aussieht, unter Verwendung des Discourse AI-Plugins:

2. Seiten-Header und Titel

Der obere Bereich einer Admin-Seite, der den Seitentitel sowie optionale Aktionen und Beschreibungen enthält.

:art: Design

Struktur

  • Seitentitel: Titel der Seite

  • Seitenbeschreibung: Einführung oder Beschreibung dessen, was der Inhalt abdeckt (optional)

  • Primäre Aktion: Primäre Aktion des Seitentitels (optional)

  • Sekundäre Aktion: Einstellungen für die sekundäre Aktionsschaltfläche des Seitentitels (optional)

Verwendung und Inhalt

  • Seitentitel: Verwenden Sie die Überschriftenebene 1, um das Hauptthema der Seite in Satzsatzschreibweise zu erklären. Normalerweise sollte die I18n-Übersetzung unter admin.config.your_page.title stehen.

  • Seitenbeschreibung: Unterstützt grundlegende Markdown-Knoten wie _kursiv_, **fett** und [Linkname](url)

  • Primäre Aktion: Verwenden Sie btn-primary. Fügen Sie kein Icon ein. Normalerweise sollte die I18n-Übersetzung unter admin.config.your_page.header_description stehen.

  • Sekundäre Aktion: Verwenden Sie btn-default-Schaltflächeneinstellungen, sichtbar nur, wenn eine primäre Aktion existiert. Fügen Sie kein Icon ein.

    :point_right: Seien Sie klar bei Aktionsschaltflächen. Verwenden Sie zum Beispiel beschreibende Labels wie “Emoji hinzufügen” statt nur “Hinzufügen”, um Ambiguität zu reduzieren.

:hammer_and_wrench: Implementierung

Die DPageHeader-Komponente wird hier verwendet. Diese akzeptiert Argumente für @titleLabel, @descriptionLabel, @learnMoreUrl und @shouldDisplay. Dies verwendet benannte yields in Ember, um 5 benannte Blöcke für den Inhalt bereitzustellen:

  1. breadcrumbs – Hier sollten alle zusätzlichen DBreadcrumbsItem-Komponenten für die Seite platziert werden.
  2. actions – Wird verwendet, um die Schaltflächen rechts neben dem Titel zu definieren. Dies gibt ein Objekt namens actions zurück, das verwendet werden kann, um Default, Primary, Danger und Wrapped-Schaltflächen zu rendern.
  3. title – Eine Alternative zu @titleLabel, die benutzerdefiniertes Markup innerhalb der Überschrift ermöglicht.
  4. drawer – Ein optionaler zusammenklappbarer Drawer-Bereich, der angezeigt wird, wenn @showDrawer wahr ist.
  5. tabs – Wird verwendet, um die Tabs für die Seite mit NavItem-Komponenten zu definieren. @hideTabs kann verwendet werden, um diesen Teil des Headers zu entfernen, wenn er nicht benötigt wird.

Ein vollständiges Beispiel ist unten:

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

Seitentitel für den Browser-Tab werden in Ember-Routen mit der titleToken-Funktionalität behandelt. Jedes Mal, wenn dies in einer Route verwendet wird, wird das Token an das Ende des Browser-Tab-Titels angehängt. Beachten Sie, dass Sie müssen die DiscourseRoute-Klasse verwenden, um Ihre Route zu erweitern, nicht die normale Route aus Ember, damit dies funktioniert:

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

:point_right: Der Seiten-Header wird automatisch für /new und /edit-Pfade ausgeblendet, um Routen der dritten Ebene zu unterstützen. Dies kann durch Verwendung des @shouldDisplay-Arguments überschrieben werden.

3. Tabs

Eine optionale Navigation, die Zugriff auf tiefere Ebenen von Einstellungen oder Funktionen bietet. Wir bezeichnen dies auch als Seiten oder Navigation der “dritten Ebene”.

:art: Design

Wir verwenden Tabs, um zwischen verschiedenen, aber verwandten Ansichten innerhalb desselben Kontexts zu wechseln.

Verwendung

  • Nicht für primäre Navigation verwendet
  • Nur einer gleichzeitig aktiv

:hammer_and_wrench: Implementierung

Siehe die Details unter Seiten-Header, die Tabs sind in der DPageHeader-Komponente definiert.

: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. Übersicht/Sektions-Landingpage

Ermöglicht Benutzern, den Inhalt einer Sektion anzusehen, insbesondere wenn die Sidebar zusammengeklappt ist oder auf Mobilgeräten.

:art: Design

Struktur
Verwenden Sie ein dreispaltiges Layout mit einem Gittersystem. Auf kleinen Bildschirmen werden diese Spalten vertikal gestapelt.

Design und Verwendung

  • Kann über Breadcrumbs erreicht werden (Admin > Community > Übersicht)
  • Jede Sektion sollte eine haben, außer Plugins (die installierte anzeigen) und Berichte (nur eine Seite)
  • Das Element hat:
    • name – gleich wie der Sektionslink
    • description – eine kurze Beschreibung, worum es auf der Seite geht
    • icon – gleiches Icon wie für die Sidebar verwendet

:hammer_and_wrench: Implementierung

Code-Snippets oder Link zu einem Thema/GitHub

5. Seiteninhalt

Der Hauptbereich einer Admin-Seite, in dem Einstellungen, Konfigurationen und andere Inhalte angezeigt und bearbeitet werden.

:art: Design

Struktur
Verwenden Sie ein 2/3 + 1/3-Layout mit einem Gittersystem. Der primäre Bereich nimmt zwei Drittel ein und der sekundäre Bereich nimmt ein Drittel des Platzes ein. Auf kleinen Bildschirmen werden diese Spalten vertikal gestapelt.

  • Konfigurationsbereich: Ein spezifischer Bereich innerhalb des Seiteninhalts, der Einstellungen und Konfigurationen gewidmet ist.
  • Hilfe/Referenz/Einbettung: Ein Bereich innerhalb des Seiteninhalts, der Anleitungen, Dokumentation oder zusätzliche kontextuelle Informationen bereitstellt. (optional)

Design und Verwendung

  • Gruppieren Sie ähnliche Einstellungen und Aktionen in Karten
  • Strukturieren Sie primäre/sekundäre Layouts so, dass der primäre (2/3)-Bereich für Haupteinstellungen verwendet wird und der sekundäre (1/3)-Bereich für zusätzliche Informationen oder hilfreichen Kontext
  • Wenn der sekundäre Bereich nicht verfügbar ist, behalten Sie die Breite des primären Bereichs bei

Inhalt

:hammer_and_wrench: Implementierung

Code-Snippets oder GitHub-Links

5.a. Untertitel

Ein Untertitel ist eine sekundäre Überschrift, die verwendet wird, um den Inhalt unter einer Sektion zu unterteilen, normalerweise unter den Tabs.

Struktur

  • Untertitel: Untertitel dessen, was der Inhalt abdeckt (optional)
  • Primäre Aktion: Primäre Aktion des Untertitels (optional)
  • Sekundäre Aktion: Einstellungen für die sekundäre Aktionsschaltfläche des Untertitels (optional)

Verwendung und Inhalt

  • Untertitel: Verwenden Sie die Überschriftenebene 2, um das Hauptthema des verwandten Inhalts zu erklären. Fügen Sie nur hinzu, wenn:

    • Es eine primäre Aktionsschaltfläche gibt, oder
    • Es eine Beschreibung gibt, die die Sektion erklärt.
  • Primäre Aktion: Verwenden Sie btn-primary. Fügen Sie kein Icon ein.

  • Sekundäre Aktion: Verwenden Sie btn-default-Schaltflächeneinstellungen, sichtbar nur, wenn eine primäre Aktion existiert. Fügen Sie kein Icon ein.

    :point_right: Seien Sie klar bei Aktionsschaltflächen. Verwenden Sie zum Beispiel beschreibende Labels wie “Emoji hinzufügen” statt nur “Hinzufügen”, um Ambiguität zu reduzieren.

:hammer_and_wrench: Implementierung

Dies ist ähnlich wie DPageHeader, es gibt eine DPageSubheader-Komponente. Der Hauptunterschied ist, dass es nur einen einzigen benannten Yield für actions gibt.

  1. actions – Wird verwendet, um die Schaltflächen rechts neben dem Titel zu definieren. Dies gibt ein Objekt namens actions zurück, das verwendet werden kann, um Default, Primary, Danger und Wrapped-Schaltflächen zu rendern.
<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. Konfigurationsbereich

Der Konfigurationsbereich besteht aus Karten oder Sektionen. Karten sind großartig, um verwandte Informationen und Aufgaben zu gruppieren und Benutzern zu helfen, Inhalte leichter zu scannen und zu priorisieren.

:art: Design

Karte

Karten werden mit einem 2px-Bordradius eingerichtet und verwenden einen Hintergrund von --secondary. Sie haben auch einen 1px-festen Rand mit --primary-low und 20px Polsterung um den Inhalt.

Standardvariante

Akkordeonvariante

Design und Verwendung

  • Verwandte Informationen gruppieren
  • Informationen so anzeigen, dass Admins und Moderatoren die wichtigsten Dinge zuerst sehen
  • Überschriften verwenden, die klar erklären, wofür die Karte ist
  • Komplizierte in mehrere Sektionen aufteilen, falls nötig

standardvariante

  • Bei einer primären Handlungsaufforderung pro Karte bleiben
  • Primäre Handlungsaufforderung am unteren Rand der Karte für nächste Schritte platzieren

akkordeonvariante

  • Verwenden Sie die obere rechte Ecke der Karte für optionale Aktionen wie “Alle anzeigen”

Inhalt

  • Alle Formulare sollten die FormKit-Ember-Komponenten im Kern verwenden, die in der Dokumentation beschrieben sind

  • Karten-Überschriften sollten in Satzsatzschreibweise sein

    :white_check_mark: Do :cross_mark: Don’t
    Allgemeine Einstellungen Allgemeine Einstellungen
    Kontaktinformationen KONTAKTINFORMATIONEN

:hammer_and_wrench: Implementierung

Wir haben eine AdminConfigAreaCard-Komponente, die für all diese Karten verwendet werden sollte. Für jetzt hat diese nur @translatedHeading und @heading-Argumente, in Zukunft können wir Aktionen hinzufügen und sie zusammenklappbar machen und so weiter:

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

Eingebettete Site-Einstellungen

Dieser Abschnitt ist in Arbeit.

5.c. Hilfe-Einbettung

Dieser Bereich bietet zusätzliche Anleitung, Dokumentation oder Kontext innerhalb des Seiteninhalts.

v1

:art: Design

Design und Verwendung

  • Verwandte Dokumentation oder Anleitungen zum Inhalt der Seite anzeigen, um nützliche Informationen bereitzustellen
  • Ein Icon in der Überschrift einschließen, um es leicht erkennbar zu machen
  • Diesen Bereich im sekundären (1/3)-Layoutbereich platzieren

Inhalt

  • Überschriften sollten in Satzsatzschreibweise sein

:hammer_and_wrench: Implementierung

Code-Snippets oder Link zu einem Thema/GitHub

5.d. Tabelle

Tabellen zeigen Informationen in einem Raster aus Zellen, Spalten und Zeilen an, was es Admins erleichtert, Elemente schnell zu scannen und Aktionen auszuführen.

:art: Design

Verwendung

  • Verwenden Sie Tabellen, um strukturierte Inhalte anzuzeigen, bei denen jeder Eintrag die gleichen Attribute teilt.
  • Ermöglichen Sie Admins, Datensätze zu überprüfen, zu aktivieren/deaktivieren, zu bearbeiten und zu löschen.
  • Geeignet für Datensätze, die im Laufe der Zeit weiter wachsen werden.

Design

  • Verwenden Sie horizontale Linien zwischen den Zeilen, um Inhalte visuell zu trennen, einschließlich der letzten Zeile. Vermeiden Sie die Verwendung von Rahmen oder Rahmen um die Tabelle, um zu verhindern, dass sie wie ein Netz aussieht.
  • Wenden Sie keine vertikalen Linien zwischen den Spalten an. Tabellen ohne vertikale Linien sind im Allgemeinen leichter zu scannen und zu lesen.

Zusätzliche Aktionen

  • Zeilenaktionen: Fügen Sie zusätzliche Aktionen in der äußersten rechten Spalte jeder Tabellenzeile hinzu.
    • Wenn es zwei oder mehr interaktive Elemente gibt, sollte die primäre Aktion (z. B. “Bearbeiten”) eine Textschaltfläche sein, und alle anderen Zeilenaktionen einschließlich “Löschen” sollten in einem [...]-Dropdown gruppiert werden. Icons in den Dropdown-Menüs werden empfohlen, um Dinge visuell aufzubrechen.
    • Wenn es nur eine “Löschen”-Aktion gibt und keine primäre Aktion, verwenden Sie eine Inline-“Löschen”-Textschaltfläche, die als btn-default gestaltet ist.
    • Sie sollten den Text der Hauptspalte (im Allgemeinen d-table__cell --overview) mit einem Link umschließen, der den Admin direkt zur Show/Bearbeiten-Seite führt, die der Zeile entspricht, für schnellen Zugriff.
  • Löschbestätigung: Alle “Löschen”-Schaltflächen sollten eine Bestätigung anzeigen, bevor die Aktion ausgeführt wird.

Inhalt

  • Header: Der Tabellen-Header ist die oberste Zeile, die die darunterliegenden Spalten identifiziert. Er bietet Klarheit, insbesondere wenn die Daten nicht beschreibend oder mehrdeutig sind. Header sollten kurz, beschreibend und relevant sein und Titelschreibweise verwenden. Vermeiden Sie Header, die für die Inhalte in den darunterliegenden Zeilen zu lang sind.
  • Spalten: Ordnen Sie Spalten nach Priorität oder auf eine Weise, die eine kohärente Geschichte mit den Daten erzählt. Passen Sie die Größe der Spalten an ihren Inhalt an, mit schmalen Spalten für kleinen Inhalt und breiteren Spalten für Absätze.
  • Zeilen: Zeilen sollten Text, Schaltflächen, Links und Icons unterstützen, um die Datendarstellung zu verbessern.
  • Keine Daten: Leere Listen sollten die AdminConfigAreaEmptyList-Komponente mit einer CTA-Schaltfläche und einem Label verwenden, um den Benutzer zur Erstellung neuer Datensätze zu führen

:hammer_and_wrench: Implementierung

Es gibt eine kleine Sammlung von CSS-Klassen, die mit Tabellen verwendet werden müssen, damit sie auf Mobil- und Desktop-Geräten gut funktionieren.

<table>-Elemente sollten die d-table-Klasse angewendet haben.

<thead>-Elemente sollten die d-table__header-Klasse angewendet haben.

<tr>-Elemente sollten die d-table__row-Klasse angewendet haben.

<td>-Elemente, die viel beschreibenden Text enthalten (normalerweise die leftmost Spalte), sollten die d-table__cell --overview-Klassen verwenden. Alle anderen Zellen sollten d-table__cell --detail verwenden.

<td>-Elemente mit den d-table__cell --overview-Klassen können den inneren Zeileninhalt in einen Link einbetten, der den Admin direkt zur Bearbeiten/Anzeigen-Seite für die Zeile führt. Dieser Link sollte dieser Struktur folgen und die d-table__overview-link-CSS-Klasse angewendet haben. Idealerweise sollte die LinkTo-Komponente verwendet werden, aber <a> ist auch in Ordnung, solange getURL damit verwendet wird.

Die d-table__overview-name-Klasse sollte auf den Namensteil hier angewendet werden, aber nicht auf die Beschreibung.

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

<td>-Elemente, die die Schaltflächen in jeder Zeile umschließen, sollten die d-table-cell --controls-CSS-Klassen angewendet haben. Dies stellt sicher, dass die Schaltflächen ausgerichtet sind. Jede Schaltfläche sollte auch die btn-small-Klasse angewendet haben.

Für Mobilgeräte sollte jedes <td>-Element außer der d-table-cell --overview auch ein <div> mit der Klasse d-table__mobile-label enthalten, das ein I18n-Label enthält, das dasselbe ist wie das in der <th> für diese Spalte:

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

Dies zeigt die Tabellenzeile als ein leichter zu lesendes, kartenbasiertes Format auf Mobilgeräten an:

Für [...]-Dropdown-Menüs sollte DMenu mit DropdownMenu verwendet werden, hier ist ein Beispiel:

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

Toggles in der Tabellenzeile werden mit der DToggleSwitch-Komponente behandelt:

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

Hier ist ein minimales Beispiel einer Admin-Tabelle, die alles zusammenfasst:

 <table class="d-table">
    <thead class="d-table__header">
      <tr>
        <th>Name</th>
        <th>Beschreibung</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">Beispiel-Element</span>
            <span class="d-table__overview-about">Eine kurze Beschreibung</span>
          </LinkTo>
        </td>
        <td class="d-table__cell --detail">
          <span class="d-table__mobile-label">Beschreibung</span>
          Hier etwas Detailinhalt
        </td>
        <td class="d-table__cell --controls">
          <div class="d-table__cell-actions">
            <button class="btn btn-default btn-small">Bearbeiten</button>
          </div>
        </td>
      </tr>
    </tbody>
  </table>

5.e Route der dritten Ebene

Eine Route der dritten Ebene ist eine, die nur von einem Konfigurationsbereich aus erreicht werden kann. Diese kommen normalerweise in Form von Bearbeiten/Neue-Routen wie dieser für Flags:

Hier werden in den meisten Fällen Formulare mit FormKit platziert.

Verwenden Sie die standardmäßigen RESTful-Routen dafür:

Aktion Pfad
Neu <resource>/new
Bearbeiten <resource>/:id/edit

und stellen Sie sicher, dass die Routen auch im Back-End geroutet sind. (Das Neuladen der neuen- oder Bearbeitungsseite sollte nicht zu einem Fehler führen.)

:art: Design

Verwendungn

  • Bevorzugen Sie diese Routen der dritten Ebene gegenüber Inline-Formularen auf der Hauptroute oder innerhalb einer Tabelle. Eigenständige Bearbeiten- und Neue-Routen sind am besten, da sie leicht verlinkt werden können.
  • Zeigen Sie nicht den oberen Teil der Seiten-UI (Breadcrumbs, Seiten-Header und -Untertitel)
  • Zeigen Sie stattdessen einen einzelnen “Zurück zu X”-Link, der dem Admin ermöglicht, zum Hauptkonfigurationsbereich zu gelangen
  • Der Inhalt der Seite sollte in mindestens einer AdminConfigAreaCard eingebettet sein
  • Alle Untertitel auf der Seite sollten mit Konfigurationsbereichskarten erfolgen

:hammer_and_wrench: Implementierung

Es gibt eine einfache BackButton-Komponente, die oben auf der Seite verwendet werden kann, um zurückzugehen:

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

6. Gefilterte Einstellungskonfigurationsseiten

Viele unserer Admin-Oberflächen-Konfigurationsseiten sind einfache Listen gefilterter Site-Einstellungen. Dies ermöglicht es Admins, verwandte Gruppen von Einstellungen zu finden, ohne von der vollständigen “Alle Site-Einstellungen”-Liste überwältigt zu werden, bis wir spezialisierte Konfigurationsseiten wie /admin/config/about/ erstellen.

:hammer_and_wrench: Implementierung

Es gibt ein paar Dinge, die Sie hinzufügen müssen, um eine dieser Routen zu erstellen. Zuerst können Sie entweder eine gesamte category von Site-Einstellungen anzeigen, die die Top-Level-Schlüssel in site_settings.yml sind (z. B. branding:), oder Sie können eine Einstellung area verwenden.

Site-Einstellungen können in mehreren areas leben, und Sie können eine oder mehrere auf derselben Seite anzeigen.

  1. Fügen Sie eine Route zur Admin-Route-Map unter adminConfig hinzu, zum Beispiel:
this.route("trustLevels", { path: "/trust-levels" }, function () {
  this.route("settings", {
    path: "/",
  });
});
  1. Fügen Sie eine neue Route .js-Datei hinzu, die Datei wird einem Pfad wie frontend/discourse/admin/routes/admin-config/localization.js entsprechen, abhängig vom Namen Ihrer neuen Route. Diese sollte von AdminConfigWithSettingsRoute erben und eine titleToken() enthalten.
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. Fügen Sie einen Controller hinzu, dies dient hauptsächlich dazu, die Einstellungssuche und -filterung zu ermöglichen. Er muss von AdminAreaSettingsBaseController erben:
import AdminAreaSettingsBaseController from "discourse/admin/controllers/admin-area-settings-base";

export default class AdminConfigLocalizationSettingsController extends AdminAreaSettingsBaseController {}
  1. Fügen Sie schließlich eine Route-Vorlagendatei im .gjs-Format hinzu, an einem Pfad wie frontend/discourse/admin/templates/admin-config/localization/settings.gjs. Diese sollte den normalen DPageHeader und Breadcrumbs enthalten, aber um die Einstellungen anzuzeigen, benötigen Sie AdminAreaSettings.
<div class="admin-config-page__main-area">
  <AdminAreaSettings
    @showBreadcrumb={{false}}
    @area="localization"
    @path="/admin/config/localization"
    @filter={{@controller.filter}}
    @adminSettingsFilterChangedCallback={{@controller.adminSettingsFilterChangedCallback}}
  />
</div>

Die wichtigsten Dinge, die hier geändert werden müssen, sind @path und @area (oder alternativ @categories). Wie ранее erwähnt, füllen Sie dies entweder mit der Site-Einstellungsarea aus, die Sie anzeigen möchten, oder mit den Kategorien.

7. Allgemeine Richtlinien

  • URL-Slugs müssen Bindestriche (-) verwenden, um Leerzeichen in Wörtern anzugeben, anstatt Unterstriche (_).

  • Alle Texte in Admin-Oberflächen sollten die Textformatierungsrichtlinien befolgen, die hier outlined sind:

8. Plugins

Einige Plugins benötigen eine tiefgehende Konfigurations-UI für ihr Plugin (zum Beispiel KI, Automatisierung, Gamification), anstatt nur eine Sammlung von Site-Einstellungen zu haben. Zum Beispiel hier ist Discourse AI:

Einige Beispiele für Plugins, die dies verwenden, sind:

:art: Design

Verwendung

  • Allgemeine Admin-UI-Richtlinien sollten befolgt werden, wenn unabhängige Plugin-UIs erstellt werden.

:hammer_and_wrench: Implementierung

Ember-Routing

  • Alle Route-Vorlagen werden unter
    admin/assets/javascripts/discourse/templates/admin-plugins/show/
  • Alle Route-JS-Dateien werden unter admin/assets/javascripts/discourse/routes/ sein und
    mit admin-plugins-show- präfixiert
  • Die Admin-Route-Map sollte in einer Datei wie admin-PLUGIN-NAME-plugin-route-map.js sein
  • Die Route-Map sollte eine Struktur wie diese haben. Der wichtige Teil ist, dass
    wir admin.adminPlugins.show als resource verwenden.
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" });
    });
  },
};
  • Das aktuelle Beispiel, wie dies alles funktioniert, ist im Discourse AI-Plugin zu sehen, wenn Sie zu /admin/plugins/discourse-ai/ai-personas gehen
  • Wenn Sie nur eine “Top-Level”-Route haben, z. B. eine, die keine Unter-Routen definiert, dann wird der Vorlagenpfad etwas wie admin/assets/javascripts/discourse/templates/admin-plugins/show/your-route-name.gjs sein. Wenn es Unter-Routen gibt, dann kommen Sie in den Bereich, in dem Sie index.gjs, show.gjs und new.gjs-Vorlagen und so weiter benötigen.

Navigation

Plugins können ihre Navigation entweder in einer inneren Sidebar oder in der oberen tabbed-Navigationsleiste anzeigen. Letzteres wird stark empfohlen, und in Zukunft kann die Unterstützung für die innere Sidebar fallen gelassen werden.

  • Alle Links, die entweder in der oberen Leiste oder in der inneren Sidebar für
    die Plugin-Show-Seite angezeigt werden sollen, sollten in einem Initializer definiert werden (z. B.
    assets/javascripts/initializers/admin-plugin-configuration-nav.js) unter Verwendung von
    api.addAdminPluginConfigurationNav . Links benötigen ein label, route und description (was für die Admin-Suche verwendet wird)
  • Dieser Initializer sollte nur ausgeführt werden, wenn der Benutzer Admin ist.
  • Der Site-Einstellungen-Link für das Plugin wird automatisch generiert, es ist nicht nötig, ihn hier einzuschließen.
  • Ein Beispiel kann hier gesehen werden discourse-ai/assets/javascripts/initializers/admin-plugin-configuration-nav.js at ab4544d8977ec0e9d6aa42b4551df8317aa9b365 · discourse/discourse-ai · GitHub .

Server-Seite

  • add_admin_route wird immer noch verwendet, um die benutzerdefinierten Admin-Routen in der Admin-Sidebar und von der /plugins-Indexseite mit den Tabs oben anzuzeigen. Grundsätzlich definiert dies die Root-Seite Ihrer Plugin-UI.
    • use_new_show_route: true sollte hier als zusätzliches Argument übergeben werden, damit die neue Plugin-Show-Seite verwendet wird.

UI-Konventionen

  • Jede Index-Route für das Plugin sollte eine DPageSubheader-Komponente anzeigen, um die Absicht dieser Route zu beschreiben und alle zugehörigen Aktionsschaltflächen hinzuzufügen.
  • Aktionsschaltflächen, die in den Haupt-Plugin-Seiten-Header gerendert werden müssen, müssen den admin-plugin-config-page-actions-Outlet mit einer dedizierten Komponente verwenden. Der beste Ort dafür ist im selben Initializer, in dem addAdminPluginConfigurationNav verwendet wird.
    • plugin und actions werden als outletArgs übergeben. plugin ist die Modellrepräsentation des aktuellen Plugins, sodass der Name des Plugins und andere Dinge zugegriffen werden können, actions sind die ausgelieferten Aktionsschaltflächen-Komponenten von DPageHeader.
api.renderInOutlet(
  "admin-plugin-config-page-actions",
  ChatAdminPluginActions
);

Verwandte Themen:

10 „Gefällt mir“

Und

funktionieren immer noch nicht. Ich denke, die zweite ist -23 statt -24.

5 „Gefällt mir“

Ich bin so froh, das endlich auf Meta zu sehen. Monatelange Arbeit steckte darin, und wir werden es verwenden, um die Benutzeroberfläche und Navigation jeder Seite in der Admin-Oberfläche zu standardisieren.

Sollten wir vielleicht einfach das Inhaltsverzeichnis entfernen und uns stattdessen auf discotoc verlassen? Ich denke, das wäre weniger fehleranfällig, obwohl ich es mag, das Inhaltsverzeichnis oben im Beitrag zu sehen.

7 „Gefällt mir“

Danke @Moin – alles behoben!

Ich habe diese Änderung vorgenommen, sonst ist es einfach ein doppeltes Inhaltsverzeichnis.

4 „Gefällt mir“

Ein Beitrag wurde in ein neues Thema aufgeteilt: Benutzernamen im Browser-Tab anzeigen, wenn auf Benutzerverwaltung zugegriffen wird