build69
build69  /  Components  /  Feedback & Status  /  JobProgress

JobProgress

v1.0.1Updated 19 Oct 2026

One long-running operation that is happening on a SERVER — a move, copy, delete, archive or any kind a host names. Distinct from UploadTray, which counts the bytes it is sending and therefore always knows the percentage: here the host POLLS and gets whatever the server chose to report, so percent is OPTIONAL and a job with no size yet draws an indeterminate bar rather than a zero that reads as stalled. Queued, running, paused, done, failed and cancelled each have their own word, bar and controls, and a failed job shows the server's own message verbatim. JobProgressList stacks several under one heading.

Preview

Live · 8 stories
DefaultOpen ↗
▸Why this is recommendedjobprogressbackgroundtask+5

The default, out-of-the-box JobProgress.

Recommended for+14
  • ✓Show how far a server-side move or copy has got
  • ✓Report a long background job the user started and walked away from
  • ✓A tray of background jobs with cancel and retry
  • ✓Say why a batch operation failed
Tags+6
jobprogressbackgroundtaskserverpollingqueuebatchdefault
Features+4
  • percent is optional — a server that has not worked out a total yet gets an indeterminate bar with no aria-valuenow, never an invented zero
  • processed / total is the other honest shape, and the percentage derives from it
  • Queued is not running: its own word and a still bar, so a queue of forty does not read as forty stalled jobs
  • A failed job shows the SERVER’s message verbatim — the only thing that says whether to retry, call someone, or change the input
  • A cancelled job shows no bar at all; a frozen 61% invites the reading that it might still finish
  • Cancel while the job can still be stopped, Retry only on a failure, Dismiss only once it has settled — and none of them without a handler
  • Polite live region on the STATUS LINE, not the whole panel, so a re-render of the buttons does not re-announce the job
  • Labelled role="group" named from the job’s title, or its kind when it has none
  • An ETA in minutes above a minute and seconds below, and only while running
  • An unrecognised state renders as running rather than throwing — a server that grows a state must not blank the page
  • Every figure through the locale formatter (Thai numerals under a LocaleProvider)
  • JobProgressList: several jobs under one replaceable heading, rendering nothing when the list is empty
  • i18n: labels prop over DEFAULT_JOB_PROGRESS_LABELS — the kind words, the six state words, the percentage and count templates, the ETA templates and every control
Not recommended for−2
  • ✕File uploads the browser is sending (use UploadTray / UploadProgress, which own the transfer and know the bytes)
  • ✕A short action inside a button (use the button’s own loading state)
  • ✕A determinate bar with no job around it (use Progress)
  • ✕Transient success or failure messages (use Sonner toasts)

Install

Ask your agent, or call the MCP tool directly. The resolved bundle is written into your project.

get_registry_item({ name: "JobProgress" })

Usage

import { JobProgress, JobProgressList } from '@/components/feedback/job-progress';

// One job the host is polling
<JobProgress
  job={{ id, kind: 'move', title: 'Moving 1,284 invoices',
         state: 'running', processed: 814, total: 1284, etaSeconds: 220 }}
  onCancel={(id) => api.cancelJob(id)}
/>

// The tray
<JobProgressList jobs={jobs} onCancel={cancel} onRetry={retry} onDismiss={dismiss} />

Tick variants in the left menu — each adds a tab with that variant’s real story source, the same code the preview above renders.

Props

PropTypeRequired
job

Job = { id, kind?, title?, detail?, state, percent?, processed?, total?, error?, etaSeconds? }. state is "queued" | "running" | "paused" | "done" | "failed" | "cancelled"; kind picks a default title when title is absent

Jobyes
onCancel

Shown only while the job is queued, running or paused

(id: string) => void—
onRetry

Shown only on a failed job

(id: string) => void—
onDismiss

Shown only once the job is done, failed or cancelled

(id: string) => void—
labels

Override any built-in string. Keys: jobProgress ({title}), move/copy/delete/archive/job, queued/running/paused/done/failed/cancelled, percentComplete ({percent}), processedOfTotal ({processed}/{total}), working, etaMinutes ({minutes}), etaSeconds ({seconds}), cancel, retry, dismiss, backgroundJobs. English defaults ship verbatim as DEFAULT_JOB_PROGRESS_LABELS. The job’s own error is NOT a label — it is the server’s text and arrives in whatever language the backend speaks

Partial<JobProgressLabels>—

Related