فهرست وظیفهها (TaskList)
کانتینر kanban یا flat برای ops UI — گروهبندی، شمارش، renderItem آزاد
معرفی
TaskList یک کانتینر domain-agnostic برای گروهبندی هر نوع item است. از طریق groupBy(item) آیتمها bucket میشوند و توسط renderItem کارتها رندر میشوند — یعنی میتواند JobCard، PostCard، AlertRuleCard یا هر کارت سفارشی را نمایش دهد.
چه زمانی استفاده کنیم:
- داشبورد ops برای job pipeline (queued / running / done)
- moderation queue کامنتها (pending review / approved / rejected)
- task board ساده با kanban یا flat layout
چه زمانی استفاده نکنیم:
- اگر نیاز به drag-drop بین ستونها دارید —
TaskListصرفاً presentational است؛ DnD را در سطح consumer wire کنید - برای جدول داده — از
DataTableاستفاده کنید - برای infinite scroll feed — از
PostListاستفاده کنید
زمین بازی
با تغییر تنظیمات زیر، فهرست را بهصورت زنده مشاهده کنید.
استفاده
import { TaskList, type TaskListGroup } from '@parto-system-design/ui'
interface Task {
id: string
title: string
status: 'queued' | 'running' | 'done'
}
const tasks: Task[] = [
/* ... */
]
const groups: TaskListGroup[] = [
{ id: 'queued', label: 'در صف', accent: '--sentiment-neutral' },
{ id: 'running', label: 'در حال اجرا', accent: '--brand-default' },
{ id: 'done', label: 'تکمیل شد', accent: '--sentiment-positive' },
]
;<TaskList
items={tasks}
groups={groups}
groupBy={(t) => t.status}
renderItem={(task) => <TaskCard task={task} />}
getItemKey={(task) => task.id}
/>حالتها و انواع
کانبان (پیشفرض)
<TaskList
variant="kanban"
items={tasks}
groups={groups}
groupBy={(t) => t.status}
renderItem={(t) => <JobCard {...t} />}
getItemKey={(t) => t.id}
/>Flat با sticky group headers
<TaskList
variant="flat"
items={tasks}
groups={groups}
groupBy={(t) => t.status}
renderItem={renderItem}
getItemKey={(t) => t.id}
/>Auto-derive groups (بدون groups prop)
<TaskList items={tasks} groupBy={(t) => t.status} renderItem={renderItem} getItemKey={(t) => t.id} />
// ستونها بر اساس مقادیر unique خود groupBy ساخته میشوندستون placeholder بدون آیتم
<TaskList
items={tasks}
groups={[
{ id: 'queued', label: 'در صف' },
{ id: 'running', label: 'در حال اجرا' },
{ id: 'done', label: 'تکمیل شد' },
{ id: 'archived', label: 'بایگانی', emptyState: <Empty>هیچ موردی بایگانی نشده</Empty> },
]}
groupBy={(t) => t.status}
renderItem={renderItem}
getItemKey={(t) => t.id}
/>بدون شمارش
<TaskList showCounts={false} {...rest} />راهنمای استفاده
بکنید
- برای ستونبندی پایدار،
groupsرا explicit پاس بدهید — auto-derive ترتیب را به document order متکی میکند - رنگ ستون را باaccentمرتبط با token معنادار set کنید (--status-warning،--sentiment-positive) - برای فید بسیار بلند، ازvariant="flat"استفاده کنید — kanban روی موبایل horizontal scroll میخواهد
نکنید
renderItemرا در render parent تعریف نکنید (memoize کنید) — هر تغییر state چندده کارت را re-render میکند - DnD بین ستونها را باdata-droppableخودِ کانتینر wire نکنید — کانتینر فقط presentational است؛ از library DnD بیرونی استفاده کنید - اگر آیتم بیشتر از ۲۰۰ تا است، یا virtualize کنید یا paginate
جدول ویژگیها
TaskListGroup
دسترسیپذیری
- هر ستون/گروه بهصورت
<section>باdata-group-idرندر میشود — landmark navigation معنادار است. - شمار آیتم با
aria-labelکامل (مثلاً «۳ مورد») تأمین میشود — screen reader هم عدد و هم suffix میخواند. - ترتیب tab روی renderItem-ها بستگی به محتوای کارت دارد — کارتها باید focus management خودشان را داشته باشند.
- variant
flatازposition: stickyبرای header استفاده میکند — keyboard scroll بهصورت طبیعی کار میکند.
کامپوننتهای مرتبط
- JobCard — کارتی که معمولاً درون TaskList رندر میشود (با status badge، progress، actions)
- PostList — برای فید پستهای پیوسته (نه گروهبندی-شده)
- ActionTimeline — برای تاریخچهی اجرای task، نه task pipeline
- DataTable — اگر data tabular است نه kanban
کارت کار (JobCard)
کارت canonical برای نمایش کار async — تحلیل، کمپین، ارزیابی، ایمپورت — با وضعیت، پیشرفت، متادیتا، آمار و خطا. Composition-based و status-aware.
کارت سلامت موجودیت (EntityHealthCard)
کارت canonical برای نمایش سلامت موجودیتهای long-lived — ورکرها، پیجهای رصدی، منابع داده — با روایت شدتبندی ۶سطحی، نمره، اعتماد، فاز، متریک و CTA.