قالب داشبورد (DashboardPage)
شاخصها و نمودارها در یک بازهٔ زمانی — انتخابگر بازه در سرِ صفحه، ردیف شاخص بی نقطهٔ شکست، و بخشهای نمودار با یک ارتفاع
معرفی
DashboardPage قالب صفحهٔ شاخص و نمودار با بازهٔ زمانی است. همهٔ عددهای چیدمان داشبورد در قالب است:
- عرض پهن 1600 پیکسل (
wide)، یا بیسقف (full)؛ - انتخابگر بازه (
period) اولین کنترل اقدامهای سرِ صفحه؛ - تا 4 فیلتر کل داشبورد (
filters) در نوارابزار؛ برای فیلترهای بیشتر یا دارای شمارش،filterPanelدر ستون دومِ آزاد قاب؛ کنار ناوبری بخش، نوار افقی و در عرض کم Sheet؛ - ردیف شاخصها (
kpis): هر کاشی دستکم--layout-tile-min-width(256 پیکسل) و کشآمده تا ردیف پر شود — بی نقطهٔ شکست. ستونها از شمار کارت میآیند و ردیف آخر هرگز یک کارت یتیم نیست: 3 یا 4 کارت در یک ردیف، 5 کارت 3 + 2 (از عرض 86rem یک ردیف)، 6 کارت 3 + 3، 7 کارت 4 + 3 و 8 کارت 4 + 4 با کارتهای پهنتر در ردیف آخر؛ این قاعده فقط برای شاخصهاست و فید پست و شبکهٔ کارت مجموعهها را عوض نمیکند؛ - بخشهای نمودار (
DashboardSection): نمودارها در شبکهای با کمترین عرض--layout-chart-min-width(448 پیکسل) — دو نمودار در عرض پیشفرض، سه در عرض پهن، یکی روی موبایل؛ - هر نمودار (
DashboardChart) در یکChartCardبا ارتفاع ثابت--layout-chart-height(288 پیکسل)، با حالتهای بارگذاری، خطا و خالی خودش در ناحیهٔ نمودار.
چه زمانی استفاده کنیم:
- صفحهٔ خلاصه با شاخصها و نمودارها در یک بازهٔ زمانی: داشبورد اصلی، خلاصهٔ یک کمپین.
چه زمانی استفاده نکنیم:
- فهرست قابلفیلتر موجودیتها:
ListPage. - صفحهٔ یک موجودیت با چند نمودار دربارهٔ همان موجودیت:
DetailPageباDashboardChartها در یکDetailSection.
استفاده
'use client'
import * as React from 'react'
import {
MetricCard,
MetricCardContent,
MetricCardHeader,
MetricCardLabel,
MetricCardValue,
PartoBarChart,
DateRangePicker,
formatNumber,
resolveDateRangePreset,
type DateRangeValue,
} from '@partodata/ui'
import { DashboardChart, DashboardPage, DashboardSection } from '@partodata/ui/templates'
const byPlatform = [
{ ماه: 'فروردین', اینستاگرام: 3200, تلگرام: 980 },
{ ماه: 'اردیبهشت', اینستاگرام: 3650, تلگرام: 1140 },
]
export default function DashboardHome() {
// A new dashboard starts on «ماه گذشته».
const [period, setPeriod] = React.useState<DateRangeValue | undefined>(() => resolveDateRangePreset('30d'))
return (
<DashboardPage
title="داشبورد"
description="خلاصهٔ گفتوگوهای برند"
period={<DateRangePicker value={period} onChange={setPeriod} />}
kpis={
<MetricCard>
<MetricCardHeader>
<MetricCardLabel>کل منشنها</MetricCardLabel>
</MetricCardHeader>
<MetricCardContent>
<MetricCardValue>{formatNumber(12480)}</MetricCardValue>
</MetricCardContent>
</MetricCard>
}
>
<DashboardSection title="روند گفتوگو">
<DashboardChart title="منشنها به تفکیک پلتفرم">
<PartoBarChart data={byPlatform} keys={['اینستاگرام', 'تلگرام']} indexBy="ماه" legend />
</DashboardChart>
</DashboardSection>
</DashboardPage>
)
}نمودار داخل DashboardChart ارتفاع خودش را ندارد و ناحیهٔ نمودار را پر میکند؛ عدد ارتفاع (h-64، height={300})
ننویسید.
حالتها و انواع
جای اقدامها
period همیشه اولین اقدام سرِ صفحه است. اقدام اصلی و اقدامهای ثانوی قاعدهٔ ListPage را دارند: با filters در
انتهای نوارابزار، بی آن در انتهای سرِ صفحه؛ اقدامی که کاربر اجازهاش را ندارد
GatedAction است (غیرفعال با دلیل، هرگز پنهان).
وضعیت بازه و فیلترها
بازه (period) و فیلترها وضعیت جزءاند (React.useState در همان کامپوننتی که قالب را رندر میکند) یا، وقتی نمای داشبورد باید
با پیوند به اشتراک گذاشته شود، با useViewParams در نشانی میروند (range: periodParam('30d')، tab، فیلترها؛
هوک): مثل ListPage، نه با useSearchParams، useFilterParams/FilterProvider و
history.replaceState خودتان (قاعدهٔ ESLint parto/page-template).
زبانهها
داشبوردی که بخشهایش صفحههای خودشاناند — یک مرکز عملیات («اکنون»، «رخدادها»، «کارها»)، گزارشی با چند نما — tabs
میگیرد: زیر سرِ صفحه، هر زبانه پیوند با نشانی خودش (یک بخش مسیر، /ops/incidents)، و زبانهٔ جاری از pathname قاب.
هر صفحهٔ زبانه همین DashboardPage را با همین tabs رندر میکند. داشبوردی که خودش تازه میشود state را با
pageState({ …, live }) میسازد (دادهٔ زنده): نشانگر «آخرین بهروزرسانی» پیش از بازه
مینشیند.
نمودار پهن و جدول
span="full" نمودار را در کل ردیف بخش میگذارد. جدول یا فهرستی که در یک کارت داشبورد است height="content" میگیرد:
بهاندازهٔ محتوا، بی حاشیهٔ داخلی.
حالتها
state روی DashboardPage (با pageState({ data, isLoading, error, onRetry })؛ isEmpty اگر دورهای بیداده حالت
خالی است) کل محتوا را عوض میکند (در بارگذاری: اسکلت ردیف شاخص و نمودارها، با یک اعلام). وقتی دورهٔ دیگری بارگذاری
میشود، شاخصها و نمودارهای روی صفحه کمرنگ میمانند تا دادهٔ تازه برسد. state روی یک
DashboardChart فقط ناحیهٔ همان نمودار را: کارت و عنوانش میمانند و عنوان حالت، سرعنوانی جدا از عنوان کارت نیست.
جدول یا فهرستی که در کارت داشبورد است DashboardChart height="content" با state خودش است، نه PageState داخل
Card.
راهنمای استفاده
بکنید
- شاخصها را
MetricCardکنید و درkpisبدهید؛ چیدمان ردیف را قالب میسازد. - هر نمودار را در یک
DashboardChartبگذارید و نمودارهای مرتبط را در یکDashboardSectionکنار هم. - اعداد شاخص را با
formatNumberیاformatLargeNumber(n, 'fa')بنویسید.
نکنید
- برای ردیف شاخصها
grid-cols-*با نقطهٔ شکست (sm:،lg:،xl:) ننویسید. - نمودار را در
Cardیاdivدستساز با عنوان خودتان نپیچید، و ارتفاع نمودار را عدد ندهید. - انتخابگر بازه را در نوار بالای قاب یا داخل یک کارت نگذارید؛ جایش
periodاست. - بازه یا فیلترها را در نشانی صفحه نگذارید؛
React.useStateصفحهاند.
Props
DashboardPage
DashboardSection
DashboardChart
دسترسیپذیری
- هر نمودار Parto
ariaLabelمیگیرد؛ آن را جملهای کامل بنویسید («منشنها به تفکیک پلتفرم در چهار ماه اخیر»). - ترتیب سرعنوانها نمیپرد: عنوان صفحه
h1، ردیف شاخصها زیر سرعنوان پنهان «شاخصها» (h2، برچسب هر شاخصh3)، بخش عنواندار یک ناحیهٔ نامدار با عنوانh2، و عنوان هر نمودار سرعنوانی یک سطح پایینتر (h3) که نام ناحیهٔ (region) کارت نمودار است. - حالتهای بلوک (بارگذاری کل داشبورد، و خالی) در یک ناحیهٔ
statusمؤدب اعلام میشوند که همیشه در صفحه است؛ خطاrole="alert"خودش را دارد. متن حالتهای هر نمودار به زبان صفحه (localeقالب) است.
کامپوننتهای مرتبط
MetricCard— کاشی هر شاخص.ChartCard— کارتی کهDashboardChartروی آن ساخته شده.DateRangePicker— انتخابگر بازه درperiod، با بازههای آماده.PeriodSelector— فقط در سرِ یک کارت نمودار (actionsدرDashboardChart).
پنل فیلتر و دورهٔ مقایسه
filterPanel همان نوع ListPageFilterPanel است: سایدبار فیلتر در ستون دوم قاب، با همهچیز داخلش (شمار و «پاک کردن همه»، چیپهای activeFilters، نشانگر بخشها) و بی دکمهٔ «فیلترها» در نوار ابزار. با collapsible: true کاربر ستون را با «بستن فیلترها» یا Ctrl+B میبندد و از زبانهٔ «فیلترها» در خود قاب برمیگرداند. نقش سایدبار دوم میتواند بین صفحههای یک محصول متفاوت باشد؛ در همین صفحه فقط ناوبری یا فیلتر دارد. ستون آزاد پنل را میگیرد؛ اگر ناوبری همین صفحه ستون را اشغال کرده یا ستون در دسترس نباشد، بخشها در نوار افقی بالای محتوا هستند و هر عنوان Popover گزینهها را باز میکند؛ زیر عرض محتوای 36rem، کنترل «فیلترها» همان پنل را در Sheet بومی باز میکند. وضعیت فیلتر در صفحه میماند؛ filters و filterPanel را همزمان ندهید.
<DashboardPage title="نمای کلی" filterPanel={{ panel: <OverviewFilters />, activeCount: activeFilters }}>
<DashboardSection title="روند انتشار">
<DashboardChart title="انتشار روزانه" description="1 تا 30 مهر در برابر 1 تا 30 شهریور">
<PartoAreaChart
data={dailyData}
dataKeys={['current', 'previous']}
seriesStyles={{ previous: { color: 'var(--foreground-lighter)', strokeDasharray: '5 4', fillOpacity: 0 } }}
/>
</DashboardChart>
</DashboardSection>
</DashboardPage>توضیح نمودار و comparisonLabel رشد باید از دورهٔ واقعی داده بیایند؛ «دورهٔ قبل» را از درصد تغییر استنباط نکنید. سربرگ نمودار خودش فاصلهٔ عنوان، توضیح و اقدامها را مدیریت میکند.
قالب صفحهٔ تنظیمات (SettingsPage)
تنظیمات در گروههای مستقل — هر گروه یک بخش با عنوان، ردیفهای برچسبکنارکنترل و نوار ذخیرهٔ خودش
قالب صفحهٔ کمکی (UtilityPage)
صفحهای که محتوای خودش را ندارد — پیدا نشد، دسترسی ندارید، خطا، خالیِ اولکار، بهروزرسانی — با یک عنوان، یک توضیح و حداکثر یک اقدام در مرکز قاب