feat(ui): add 'Cancel all failed' button to Jobs screen
Pair with the existing 'Retry all failed'. Drops every failed job from the queue at once. Single confirm prompt. Optimistic local update so the list clears instantly instead of waiting for the 5s poll tick. .jobs-cancel-all CSS tinted danger-red without being a loud .btn danger, matching the per-row Cancel pattern.
This commit is contained in:
parent
303f12e0f9
commit
6f64b55824
2 changed files with 29 additions and 3 deletions
|
|
@ -108,6 +108,23 @@ function Jobs({ navigate }) {
|
|||
).then(refresh);
|
||||
}, [jobs, refresh]);
|
||||
|
||||
// Drop every failed job from the queue. The opposite of Retry all — used
|
||||
// when a batch of jobs is unrecoverable (e.g. assets that were deleted
|
||||
// mid-encode) and the operator just wants the queue cleared.
|
||||
const handleCancelAll = React.useCallback(() => {
|
||||
const failedJobs = jobs.filter(j => j.status === 'failed');
|
||||
if (failedJobs.length === 0) return;
|
||||
if (!window.confirm(`Remove all ${failedJobs.length} failed jobs from the queue?\nThis cannot be undone.`)) return;
|
||||
Promise.allSettled(
|
||||
failedJobs.map(j => window.ZAMPP_API.fetch('/jobs/' + j.id, { method: 'DELETE' }))
|
||||
).then(() => {
|
||||
// Optimistic local drop so the UI updates the instant the modal closes,
|
||||
// not 5s later on the next poll tick.
|
||||
setJobs(prev => prev.filter(j => j.status !== 'failed'));
|
||||
refresh();
|
||||
});
|
||||
}, [jobs, refresh]);
|
||||
|
||||
const counts = {
|
||||
all: jobs.length,
|
||||
running: jobs.filter(j => j.status === 'running').length,
|
||||
|
|
@ -124,9 +141,14 @@ function Jobs({ navigate }) {
|
|||
<span className="subtitle">Proxy generation, transcoding, and processing queue</span>
|
||||
<div className="spacer" />
|
||||
{counts.failed > 0 && (
|
||||
<button className="btn ghost sm" onClick={handleRetryAll} title={`Retry all ${counts.failed} failed jobs`}>
|
||||
<Icon name="refresh" />Retry all failed
|
||||
</button>
|
||||
<>
|
||||
<button className="btn ghost sm" onClick={handleRetryAll} title={`Retry all ${counts.failed} failed jobs`}>
|
||||
<Icon name="refresh" />Retry all failed
|
||||
</button>
|
||||
<button className="btn ghost sm jobs-cancel-all" onClick={handleCancelAll} title={`Remove all ${counts.failed} failed jobs from the queue`}>
|
||||
<Icon name="x" />Cancel all failed
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
<button className="btn ghost sm" onClick={refresh}>
|
||||
<Icon name="refresh" />Refresh
|
||||
|
|
|
|||
|
|
@ -1372,3 +1372,7 @@
|
|||
display: flex; gap: 8px; margin-top: 4px;
|
||||
}
|
||||
.premiere-release-actions a { text-decoration: none; }
|
||||
|
||||
/* Tint Cancel-all-failed button to signal destructive action without
|
||||
making it loud — same pattern as the per-row Cancel. */
|
||||
.jobs-cancel-all { color: var(--danger); }
|
||||
|
|
|
|||
Loading…
Reference in a new issue