Skip to main content

Background Tasks Components

3 Components

Pre-built React components for scheduling one-time and recurring tasks, viewing task status, and building cron expressions visually.

TaskScheduler

Schedule one-time and recurring cron tasks

TaskList

View and manage all task runs

CronBuilder

Visual cron expression builder

Installation

All task components are included in the SDK. Import them from @sylphx/sdk/react.

TaskScheduler

A comprehensive form component for triggering background tasks. Supports one-time runs, delayed triggers, and recurring cron schedules with a clean, intuitive interface.

Basic Usage

app/admin/tasks/new/page.tsx
import { TaskScheduler } from '@sylphx/sdk/react'

export default function NewTaskPage() {
  return (
    <TaskScheduler
      onSchedule={(run) => {
        console.log('Task triggered:', run.id)
      }}
    />
  )
}

Props

PropertyTypeDescription
onSchedulerequired(run: RunHandle) => voidCallback when task is successfully triggered
defaultTaskIdstringPre-select a task by ID
defaultPayloadobjectPre-fill the task payload
defaultMode"immediate" | "delayed" | "cron"= "immediate"Initial scheduling mode
allowedModesScheduleMode[]Limit available scheduling modes
tasksTaskHandle[]Task handles available for selection
showRetryConfigboolean= trueShow retry configuration options
showTimeoutConfigboolean= trueShow timeout configuration
maxRetriesnumber= 10Maximum allowed retry attempts
onError(error: Error) => voidCallback when triggering fails
onCancel() => voidCallback when user cancels
submitLabelstring= "Trigger Task"Custom submit button text
loadingboolean= falseShow loading state
disabledboolean= falseDisable the form
classNamestringAdditional CSS classes

Advanced Configuration

With tasks
import { TaskScheduler } from '@sylphx/sdk/react'
import { sendEmail, generateReport, processUpload } from '@/tasks'

<TaskScheduler
  tasks={[sendEmail, generateReport, processUpload]}
  onSchedule={(run) => console.log('Triggered:', run.id)}
/>

Type Safety

Pass your typed task handles to tasks. The scheduler will auto-generate payload form fields based on the task's payload type.

TaskList

A data table component for viewing, filtering, and managing task runs. Supports pagination, filtering by status, and bulk actions.

Basic Usage

app/admin/tasks/page.tsx
import { TaskList } from '@sylphx/sdk/react'

export default function TasksPage() {
  return (
    <TaskList
      title="Task Runs"
      onTaskClick={(run) => router.push(`/admin/tasks/${run.id}`)}
    />
  )
}

Props

PropertyTypeDescription
titlestring= "Tasks"Title displayed above the list
statusTaskRunStatus | TaskRunStatus[]Filter by task run status
taskIdstringFilter by task ID
limitnumber= 25Runs per page
showFiltersboolean= trueShow filter controls
showSearchboolean= trueShow search input
showPaginationboolean= trueShow pagination controls
showActionsboolean= trueShow action buttons (cancel, retry)
selectableboolean= falseEnable row selection for bulk actions
autoRefreshboolean= falseAuto-refresh list every 10 seconds
refreshIntervalnumber= 10000Auto-refresh interval in ms
columnsColumn[]Custom columns to display
onTaskClick(run: RunHandle) => voidCallback when task row is clicked
onCancel(run: RunHandle) => voidCallback when run is cancelled
onRetry(run: RunHandle) => voidCallback when run is retried
onBulkAction(action: string, runs: RunHandle[]) => voidCallback for bulk actions
emptyMessagestring= "No task runs found"Message when no runs found
loadingboolean= falseShow loading state
classNamestringAdditional CSS classes

TaskRunStatus Type

type TaskRunStatus =
  | 'pending'    // Run is queued, waiting to execute
  | 'running'    // Run is currently executing
  | 'completed'  // Run finished successfully
  | 'failed'     // Run failed after all retries
  | 'cancelled'  // Run was manually cancelled

Advanced Usage

Filtered by status
import { TaskList } from '@sylphx/sdk/react'

// Show only failed runs
<TaskList
  title="Failed Runs"
  status="failed"
  showFilters={false}
/>

// Show active runs (pending or running)
<TaskList
  title="Active Runs"
  status={['pending', 'running']}
  autoRefresh={true}
  refreshInterval={5000}
/>

// Show runs for a specific task
<TaskList
  title="Email Sends"
  taskId="send-email"
  showActions={true}
/>

Real-time Updates

Enable autoRefresh for dashboards that need to show live task run status. The component will poll for updates at the specified interval.

CronBuilder

A visual cron expression builder that makes it easy to create complex schedules without memorizing cron syntax. Includes a human-readable preview and next run times.

Basic Usage

components/schedule-picker.tsx
import { CronBuilder } from '@sylphx/sdk/react'

export function SchedulePicker() {
  const [cron, setCron] = useState('0 9 * * *')

  return (
    <CronBuilder
      value={cron}
      onChange={setCron}
    />
  )
}

Props

PropertyTypeDescription
valuerequiredstringCurrent cron expression
onChangerequired(cron: string) => voidCallback when expression changes
mode"simple" | "advanced"= "simple"UI mode - simple shows presets, advanced shows full editor
showPreviewboolean= trueShow human-readable description
showNextRunsboolean= trueShow next scheduled run times
nextRunCountnumber= 5Number of next runs to display
timezonestring= browser timezoneTimezone for display
showTimezoneboolean= trueShow timezone selector
presetsCronPreset[]Custom preset options
minIntervalnumber= 1Minimum interval in minutes
disabledFieldsCronField[]Disable specific fields (minute, hour, etc.)
onError(error: string) => voidCallback for validation errors
compactboolean= falseUse compact layout
disabledboolean= falseDisable the builder
classNamestringAdditional CSS classes

