پرتوپرتو

فید فعالیت (ActionTimeline)

فید زمانی رویدادها و اقدامات — عملیات Booster، رویدادهای چرخه‌عمر تحلیل، لاگ audit — با markerهای وضعیتی، متادیتای نسبی/مطلق، گروه‌بندی روزانه، و پشتیبانی از پیش‌نمایش و اکشن‌های inline.

معرفی

ActionTimeline یک لیست زمانی از رویدادها است. هر آیتم یک مارکر با آیکون وضعیت، یک عنوان (subject + verb + object)، یک timestamp نسبی، و به‌صورت اختیاری پیش‌نمایش متنی (مثل محتوای کامنت)، تگ دسته‌بندی، و دکمه‌های action دارد. از سه پنل audit شده استخراج شد:

  • Booster — لاگ عملیات per-worker (لایک، کامنت، فالو، ...)
  • کامنت‌سنج — رویدادهای چرخه‌عمر تحلیل (شروع، اتمام، خطا)
  • ارزیابی — audit log اجرای ارزیابی‌ها

چه زمانی استفاده کنیم:

  • فید فعالیت‌های اخیر در داشبورد
  • Audit trail یک entity (مثل تاریخچه‌ی یک worker یا کمپین)
  • Activity tab داخل یک Drawer/Dialog جزئیات
  • لاگ real-time رویدادهای سیستم (با aria-live از بیرون)

چه زمانی استفاده نکنیم:

  • برای نمایش مراحل یک pipeline از StatusFlow استفاده کنید (رویداد نیست، stage است)
  • برای توییت/پست از PostCard استفاده کنید
  • برای لیست notification از NotificationCenter استفاده کنید (محور: mark-as-read, dismiss, filter)
  • اگر همه‌ی آیتم‌ها هم‌نوع و بدون timestamp معنادار هستند، یک <ul> ساده با DataTable کفایت می‌کند
  1. worker_12 کامنتی روی پست @news_channel گذاشتکامنت
    «خیلی ممنون بابت این توضیحات، کار شما ارزشمنده»
  2. worker_08 پست @tech_weekly را لایک کردلایک
  3. worker_03 هنگام فالو کردن @cafe_lux خطا گرفتفالو

    challenged → نیاز به ورود مجدد

  4. worker_17 در صف لایک ۳ پستلایک
  5. worker_05 نرخ rate-limit بالا گزارش دادسیستم

    کمپین موقتاً متوقف شد

زمین بازی

با تغییر تنظیمات زیر، پیش‌نمایش زنده را مشاهده کنید.

زمین بازی
  1. نظر جدید ثبت شد
  2. در حال تحلیل لایک‌ها
  3. گزارش هفتگی صادر شد
تنظیمات
داده
3
کد این نمونه به‌صورت خودکار قابل تولید نیست — برای کد آماده‌ی copy/paste به بخش «استفاده» در بالای صفحه مراجعه کنید.

استفاده

data-driven (پیش‌فرض)

import { ActionTimeline } from '@parto-system-design/ui'

export function RecentActivity({ events }) {
  return (
    <ActionTimeline
      items={events.map((e) => ({
        id: e.id,
        status: e.outcome, // 'success' | 'failed' | 'pending' | 'warning' | 'info'
        title: e.summary,
        description: e.detail,
        preview: e.commentText, // snippet shown in a muted box
        tag: e.type, // 'Instagram', 'AI', ...
        timestamp: e.createdAt, // Date | ISO string | epoch ms
      }))}
    />
  )
}

composition

<ActionTimeline>
  <ActionTimelineItem id="a" status="success" title="ورود worker موفق" timestamp={Date.now() - 60_000} />
  <ActionTimelineItem id="b" status="pending" title="در حال warmup" timestamp={Date.now()} tag="warmup" />
</ActionTimeline>
  1. worker_01 وارد سیستم شدلاگین
  2. worker_01 در حال گرم‌سازیwarmup

    روز ۳ از ۷ دوره warmup

گروه‌بندی روزانه

  1. امروز
  2. تحلیل کامنت‌های پست ۱۲۳ تکمیل شدتحلیل
  3. احمدی برچسب «منتقد سازنده» را به کامنت افزودبرچسب
  4. دیروز
  5. کمپین بوستر فالو تکمیل شدبوستر

    ۲۵۰ از ۲۵۰ موفق

  6. ایمپورت اکسل با خطا مواجه شدایمپورت

    ستون دوم ناسازگار

  7. ۱۸ خرداد ۱۴۰۵
  8. ارزیابی ۸ پیج ورزشی اجرا شدارزیابی

