일관된 관리자 인터페이스 만들기

이 가이드라인은 일관된 관리자 인터페이스를 만들기 위해 사용성, 접근성 및 구조화된 레이아웃에 초점을 맞춥니다. 포함되는 내용과 각 섹션으로 쉽게 이동하려면 목차를 참조하세요.

참고: 여기서 사용되는 용어는 관리자 인터페이스 용어집에서 정의되어 있습니다.

0. 서문 - 설정 페이지 구조 및 사이드바 링크

관리자 인터페이스에 새로운 설정 페이지를 추가할 때, 각 페이지에는 사이드바 링크가 필요하며, 각 페이지에는 제목과 헤더 설명이 모두 필요합니다. 이를 통해 모든 곳에서 일관성을 유지하고, 향후 관리자 검색 기능의 향상이 관리자 인터페이스의 전체 레이아웃을 표시할 수 있습니다.

일반적으로 관리자 인터페이스의 구조는 다음과 같습니다:

  • 관리자 인터페이스
    • 설정 페이지 (사이드바에 표시됨)
      • 설정 탭
      • 선택적 기타 3차 탭
        • 리소스를 위한 편집/신규 3차 페이지

궁극적으로, 루트 인터페이스와 설정 페이지 사이에 "섹션 개요"가 삽입될 것입니다.

사이드바 링크

모든 관리자 페이지는 discourse/frontend/discourse/app/lib/sidebar/admin-nav-map.js at main · discourse/discourse · GitHub 의 ADMIN_NAV_MAP에 추가되어야 합니다. 각 항목은 최소한 다음 키를 가져야 합니다:

  • name - 링크의 고유 식별자, snake_case여야 합니다.
  • route 또는 href - route는 adminUsers와 같은 Ember 라우트 식별자입니다. 관리자의 경우, 이들은 관리자 라우트 맵에서 정의됩니다. 대신 href를 사용할 수 있지만, route가 권장됩니다.
  • label 또는 text - label은 일반적으로 admin.config.page_name.title이어야 하는 I18n 키입니다 (아래 번역 섹션 참조). text를 사용하면 이미 번역된 텍스트가 됩니다.

다음과 같은 선택적 키도 제공할 수 있습니다:

  • description - 이것도 제공되는 것이 권장됩니다. 이는 I18n 키이며, 일반적으로 admin.config.page_name.header_description이어야 합니다.
  • icon - 이것도 권장되며, 사이드바에서 링크 옆에 표시됩니다.
  • routeModels - 라우트 매개변수의 경우를 위한 URL 데이터 배열. 예를 들어 adminCustomizeThemes에는 :type 라우트 매개변수가 있으므로 routeModels: ["components"]를 전달할 수 있습니다. 배열 항목은 라우트 매개변수가 나타나는 순서와 동일한 순서로 사용됩니다.
  • moderator: 이 페이지가 사이드바에서 모더레이터에게도 표시되어야 한다면 true로 설정합니다.
  • keywords: 사이드바 링크를 위한 |로 구분된 키워드 목록의 I18n 키로, 페이지를 필터링/검색할 때 추가적인 "검색 용이성"을 위해 사용됩니다.
  • links: 사이드바에서 페이지 아래에 있는 3차 라우트 목록입니다. 이들은 사이드바 자체에는 표시되지 않습니다. 이는 향후 관리자 검색 기능에 사용될 것입니다.
  • settings_area 및 settings_category: 페이지가 필터링된 사이트 설정 목록만 표시하는 경우, 이 중 하나를 채워야 합니다. 사이트 설정에 AdminAreaSettings에서 사용되는 area가 정의되어 있다면 settings_area를 사용해야 합니다. 페이지에서 설정의 전체 카테고리가 표시되고 AdminAreaSettings에서도 사용되는 경우, settings_category를 사용해야 합니다.
  • multi_tabbed: 페이지에 설정 탭 및 기타 탭이 있는 경우, 이 값을 true로 설정해야 합니다. 이는 관리자 검색 시스템을 위한 링크 생성에 도움이 됩니다.

번역

모든 설정 페이지의 제목과 헤더 설명은 아래 위치에 있어야 합니다:

  • admin
    • config
      • page_name
        • title: “페이지 제목”
        • header_description: “이 페이지는 xyz를 위한 것입니다”

여기서 이를 확인할 수 있습니다:

1. 브레드크럼

