# Dashboard

`Dashboard` 元件為 blocklet 應用程式提供了一個預先建置、響應式的佈局，通常用於管理介面或以使用者為中心的視圖。它透過解析 blocklet 的元資料，自動建構一個包含側邊欄、頁首和主要內容區域的標準儀表板。此元件顯著減少了建構通用應用程式結構所需的樣板程式碼。

該佈局由三個主要部分組成：一個用於導覽的常駐側邊欄、一個用於全域操作和使用者資訊的頁首，以及一個呈現特定頁面內容的主要內容區域。

<!-- DIAGRAM_IMAGE_START:architecture:16:9:1765962229 -->
![Dashboard](assets/diagram/dashboard-diagram-0.zh-TW.jpg)
<!-- DIAGRAM_IMAGE_END -->

## 基本用法

若要使用 `Dashboard` 元件，只需將您的頁面內容包裹在其中即可。該元件將自動在您的內容周圍呈現頁首和側邊欄。

```javascript MyDashboard.jsx icon=logos:react
import Dashboard from '@arcblock/blocklet-ui-react/lib/Dashboard';

export default function MyDashboardPage() {
  return (
    <Dashboard>
      <h1>Welcome to the Dashboard</h1>
      <p>This is your main content area.</p>
    </Dashboard>
  );
}
```

傳遞給 `Dashboard` 元件的 children 將顯示在主要內容區域中。

## 屬性 (Props)

`Dashboard` 元件接受以下屬性 (props) 以自訂其行為和外觀。

<x-field-group>
  <x-field data-name="children" data-type="React.ReactNode" data-required="true">
    <x-field-desc markdown>要在儀表板佈局的主要內容區域內呈現的內容。</x-field-desc>
  </x-field>
  <x-field data-name="meta" data-type="object" data-required="false">
    <x-field-desc markdown>一個 blocklet 元資料物件。若提供，它將與預設的 `window.blocklet` 元資料合併並覆寫。這對於測試或動態更改 blocklet 資訊很有用。</x-field-desc>
  </x-field>
  <x-field data-name="fallbackUrl" data-type="string" data-required="false" data-default="publicPath">
    <x-field-desc markdown>如果目前已驗證的使用者根據其角色無權存取任何導覽連結，則重新導向到的 URL。設定為 `null` 可停用此自動重新導向。</x-field-desc>
  </x-field>
  <x-field data-name="invalidPathFallback" data-type="function" data-required="false">
    <x-field-desc markdown>當前 URL 路徑不符合任何可用導覽連結時執行的回呼函式。預設行為是重新導向到第一個可用的連結。</x-field-desc>
  </x-field>
  <x-field data-name="headerAddons" data-type="React.ReactNode | function" data-required="false">
    <x-field-desc markdown>允許自訂頁首右側的附加元件。如果提供一個節點，它將取代所有預設的附加元件。如果提供一個函式，它會接收預設的附加元件陣列作為參數，讓您可以新增、移除或重新排序它們。</x-field-desc>
  </x-field>
  <x-field data-name="sessionManagerProps" data-type="object" data-required="false">
    <x-field-desc markdown>直接傳遞給頁首底層 `SessionUser` 元件的 props。這允許自訂使用者會話選單，例如 `showRole` 或定義自訂的 `onLogout` 處理常式。</x-field-desc>
  </x-field>
  <x-field data-name="links" data-type="array | function" data-required="false">
    <x-field-desc markdown>允許以程式化方式修改側邊欄導覽連結。如果提供一個陣列，其項目將附加到從元資料生成的連結中。如果提供一個函式，它會接收元資料生成的連結作為參數，並應返回一個新的連結陣列。</x-field-desc>
  </x-field>
  <x-field data-name="showDomainWarningDialog" data-type="boolean" data-required="false" data-default="true">
    <x-field-desc markdown>若為 `true`，則在從不受信任的網域存取應用程式時顯示警告對話方塊。</x-field-desc>
  </x-field>
</x-field-group>

## 運作方式

`Dashboard` 元件被設計為「設定驅動」，其結構和內容主要來自 blocklet 的元資料檔案 (`blocklet.yml`)。

### 透過元資料產生導覽

側邊欄導覽是根據您 `blocklet.yml` 中的 `navigation` 陣列自動產生的。該元件會特別尋找其 `section` 屬性中包含 `dashboard` 的導覽項目。