CronPreset Type

interface CronPreset {
  label: string        // Display name (e.g., "Every hour")
  value: string        // Cron expression (e.g., "0 * * * *")
  description?: string // Optional description
  icon?: ReactNode     // Optional icon
}

Built-in Presets

PresetExpressionDescription
Every minute* * * * *Runs every minute
Every hour0 * * * *Runs at the start of every hour
Daily at midnight0 0 * * *Runs every day at 00:00
Weekdays at 9am0 9 * * 1-5Runs Monday-Friday at 9:00 AM
Weekly on Sunday0 0 * * 0Runs every Sunday at midnight
Monthly0 0 1 * *Runs on the 1st of every month

Examples

Simple presets
import { CronBuilder } from '@sylphx/sdk/react'

// Simple mode with presets (default)
<CronBuilder
  value={cron}
  onChange={setCron}
  mode="simple"
  showPreview={true}
  showNextRuns={true}
/>

Minimum Interval

Use minInterval to prevent users from scheduling tasks too frequently. This helps avoid overwhelming your task handlers with excessive requests.

Complete Example

Here is a complete example combining all task components into a task management interface:

app/admin/tasks/page.tsx
'use client'

import { useState } from 'react'
import { TaskScheduler, TaskList, CronBuilder } from '@sylphx/sdk/react'
import { cancelTask } from '@sylphx/sdk/tasks'
import { sendEmail, generateReport, syncData } from '@/tasks'
import { Plus, Calendar, List, Clock } from 'lucide-react'

const config = {
  secretKey: process.env.NEXT_PUBLIC_SYLPHX_KEY!,
  platformUrl: process.env.NEXT_PUBLIC_SYLPHX_URL ?? 'https://sylphx.com',
}

export default function TasksManagementPage() {
  const [view, setView] = useState<'list' | 'schedule'>('list')
  const [cronValue, setCronValue] = useState('0 9 * * *')

  const handleSchedule = async (run) => {
    toast.success(`Task triggered: ${run.id}`)
    setView('list') // Return to list view
  }

  const handleCancel = async (run) => {
    await cancelTask(config, run.id)
    toast.success('Task run cancelled')
  }

  const handleRetry = async (run) => {
    // Re-trigger with original payload
    await sendEmail.trigger(run.payload)
    toast.success('Task re-triggered')
  }

  return (
    <div className="max-w-6xl mx-auto p-6 space-y-8">
      <div className="flex items-center justify-between">
        <h1 className="text-3xl font-bold">Background Tasks</h1>

        <div className="flex gap-2">
          <button
            onClick={() => setView('list')}
            className={`px-4 py-2 rounded-lg flex items-center gap-2 ${
              view === 'list'
                ? 'bg-primary text-primary-foreground'
                : 'bg-muted'
            }`}
          >
            <List className="w-4 h-4" />
            View Runs
          </button>
          <button
            onClick={() => setView('schedule')}
            className={`px-4 py-2 rounded-lg flex items-center gap-2 ${
              view === 'schedule'
                ? 'bg-primary text-primary-foreground'
                : 'bg-muted'
            }`}
          >
            <Plus className="w-4 h-4" />
            Trigger Task
          </button>
        </div>
      </div>

      {view === 'list' ? (
        <TaskList
          title="All Task Runs"
          showFilters={true}
          showSearch={true}
          showActions={true}
          autoRefresh={true}
          refreshInterval={10000}
          onCancel={handleCancel}
          onRetry={handleRetry}
          onTaskClick={(run) => router.push(`/admin/tasks/${run.id}`)}
        />
      ) : (
        <div className="grid grid-cols-2 gap-8">
          <div>
            <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
              <Clock className="w-5 h-5" />
              Trigger a Task
            </h2>
            <TaskScheduler
              tasks={[sendEmail, generateReport, syncData]}
              onSchedule={handleSchedule}
              onCancel={() => setView('list')}
              showRetryConfig={true}
            />
          </div>

          <div>
            <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
              <Calendar className="w-5 h-5" />
              Cron Schedule Builder
            </h2>
            <CronBuilder
              value={cronValue}
              onChange={setCronValue}
              mode="simple"
              showPreview={true}
              showNextRuns={true}
              showTimezone={true}
            />
          </div>
        </div>
      )}
    </div>
  )
}

Theming

All task components inherit theming from the SylphxProvider:

import { SylphxProvider, TaskList, TaskScheduler } from '@sylphx/sdk/react'
import { sendEmail } from '@/tasks'

// Global theming via provider
<SylphxProvider
  theme={{
    colorPrimary: '#6366f1',
    colorSuccess: '#10b981',
    colorWarning: '#f59e0b',
    colorDanger: '#ef4444',
    borderRadius: '0.75rem',
  }}
>
  <TaskList title="Tasks" />
  <TaskScheduler tasks={[sendEmail]} onSchedule={handleSchedule} />
</SylphxProvider>

// Individual component styling
<TaskList
  title="Tasks"
  className="border-2 border-primary/20 rounded-2xl"
/>

<CronBuilder
  value={cron}
  onChange={setCron}
  className="bg-muted p-4 rounded-xl"
/>

Server Components

These components use client-side interactivity. When using in Next.js App Router, import them in a Client Component or add 'use client' at the top of your page.