diff --git a/admin/app/controllers/downloads_controller.ts b/admin/app/controllers/downloads_controller.ts index bd58790..023806b 100644 --- a/admin/app/controllers/downloads_controller.ts +++ b/admin/app/controllers/downloads_controller.ts @@ -15,4 +15,9 @@ export default class DownloadsController { const payload = await request.validateUsing(downloadJobsByFiletypeSchema) return this.downloadService.listDownloadJobs(payload.params.filetype) } + + async removeJob({ params }: HttpContext) { + await this.downloadService.removeFailedJob(params.jobId) + return { success: true } + } } diff --git a/admin/app/services/download_service.ts b/admin/app/services/download_service.ts index 63c7ecd..a2b7faf 100644 --- a/admin/app/services/download_service.ts +++ b/admin/app/services/download_service.ts @@ -50,4 +50,15 @@ export class DownloadService { return b.progress - a.progress }) } + + async removeFailedJob(jobId: string): Promise { + for (const queueName of [RunDownloadJob.queue, DownloadModelJob.queue]) { + const queue = this.queueService.getQueue(queueName) + const job = await queue.getJob(jobId) + if (job) { + await job.remove() + return + } + } + } } diff --git a/admin/inertia/components/ActiveDownloads.tsx b/admin/inertia/components/ActiveDownloads.tsx index 69bbb8f..9661f22 100644 --- a/admin/inertia/components/ActiveDownloads.tsx +++ b/admin/inertia/components/ActiveDownloads.tsx @@ -2,7 +2,8 @@ import useDownloads, { useDownloadsProps } from '~/hooks/useDownloads' import HorizontalBarChart from './HorizontalBarChart' import { extractFileName } from '~/lib/util' import StyledSectionHeader from './StyledSectionHeader' -import { IconAlertTriangle } from '@tabler/icons-react' +import { IconAlertTriangle, IconX } from '@tabler/icons-react' +import api from '~/lib/api' interface ActiveDownloadProps { filetype?: useDownloadsProps['filetype'] @@ -10,7 +11,12 @@ interface ActiveDownloadProps { } const ActiveDownloads = ({ filetype, withHeader = false }: ActiveDownloadProps) => { - const { data: downloads } = useDownloads({ filetype }) + const { data: downloads, invalidate } = useDownloads({ filetype }) + + const handleDismiss = async (jobId: string) => { + await api.removeDownloadJob(jobId) + invalidate() + } return ( <> @@ -37,6 +43,13 @@ const ActiveDownloads = ({ filetype, withHeader = false }: ActiveDownloadProps) Download failed{download.failedReason ? `: ${download.failedReason}` : ''}

+ ) : ( { + return catchInternal(async () => { + await this.client.delete(`/downloads/jobs/${jobId}`) + })() + } + async runBenchmark(type: BenchmarkType, sync: boolean = false) { return catchInternal(async () => { const response = await this.client.post( diff --git a/admin/start/routes.ts b/admin/start/routes.ts index 2045b27..631c528 100644 --- a/admin/start/routes.ts +++ b/admin/start/routes.ts @@ -92,6 +92,7 @@ router .group(() => { router.get('/jobs', [DownloadsController, 'index']) router.get('/jobs/:filetype', [DownloadsController, 'filetype']) + router.delete('/jobs/:jobId', [DownloadsController, 'removeJob']) }) .prefix('/api/downloads')