브레드크럼은 사용자가 관리자 인터페이스 내에서 현재 위치, 콘텐츠 구조 및 계층 구조를 이해하도록 돕는 탐색 도구입니다.

Admin > Breadcrumb > Trail
페이지 제목

:art: 디자인

구조

  1. Admin: 모든 브레드크럼 트레일의 시작 부분에 나타나며 /admin으로 연결되는 고정 접두사입니다.
  2. 링크: 같은 창에서 페이지를 엽니다.
  3. 구분자: 각 링크를 구분하는 angle-right 아이콘입니다.

사용법

사용할 때:

  • 모든 관리자 페이지에 존재합니다.
  • 콘텐츠(제목, 설명, 탭) 위에 위치합니다.
  • 현재 선택된 페이지를 표시합니다.

사용하지 않을 때:

  • 신규 또는 편집 라우트를 방문할 때

콘텐츠

  • 각 항목에는 해당 페이지로의 링크가 포함됩니다.
  • 현재 선택된 페이지를 표시합니다.

접근성

  • aria-label="Breadcrumb"가 있는 nav 요소가 순서 있는 목록을 감싸서 탐색 랜드마크를 제공합니다.
  • 현재 페이지임을 나타내기 위해 마지막 링크에 aria-current="page"를 적용합니다.
  • 자세한 내용은 WAI-ARIA Authoring Practices Breadcrumb Example을 참조하세요.

:hammer_and_wrench: 구현

DBreadcrumbsContainer 컴포넌트는 페이지 어딘가에 배치되어야 합니다:

<DBreadcrumbsContainer />

그런 다음, 라우트 또는 하위 라우트의 모든 컴포넌트에 추가되는 모든 DBreadcrumbsItem 요소는 이 컨테이너에 렌더링됩니다. 각 DBreadcrumbsItem에는 제공되어야 하는 @label과 @path가 있습니다:

