diff --git a/frontend/src/lib/components/DropdownMenu.svelte b/frontend/src/lib/components/DropdownMenu.svelte
index 280f63ed08..e2289bcb4a 100644
--- a/frontend/src/lib/components/DropdownMenu.svelte
+++ b/frontend/src/lib/components/DropdownMenu.svelte
@@ -2,6 +2,7 @@
type Item = {
label: string
icon?: any
+ right?: string
onClick: () => void
}
type Props = {
@@ -11,7 +12,7 @@
let { items, closeCallback }: Props = $props()
-
+
{#each items as item}
-
{/each}
diff --git a/frontend/src/lib/components/runs/RunsTable.svelte b/frontend/src/lib/components/runs/RunsTable.svelte
index a9c44ddba5..4f73eb830e 100644
--- a/frontend/src/lib/components/runs/RunsTable.svelte
+++ b/frontend/src/lib/components/runs/RunsTable.svelte
@@ -12,6 +12,7 @@
import { twMerge } from 'tailwind-merge'
import RightClickPopover from '../RightClickPopover.svelte'
import DropdownMenu from '../DropdownMenu.svelte'
+ import { isJobCancelable, isJobReRunnable } from '$lib/utils'
interface Props {
//import InfiniteLoading from 'svelte-infinite-loading'
@@ -207,7 +208,27 @@
return nstickyIndices
})
- const showTag = $derived(containerWidth > 700)
+ let showTag = $derived(containerWidth > 700)
+ let selectedIdsPossibleActions = $derived.by(() => {
+ const cancellableJobs: Job[] = []
+ const uncancelableJobs: Job[] = []
+ const rerunnableJobs: Job[] = []
+ const unrerunnableJobs: Job[] = []
+ for (const jobId of selectedIds) {
+ const job = flatJobs?.find(
+ (jobOrDate) => jobOrDate.type === 'job' && jobOrDate.job.id === jobId
+ )
+ if (job?.type === 'job') {
+ if (isJobCancelable(job.job)) cancellableJobs.push(job.job)
+ else uncancelableJobs.push(job.job)
+ if (isJobReRunnable(job.job)) rerunnableJobs.push(job.job)
+ else unrerunnableJobs.push(job.job)
+ }
+ }
+ return { cancellableJobs, uncancelableJobs, rerunnableJobs, unrerunnableJobs }
+ })
+ let rerunnable = $derived(selectedIdsPossibleActions.rerunnableJobs.length)
+ let cancellable = $derived(selectedIdsPossibleActions.cancellableJobs.length)
rightClickPopover?.close()}
items={[
- {
- label: 'Cancel',
- icon: CircleXIcon,
- onClick: () => {}
- },
- {
- label: 'Run again',
- icon: RefreshCwIcon,
- onClick: () => {}
- }
+ ...(cancellable
+ ? [
+ {
+ label: 'Cancel',
+ icon: CircleXIcon,
+ right: cancellable >= 2 ? `${cancellable}` : undefined,
+ onClick: () => {}
+ }
+ ]
+ : []),
+ ...(rerunnable
+ ? [
+ {
+ label: 'Run again',
+ icon: RefreshCwIcon,
+ right: rerunnable >= 2 ? `${rerunnable}` : undefined,
+ onClick: () => {}
+ }
+ ]
+ : [])
]}
/>