以下是如何定義儀表板導覽的範例：

```yaml blocklet.yml icon=mdi:file-document
navigation:
  - title: 'Home'
    link: '/'
    section: 'dashboard'
    icon: 'mdi:home'
    role: ['owner', 'admin', 'guest']
  - title: 'Analytics'
    link: '/analytics'
    section: 'dashboard'
    icon: 'mdi:chart-bar'
    role: ['owner', 'admin']
  - title: 'Settings'
    link: '/settings'
    section: 'dashboard'
    icon: 'mdi:cog'
    role: ['owner']
    items:
      - title: 'Profile'
        link: '/settings/profile'
      - title: 'Billing'
        link: '/settings/billing'
```

### 角色型存取控制

`Dashboard` 元件對導覽連結強制執行角色型存取控制 (RBAC)。每個導覽項目都可以有一個 `role` 屬性，這是一個允許查看該連結的角色陣列。

- 如果導覽項目沒有 `role` 屬性，則所有人皆可見。
- 如果目前使用者未經驗證，他們只能看到包含 `guest` 角色的項目。
- 如果目前使用者已驗證，元件會將其 `user.role` 與每個導覽項目的 `role` 陣列進行比較。只有在匹配的情況下，該項目才會顯示。
- 只有在父導覽項目至少有一個子項目可見時，該父項目才可見。

使用上面的 `blocklet.yml` 範例：
- 具有 `guest` 角色的使用者只會看到「Home」連結。
- 具有 `admin` 角色的使用者將看到「Home」和「Analytics」。
- 具有 `owner` 角色的使用者將看到所有連結，包括「Settings」下的巢狀「Profile」和「Billing」連結。

### 圖示

導覽項目的 `icon` 屬性應為一個字串，對應於 [Iconify](https://icon-sets.iconify.design/) 圖示庫中的圖示名稱（例如 `mdi:home`）。您也可以提供一個指向圖片檔案的完整 URL。

## 自訂

雖然 `Dashboard` 設計為可透過元資料開箱即用，但它也提供了幾個屬性以進行更進階的自訂。

### 自訂頁首附加元件

您可以使用 `headerAddons` 屬性修改預設的頁首附加元件（例如，主題切換、語系選擇器、會話管理器）。透過傳遞一個函式，您可以新增元素或重新排列現有元素。

```javascript CustomHeader.jsx icon=logos:react
import Dashboard from '@arcblock/blocklet-ui-react/lib/Dashboard';
import Button from '@mui/material/Button';

function MyCustomButton() {
  return <Button color="inherit" onClick={() => alert('Help!')}>Help</Button>;
}

export default function CustomDashboard() {
  return (
    <Dashboard
      headerAddons={(existingAddons) => {
        const customAddon = <MyCustomButton key="custom-help" />;
        // Add the custom button before the other addons
        return [customAddon, ...existingAddons];
      }}
    >
      <p>Dashboard with a custom header button.</p>
    </Dashboard>
  );
}
```

### 以程式化方式新增連結

`links` 屬性允許您從程式碼中動態新增或修改側邊欄導覽連結。這對於依賴應用程式狀態的連結很有用。

```javascript DynamicLinks.jsx icon=logos:react
import Dashboard from '@arcblock/blocklet-ui-react/lib/Dashboard';
import Icon from '@arcblock/ux/lib/Icon';

const useFeatureFlag = () => {
  // 在實際應用程式中，這裡會檢查功能旗標服務
  return true;
};

export default function DynamicDashboard() {
  const isBetaFeatureEnabled = useFeatureFlag();

  return (
    <Dashboard
      links={(existingLinks) => {
        if (isBetaFeatureEnabled) {
          const betaLink = {
            id: 'beta-feature',
            title: 'Beta Feature',
            url: '/beta',
            icon: <Icon name="mdi:test-tube" />,
            external: true, // 客戶端路由所需
          };
          return [...existingLinks, betaLink];
        }
        return existingLinks;
      }}
    >
      <p>This dashboard may have dynamic links.</p>
    </Dashboard>
  );
}

```

## 總結

`Dashboard` 元件是快速建構應用程式佈局的強大工具。透過利用 blocklet 元資料，它提供了一個開箱即用的、具備角色感知能力的結構化導覽系統。若需更基礎的佈局元件，請參閱 [Header](./components-layout-header.md) 和 [Footer](./components-layout-footer.md) 的文件。