با groupBy="day" هدرهای sticky روزانه ظاهر می‌شوند — «امروز»، «دیروز»، یا تاریخ کامل (Jalali برای fa/ar، گریگوری برای en). آیتم‌ها باید به ترتیب نزولی timestamp مرتب شده باشند (ActionTimeline خودش مرتب نمی‌کند).

چگالی (density)

compact

  1. رویداد اول
  2. رویداد دوم
  3. رویداد سوم

default

  1. رویداد اول
  2. رویداد دوم
  3. رویداد سوم

spacious

  1. رویداد اول
  2. رویداد دوم
  3. رویداد سوم
  • compact — مناسب sidebar یا لیست متراکم inside drawer
  • default — متن عادی، برای فیدهای داشبورد
  • spacious — در صفحات اختصاصی audit با پیش‌نمایش‌های طولانی

پنج وضعیت canonical

ActionStatusKey: success | failed | pending | warning | info

این‌ها سبک‌تر از JobStatusKey هستند چون یک event اتمیک است (چیزی مثل «paused» برای یک event خاص معنا ندارد). با توکن‌های --sentiment-positive، --destructive-default، --brand-default، --warning-default، و --foreground-lighter map می‌شوند.

اکشن‌های inline

  1. کمپین بوستر ناموفقبوستر

    خطا در احراز هویت ۳ worker

  2. تحلیل تکمیل شد — ۸۷۰ کامنتتحلیل

actions یک slot جانبی است که در انتهای ردیف نمایش داده می‌شود. کلیک روی این slot propagate نمی‌شود — بنابراین وقتی onItemSelect هم تنظیم است، هندلر row trigger نمی‌شود. مناسب «تلاش مجدد»، «مشاهده گزارش»، «پنهان کردن».

حالت خالی

  1. هیچ رویدادی ثبت نشده است

وقتی items خالی یا تعریف‌نشده است، یک متن پیش‌فرض («هیچ رویدادی ثبت نشده») نشان داده می‌شود. با emptyState می‌توانید نود دلخواه جایگزین کنید (مثل یک <Empty> با illustration).

Props

ActionTimeline

Prop

Type

ActionTimelineItemData

Prop

Type

راهنمای استفاده

بکنید

  • آیتم‌ها را مرتب‌شده نزولی بر اساس timestamp پاس دهید — ActionTimeline خودش مرتب نمی‌کند - برای feed طولانی از limit استفاده کنید و pagination/scroll-infinite را در والد بزنید - tag را برای دسته‌بندی اولیه استفاده کنید (نوع action، پلتفرم) — کوتاه نگه دارید (۱-۲ کلمه) - preview برای متن کامنت یا پیام خطا ایده‌آل است — باعث می‌شود کاربر بدون کلیک کانتکست کامل بگیرد - در feed زنده، پس از اضافه شدن آیتم جدید، root را aria-live="polite" بگذارید تا screen reader announce کند

نکنید

  • ActionTimeline را برای stepها/pipeline استفاده نکنید — StatusFlow این کار را بهتر می‌کند - preview را برای محتوای خیلی بلند پر نکنید؛ اگر ۳+ خط است، row را interactive کنید تا کاربر با کلیک به detail برود - بیش از ۳-۴ actions در actions slot نگذارید — از dropdown menu استفاده کنید - groupBy="day" را با density="compact" ترکیب نکنید روی لیست کوتاه — هدرها overhead می‌شوند

دسترسی‌پذیری

  • Root <ol> با data-density + data-group-by
  • هر آیتم <li> با aria-label="{statusLabel}: {title}" — screen reader وضعیت + عنوان را در کنار هم اعلام می‌کند
  • timestamp در <time dateTime={ISO}> با title absolute (هاور tooltip نشان می‌دهد Jalali کامل)
  • مارکرها aria-hidden هستند (اطلاعات در aria-label و متن تکرار شده)
  • spinner روی status pending با motion-safe:animate-spin — prefers-reduced-motion safe
  • وقتی onItemSelect تنظیم باشد، بدنه‌ی آیتم به <button> تبدیل می‌شود با focus ring
  • actions slot با onClick={e.stopPropagation()} wrapped — کلیک دکمه‌ها trigger row نمی‌کند

کامپوننت‌های مرتبط

  • StatusFlow — برای نمایش مرحله‌های یک pipeline نه event history
  • NotificationCenter — اگر آیتم‌ها mark-as-read و dismiss دارند
  • JobCard — برای هر job احتمالاً یک «تاریخچه‌ی اقدامات» داخلی می‌خواهید؛ ActionTimeline درون آن قرار می‌گیرد
  • PostCard — برای نمایش پست کامل، نه event atomic