diff --git a/i18n/en.json b/i18n/en.json index f8a51eb5f6..6b70a366ae 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -1645,6 +1645,7 @@ "restore_user": "Restore user", "restored_asset": "Restored asset", "resume": "Resume", + "resume_paused_jobs": "Resume {count, plural, one {# paused job} other {# paused jobs}}", "retry_upload": "Retry upload", "review_duplicates": "Review duplicates", "review_large_files": "Review large files", diff --git a/web/src/routes/admin/jobs-status/+page.svelte b/web/src/routes/admin/jobs-status/+page.svelte index d1bd4e41d0..db846557e9 100644 --- a/web/src/routes/admin/jobs-status/+page.svelte +++ b/web/src/routes/admin/jobs-status/+page.svelte @@ -4,9 +4,16 @@ import { AppRoute } from '$lib/constants'; import JobCreateModal from '$lib/modals/JobCreateModal.svelte'; import { asyncTimeout } from '$lib/utils'; - import { getAllJobsStatus, type AllJobStatusResponseDto } from '@immich/sdk'; + import { handleError } from '$lib/utils/handle-error'; + import { + getAllJobsStatus, + JobCommand, + sendJobCommand, + type AllJobStatusResponseDto, + type JobName, + } from '@immich/sdk'; import { Button, HStack, modalManager, Text } from '@immich/ui'; - import { mdiCog, mdiPlus } from '@mdi/js'; + import { mdiCog, mdiPlay, mdiPlus } from '@mdi/js'; import { onDestroy, onMount } from 'svelte'; import { t } from 'svelte-i18n'; import type { PageData } from './$types'; @@ -21,6 +28,24 @@ let running = true; + const pausedJobs = $derived( + Object.entries(jobs ?? {}) + .filter(([_, jobStatus]) => jobStatus.queueStatus?.isPaused) + .map(([jobName]) => jobName as JobName), + ); + + const handleResumePausedJobs = async () => { + try { + for (const jobName of pausedJobs) { + await sendJobCommand({ id: jobName, jobCommandDto: { command: JobCommand.Resume, force: false } }); + } + // Refresh jobs status immediately after resuming + jobs = await getAllJobsStatus(); + } catch (error) { + handleError(error, $t('admin.failed_job_command', { values: { command: 'resume', job: 'paused jobs' } })); + } + }; + onMount(async () => { while (running) { jobs = await getAllJobsStatus(); @@ -36,6 +61,19 @@ {#snippet buttons()} + {#if pausedJobs.length > 0} + + {/if}