<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}}
/>
```\n
Discourse AI 플러그인을 사용하여 시각적 예제로 이렇게 보입니다:

![An example of breadcrumbs|690x302, 75%](upload://2jbYauteEJY2b6OimlKlW1TDJyq.jpeg)

# 2. 페이지 헤더 및 제목

관리자 페이지의 상단 섹션으로, 페이지 제목과 함께 선택적 작업 및 설명을 포함합니다.

![A page title example|690x114](upload://iBs3rxNAlF6s0xrUj2XFIVvMsBC.png)

## :art: 디자인

**구조**

* **페이지 제목:** 페이지의 제목

* **페이지 설명:** 콘텐츠가 다루는 내용에 대한 도입부 또는 설명 *(선택적)*

* **주 작업:** 페이지 제목의 주 작업 *(선택적)*

* **보조 작업:** 페이지 제목의 보조 작업 버튼 설정 *(선택적)*

**사용법 및 콘텐츠**

* **페이지 제목:** 페이지의 주요 주제를 문장 체(senctence case)로 설명하기 위해 헤딩 레벨 1을 사용하세요. 일반적으로 I18n 번역은 `admin.config.your_page.title` 아래에 있어야 합니다.

* **페이지 설명:** `_italic_`, `**bold**`, `[link name](url)`과 같은 기본 마크다운 노드를 지원합니다.

* **주 작업:** `btn-primary`를 사용하세요. 아이콘을 포함하지 마세요. 일반적으로 I18n 번역은 `admin.config.your_page.header_description` 아래에 있어야 합니다.

* **보조 작업:** `btn-default` 버튼 설정을 사용하며, 주 작업이 존재할 때만 표시됩니다. 아이콘을 포함하지 마세요.

  > :point_right: 작업 버튼은 명확해야 합니다. 예를 들어, 모호성을 줄이기 위해 단순히 "추가" 대신 "이모지 추가"와 같은 설명적인 라벨을 사용하세요.

## :hammer_and_wrench: 구현

여기서는 `DPageHeader` 컴포넌트가 사용됩니다. 이는 `@titleLabel`, `@descriptionLabel`, `@learnMoreUrl`, `@shouldDisplay` 인수를 받아들입니다. 이는 Ember에서 명명된 `yields`를 사용하여 콘텐츠에 5개의 명명된 블록을 제공합니다:

1. `breadcrumbs` - 페이지를 위한 추가 `DBreadcrumbsItem` 컴포넌트는 여기에 배치해야 합니다.
2. `actions` - 제목 오른쪽의 버튼을 정의하는 데 사용됩니다. `Default`, `Primary`, `Danger`, `Wrapped` 버튼을 렌더링하는 데 사용할 수 있는 `actions`라는 이름의 객체를 yield합니다.
3. `title` - `@titleLabel`의 대안으로, 헤딩 내부에 사용자 정의 마크업을 허용합니다.
4. `drawer` - `@showDrawer`가 true일 때 표시되는 선택적 접이식 드로어 섹션입니다.
5. `tabs` - `NavItem` 컴포넌트를 사용하여 페이지의 탭을 정의하는 데 사용됩니다. 필요하지 않다면 `@hideTabs`를 사용하여 헤더의 이 부분을 제거할 수 있습니다.

완전한 예제는 아래와 같습니다:

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

브라우저 탭의 페이지 제목은 titleToken 기능을 사용하여 Ember 라우트에서 처리됩니다. 라우트에서 이 기능이 사용될 때마다 브라우저 탭 제목의 끝에 토큰이 추가됩니다. 이것이 작동하려면 반드시 DiscourseRoute 클래스를 사용하여 라우트를 확장해야 하며, Ember의 일반 Route를 사용해서는 안 됩니다:

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

:point_right: 페이지 헤더는 3차 라우트를 지원하기 위해 /new 및 /edit 경로에 대해 자동으로 숨겨집니다. @shouldDisplay 인수를 사용하여 오버라이드할 수 있습니다.

3. 탭

설정 또는 기능의 더 깊은 수준에 대한 액세스를 제공하는 선택적 탐색입니다. 우리는 이것을 “3차” 페이지 또는 탐색이라고도 부릅니다.

:art: 디자인

우리는 같은 컨텍스트 내에서 서로 관련이 있지만 다른 뷰를 전환하는 데 탭을 사용합니다.

사용법

  • 주 탐색에는 사용되지 않습니다.
  • 한 번에 하나만 활성 상태입니다.

:hammer_and_wrench: 구현

페이지 헤더 세부 사항을 참조하세요. 탭은 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. 개요/섹션 랜딩 페이지

사이드바가 접히거나 모바일 환경에서 특히 섹션의 콘텐츠를 사용자에게 표시할 수 있게 합니다.

:art: 디자인

구조
그리드 시스템을 사용하여 세 개의 동일한 열 레이아웃을 사용합니다. 작은 화면에서 이러한 열은 세로로 쌓입니다.

디자인 및 사용법

  • 브레드크럼(Admin > Community > Overview)을 통해 액세스할 수 있습니다.
  • 각 섹션에는 하나씩 있어야 하지만, 플러그인(설치된 항목을 표시)과 보고서(페이지가 하나만 있음)는 예외입니다.
  • 항목에는 다음이 있습니다:
    • 이름 - 섹션 링크와 동일
    • 설명 - 페이지가 무엇에 대한지에 대한 짧은 설명
    • 아이콘 - 사이드바에 사용되는 동일한 아이콘

:hammer_and_wrench: 구현

코드 스니펫 또는 토픽/GitHub 링크

5. 페이지 콘텐츠

설정, 구성 및 기타 콘텐츠가 표시되고 상호 작용되는 관리자 페이지의 주요 영역입니다.

:art: 디자인

구조
그리드 시스템을 사용하여 2/3 + 1/3 레이아웃을 사용합니다. 주요 섹션은 2/3를 차지하고 보조 섹션은 공간의 1/3를 차지합니다. 작은 화면에서 이러한 열은 세로로 쌓입니다.

  • 설정 영역: 페이지 콘텐츠 내에서 설정 및 구성에 전념하는 특정 섹션입니다.
  • 도움말/참조/인셋: 가이드, 문서 또는 추가적인 컨텍스트 정보를 제공하는 페이지 콘텐츠 내 영역입니다. (선택적)

디자인 및 사용법

  • 유사한 설정과 작업을 카드로 그룹화하세요.
  • 주요(2/3) 섹션은 주요 설정에, 보조(1/3) 섹션은 추가 정보나 도움이 되는 컨텍스트에 사용되도록 주요/보조 레이아웃을 구성하세요.
  • 보조 섹션이 없으면 주요 섹션의 너비를 동일하게 유지하세요.

콘텐츠

:hammer_and_wrench: 구현

코드 스니펫 또는 GitHub 링크

5.a. 서브헤드

서브헤드는 섹션 아래, 일반적으로 탭 아래에서 콘텐츠를 나누기 위해 사용되는 보조 헤딩입니다.

구조

  • 서브헤딩: 콘텐츠가 다루는 내용에 대한 서브헤딩 (선택적)
  • 주 작업: 서브헤딩의 주 작업 (선택적)
  • 보조 작업: 서브헤딩의 보조 작업 버튼 설정 (선택적)

사용법 및 콘텐츠

  • 서브헤딩: 관련 콘텐츠의 주요 주제를 설명하기 위해 헤딩 레벨 2를 사용하세요. 다음 경우에만 포함하세요:

    • 주 작업 버튼이 있거나,
    • 섹션을 설명하는 설명이 있는 경우.
  • 주 작업: btn-primary를 사용하세요. 아이콘을 포함하지 마세요.

  • 보조 작업: btn-default 버튼 설정을 사용하며, 주 작업이 존재할 때만 표시됩니다. 아이콘을 포함하지 마세요.

    :point_right: 작업 버튼은 명확해야 합니다. 예를 들어, 모호성을 줄이기 위해 단순히 “추가” 대신 "이모지 추가"와 같은 설명적인 라벨을 사용하세요.

:hammer_and_wrench: 구현

이것은 DPageHeader와 유사하며, DPageSubheader 컴포넌트가 있습니다. 주요 차이점은 actions를 위한 단일 명명된 yield만 있다는 것입니다.

  1. actions - 제목 오른쪽의 버튼을 정의하는 데 사용됩니다. Default, Primary, Danger, Wrapped 버튼을 렌더링하는 데 사용할 수 있는 actions라는 이름의 객체를 yield합니다.
<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. 설정 영역

설정 영역은 카드 또는 섹션으로 구성됩니다. 카드는 관련 정보와 작업을 그룹화하는 데 유용하며, 사용자가 콘텐츠를 더 쉽게 스캔하고 우선순위를 정하는 데 도움이 됩니다.

:art: 디자인

카드

카드는 2px의 테두리 반경으로 설정되고 --secondary 배경을 사용합니다. 또한 --primary-low의 1px 솔리드 테두리와 콘텐츠 주위의 20px 패딩을 가집니다.

기본 변형

아코디언 변형

디자인 및 사용법

  • 관련 정보를 그룹화하세요.
  • 관리자와 모더레이터가 가장 중요한 사항을 먼저 볼 수 있도록 정보를 표시하세요.
  • 카드의 용도를 명확히 설명하는 헤딩을 사용하세요.
  • 필요할 경우 복잡한 카드를 여러 섹션으로 나누세요.

기본 변형

  • 카드당 하나의 주 호출 작업(CTA)에 집중하세요.
  • 다음 단계를 위해 주 호출 작업을 카드 하단에 배치하세요.

아코디언 변형

  • "모두 보기"와 같은 선택적 작업을 위해 카드의 오른쪽 위 모서리를 사용하세요.

콘텐츠

  • 모든 양식은 문서에 설명된 코어의 FormKit ember 컴포넌트를 사용해야 합니다.

  • 카드 헤더는 문장 체(senctence case)여야 합니다.

    :white_check_mark: 이렇게 하세요 :cross_mark: 이렇게 하지 마세요
    일반 설정 General Settings
    연락처 정보 CONTACT INFORMATION

:hammer_and_wrench: 구현

이 모든 카드에 사용해야 하는 AdminConfigAreaCard 컴포넌트가 있습니다. 현재 이것은 @translatedHeading과 @heading 인수만 가지고 있지만, 미래에는 작업을 추가하고 접을 수 있게 하는 등의 기능이 추가될 수 있습니다:

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

내장 사이트 설정

이 섹션은 진행 중입니다.

5.c. 도움말 인셋

이 섹션은 페이지 콘텐츠 내에서 추가적인 가이드, 문서 또는 컨텍스트를 제공합니다.

v1

:art: 디자인

디자인 및 사용법

  • 페이지 콘텐츠에 대한 관련 문서 또는 가이드를 표시하여 유용한 정보를 제공하세요.
  • 쉽게 인식할 수 있도록 헤딩에 아이콘을 포함하세요.
  • 이 섹션을 보조(1/3) 레이아웃 영역에 배치하세요.

콘텐츠

  • 헤더는 문장 체(senctence case)여야 합니다.

:hammer_and_wrench: 구현

코드 스니펫 또는 토픽/GitHub 링크

5.d. 테이블

테이블은 정보를 셀, 열, 행의 그리드로 표시하여 관리자가 항목을 빠르게 스캔하고 조치를 취할 수 있게 합니다.

:art: 디자인

사용법

  • 각 항목이 동일한 속성을 공유하는 구조화된 콘텐츠를 표시하는 데 테이블을 사용하세요.
  • 관리자가 데이터 세트를 검토하고, 활성화/비활성화하고, 편집하고, 삭제할 수 있도록 하세요.
  • 시간이 지남에 따라 계속 성장할 데이터 세트에 적합합니다.

디자인

  • 콘텐츠를 시각적으로 분리하기 위해 행 사이에 수평선을 사용하세요. 마지막 행도 포함합니다. 테이블 주위에 테두리나 프레임을 사용하여 그물처럼 보이게 하는 것을 피하세요.
  • 열 사이에 수직선을 적용하지 마세요. 수직선이 없는 테이블은 일반적으로 스캔하고 읽기가 더 쉽습니다.

추가 작업

  • 행 작업: 각 테이블 행의 가장 오른쪽 열에 추가 작업을 포함하세요.
    • 두 개 이상의 인터랙티브 요소가 있는 경우, 주 작업(예: “편집”)은 텍스트 버튼이어야 하고, "삭제"를 포함한 모든 기타 행 작업은 [...] 드롭다운에 그룹화되어야 합니다. 드롭다운 메뉴의 아이콘은 시각적으로 요소를 나누기 위해 권장됩니다.
    • 주 작업이 없고 “삭제” 작업만 있는 경우, btn-default 스타일의 인라인 “삭제” 텍스트 버튼을 사용하세요.
    • 행에 해당하는 Show/Edit 페이지로 관리자를 직접 연결하는 링크로 주요 열의 텍스트(일반적으로 d-table__cell --overview)를 감싸서 빠른 액세스를 제공해야 합니다.
  • 삭제 확인: 모든 “삭제” 버튼은 작업을 수행하기 전에 확인을 표시해야 합니다.

콘텐츠

  • 헤더: 테이블 헤더는 아래 열을 식별하는 맨 위 행입니다. 데이터가 비설명적이거나 모호한 경우 특히 명확성을 제공합니다. 헤더는 짧고, 설명적이며, 관련성이 있어야 하며, 제목 체(title case)를 사용해야 합니다. 아래 행의 콘텐츠에 비해 너무 긴 헤더를 피하세요.
  • 열: 우선순위 순서로 열을 정렬하거나 데이터로 일관된 이야기를 들려주는 방식으로 정렬하세요. 콘텐츠에 따라 열의 크기를 조정하세요. 작은 콘텐츠에는 좁은 열을, 단락에는 넓은 열을 사용하세요.
  • 행: 행은 데이터 표현을 향상시키기 위해 텍스트, 버튼, 링크, 아이콘을 지원해야 합니다.
  • 데이터 없음: 빈 목록은 AdminConfigAreaEmptyList 컴포넌트를 사용하여 CTA 버튼과 라벨을 포함하여 사용자가 새 레코드 생성으로 유도되도록 해야 합니다.

:hammer_and_wrench: 구현

테이블이 모바일과 데스크톱에서 잘 작동하도록 해야 하는 작은 CSS 클래스 컬렉션이 있습니다.

<table> 요소에는 d-table 클래스가 적용되어야 합니다.

<thead> 요소에는 d-table__header 클래스가 적용되어야 합니다.

<tr> 요소에는 d-table__row 클래스가 적용되어야 합니다.

많은 설명 텍스트를 포함하는 <td> 요소(보통 가장 왼쪽 열)에는 d-table__cell --overview 클래스를 사용해야 합니다. 기타 모든 셀에는 d-table__cell --detail을 사용해야 합니다.

d-table__cell --overview 클래스가 있는 <td> 요소는 행에 해당하는 Edit/Show 페이지로 관리자를 직접 연결하는 링크로 내부 행 콘텐츠를 감쌀 수 있습니다. 이 링크는 이 구조를 따르고 d-table__overview-link CSS 클래스가 적용되어야 합니다. 이상적으로는 LinkTo 컴포넌트를 사용해야 하지만, getURL이 함께 사용되는 한 <a>도 괜찮습니다.

여기서 이름 부분에 d-table__overview-name 클래스가 적용되어야 하지만, 설명에는 적용되지 않아야 합니다.

<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> 요소에는 d-table-cell --controls CSS 클래스가 적용되어야 합니다. 이렇게 하면 버튼이 정렬됩니다. 각 버튼에는 btn-small 클래스도 적용되어야 합니다.

모바일의 경우, d-table-cell --overview를 제외한 각 <td> 요소에는 해당 열의 <th>와 동일한 I18n 라벨을 포함하는 d-table__mobile-label 클래스가 있는 <div>를 포함해야 합니다:

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

이것은 모바일에서 테이블 행을 더 읽기 쉬운 카드 기반 형식으로 표시합니다:

[...] 드롭다운 메뉴의 경우, DMenu를 DropdownMenu와 함께 사용해야 합니다. 다음은 예제입니다:

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

테이블 행의 토글은 DToggleSwitch 컴포넌트를 사용하여 처리됩니다:

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

모든 것을 합쳐서 여기는 관리자 테이블의 최소 예제입니다:

 <table class="d-table">
    <thead class="d-table__header">
      <tr>
        <th>Name</th>
        <th>Description</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">Example Item</span>
            <span class="d-table__overview-about">A short description</span>
          </LinkTo>
        </td>
        <td class="d-table__cell --detail">
          <span class="d-table__mobile-label">Description</span>
          Some detail content here
        </td>
        <td class="d-table__cell --controls">
          <div class="d-table__cell-actions">
            <button class="btn btn-default btn-small">Edit</button>
          </div>
        </td>
      </tr>
    </tbody>
  </table>

5.e 3차 라우트

3차 라우트는 설정 영역에서만 도달할 수 있는 라우트입니다. 이들은 플래그와 같은 편집/신규 라우트의 형태를 띠는 경우가 많습니다:

대부분의 경우 FormKit를 사용하는 양식이 여기에 배치됩니다.

이것을 위해 표준 RESTful 라우트를 사용하세요:

Action Path
New <resource>/new
Edit <resource>/:id/edit

그리고 라우트가 백엔드에서도 라우팅되도록 하세요. (신규 또는 편집 페이지를 새로 고침해도 오류가 발생하지 않아야 합니다.)

:art: 디자인

사용법

  • 주 라우트 또는 테이블 내에서 인라인 양식을 갖는 것보다 이러한 3차 라우트를 갖는 것이 좋습니다. 독립적인 편집 및 신규 라우트가 가장 좋습니다. 쉽게 링크할 수 있기 때문입니다.
  • 페이지 UI의 상단 부분(브레드크럼, 페이지 헤더 및 서브헤더)을 표시하지 마세요.
  • 대신, 관리자가 주요 설정 영역으로 돌아가도록 허용하는 단일 “X로 돌아가기” 링크를 표시하세요.
  • 페이지의 콘텐츠는 최소 하나의 AdminConfigAreaCard로 감싸야 합니다.
  • 페이지의 모든 부제목은 설정 영역 카드로 수행되어야 합니다.

:hammer_and_wrench: 구현

페이지 상단에 배치하여 뒤로 갈 수 있는 간단한 BackButton 컴포넌트가 있습니다:

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

6. 필터링된 설정 구성 페이지

우리 관리자 인터페이스의 설정 페이지 중 많은 부분은 필터링된 사이트 설정의 간단한 목록입니다. 이를 통해 관리자는 /admin/config/about/와 같은 더 전문적인 설정 페이지를 만들 때까지 전체 “모든 사이트 설정” 목록에 압도되지 않고 관련 설정 그룹을 찾을 수 있습니다.

:hammer_and_wrench: 구현

이러한 라우트 중 하나를 추가하려면 몇 가지 사항이 필요합니다. 먼저, site_settings.yml의 최상위 키인 사이트 설정의 전체 category(예: branding:)를 표시하거나 설정 area를 사용할 수 있습니다.

사이트 설정은 여러 areas에 존재할 수 있으며, 같은 페이지에 하나 이상을 표시할 수 있습니다.

  1. adminConfig 아래에 관리자 라우트 맵에 라우트를 추가하세요. 예를 들어:
this.route("trustLevels", { path: "/trust-levels" }, function () {
  this.route("settings", {
    path: "/",
  });
});
  1. 새로운 라우트 .js 파일을 추가하세요. 파일은 새로운 라우트의 이름에 따라 frontend/discourse/admin/routes/admin-config/localization.js와 같은 경로와 일치해야 합니다. 이것은 AdminConfigWithSettingsRoute를 상속하고 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. 컨트롤러를 추가하세요. 이것은 주로 설정 검색 및 필터링을 활성화하기 위한 것입니다. AdminAreaSettingsBaseController를 상속해야 합니다:
import AdminAreaSettingsBaseController from "discourse/admin/controllers/admin-area-settings-base";

export default class AdminConfigLocalizationSettingsController extends AdminAreaSettingsBaseController {}
  1. 마지막으로, .gjs 형식의 라우트 템플릿 파일을 frontend/discourse/admin/templates/admin-config/localization/settings.gjs와 같은 경로에 추가하세요. 여기에는 정상적인 DPageHeader와 브레드크럼이 포함되어야 하지만, 설정을 표시하려면 AdminAreaSettings가 필요합니다.
<div class="admin-config-page__main-area">
  <AdminAreaSettings
    @showBreadcrumb={{false}}
    @area="localization"
    @path="/admin/config/localization"
    @filter={{@controller.filter}}
    @adminSettingsFilterChangedCallback={{@controller.adminSettingsFilterChangedCallback}}
  />
</div>

여기서 변경해야 하는 중요한 사항은 @path와 @area(또는 대체로 @categories)입니다. 앞서 언급했듯이, 표시하려는 사이트 설정 영역 또는 카테고리로 채워 넣으세요.

7. 일반 가이드라인

  • URL 슬러그는 단어 내 공백을 나타내기 위해 언더스코어(_) 대신 하이픈(-)을 사용해야 합니다.

  • 관리자 인터페이스의 모든 텍스트는 여기에概述된 텍스트 서식 가이드라인을 따라야 합니다:

8. 플러그인

일부 플러그인은 사이트 설정의 컬렉션만 갖는 것이 아니라 플러그인에 대한 심층적인 구성 UI(예: AI, 자동화, 게이미피케이션)가 필요합니다. 예를 들어, 여기는 Discourse AI입니다:

이것을 사용하는 플러그인의 몇 가지 예시는 다음과 같습니다:

:art: 디자인

사용법

  • 독립적인 플러그인 UI를 만들 때 일반 관리자 UI 가이드라인을 따라야 합니다.

:hammer_and_wrench: 구현

Ember 라우팅

  • 모든 라우트 템플릿은
    admin/assets/javascripts/discourse/templates/admin-plugins/show/ 아래에 있어야 합니다.
  • 모든 라우트 js 파일은 admin/assets/javascripts/discourse/routes/ 아래에 있어야 하며
    admin-plugins-show- 접두사가 붙어야 합니다.
  • 관리자 라우트 맵은 admin-PLUGIN-NAME-plugin-route-map.js와 같은 파일에 있어야 합니다.
  • 라우트 맵은 다음과 같은 구조를 가져야 합니다. 중요한 부분은
    resource로 admin.adminPlugins.show를 사용한다는 것입니다.
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" });
    });
  },
};
  • 이것이 어떻게 작동하는지에 대한 현재 예제는 Discourse AI 플러그인에서 볼 수 있으며, /admin/plugins/discourse-ai/ai-personas로 이동하면 됩니다.
  • 하위 라우트를 정의하지 않는 "상위
10개의 좋아요

그리고

여전히 작동하지 않습니다. 두 번째 것은 -24 대신 -23이라고 생각합니다

5개의 좋아요

드디어 메타에 올라온 걸 보니 정말 기쁩니다. 몇 달간의 노력이 투입되었고, 이를 통해 관리자 화면의 모든 페이지에서 UI와 내비게이션을 표준화할 계획입니다.

아예 목차를 제거하고 discotoc에만 의존하는 게 어떨까요? 그렇게 하면 더 안정적일 것 같긴 하지만, 게시물 상단에 목차가 표시되는 걸 좋아하긴 합니다.

7개의 좋아요

고맙습니다 @Moin - 모두 수정했습니다!

해당 변경 사항을 적용했습니다. 그렇지 않으면 단순히 중복된 목차 표가 되기 때문입니다.

4개의 좋아요

게시물이 새 주제로 분리되었습니다: 사용자 관리 화면에서 브라우저 탭에 사용자 이름 표시