mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-28 00:02:42 +00:00
* improve arg layout * improve runs row (wip) * Add job badges * group filters in dropdown * improve runs row layout * Improve filter layout * use select for graph display * handle width modification * Remove useless headers * fix bad display when result is null * Display all jobs tags * Improve display for 'step of flow' jobs * Add empty message for JobAssetsViewer * Move job preview assets tab to flow result for flows * Only show tag in the tag column * Add job kind to rows * Add padding to the run preview * nit * move refresh on top of table * Move filters into header bar * move runs table topbar outside table * Simplify layout * Use toggle for kind for large screen * move sync job and add batch actions breakpoint * revert dropdown to toggle for conurrency/duration * handle run labels overflow * improve time display * fix flow preview with no path display * Add titles * Prevent tab shift for script and flow result * nit * Allow job deselect * Make job link more visible * Fix filtering for queued job * Fix filter not reseting after select from toggleMore * Allways show assets for flow status viewer * Update run chart to svelte 5 and fix reactivity issue * migrate concurrency chart to svelte 5 * Improve admmin workspace display and fix missing in add filter popover * nit * fix run table resize * Add breakpoint to hide tag in small screens * use a css file for gathering RunRow and RunTable classes * nit * nit * remove debug log * nit * fix typo * Have too icons for queued workers and suspended * add gap before auto-refresh * Replace min max to from to calendar picker * Add loading state for job preview * Move duration * Display kind full width when calendar not set * Only show 2 digits for jobs duration * Replace Scheduled for by a clock un the run row * Fix typpo in dropown select to dropdown select * Hide sync and previews in toggle more * Fix runs row padding * Change notification colors for queued jobs * use utils debounce function * fix typo * nit * use class instead of classNames * clean select filter side effects
113 lines
3.2 KiB
Svelte
113 lines
3.2 KiB
Svelte
<script lang="ts">
|
|
import { twMerge } from 'tailwind-merge'
|
|
import { ListFilterPlus } from 'lucide-svelte'
|
|
import Tooltip from '$lib/components/meltComponents/Tooltip.svelte'
|
|
import DropdownV2 from '$lib/components/DropdownV2.svelte'
|
|
import type { Job } from '$lib/gen'
|
|
import type { Item } from '$lib/utils'
|
|
|
|
interface Props {
|
|
job: Job
|
|
activeLabel: string | null
|
|
onFilterByLabel: (label: string) => void
|
|
labelWidth: number
|
|
}
|
|
|
|
let { job, activeLabel, onFilterByLabel, labelWidth }: Props = $props()
|
|
|
|
const GAP = 4
|
|
const LABEL_MAX_WIDTH = 84
|
|
const MORE_LABEL_WIDTH = 30
|
|
// Min width for labels columns is 120px
|
|
|
|
const labels = $derived(job && Array.isArray(job?.['labels']) ? (job['labels'] as string[]) : [])
|
|
|
|
const labelSplit = $derived.by(() => {
|
|
if (!labels || labels.length === 0 || labelWidth <= 0) {
|
|
return { visibleLabels: [], hiddenLabels: [] }
|
|
}
|
|
|
|
if (labels.length === 1) {
|
|
return { visibleLabels: labels, hiddenLabels: [] }
|
|
}
|
|
|
|
let currentWidth = 0
|
|
const visible: string[] = []
|
|
const hidden: string[] = []
|
|
const margin = 20
|
|
|
|
for (let i = 0; i < labels.length; i++) {
|
|
const label = labels[i]
|
|
|
|
// Check if we need to reserve space for overflow badge
|
|
const needsOverflowBadge = i < labels.length - 1
|
|
const remainingWidth = labelWidth - currentWidth
|
|
const requiredWidth =
|
|
LABEL_MAX_WIDTH + (needsOverflowBadge ? MORE_LABEL_WIDTH + GAP : 0) + margin
|
|
|
|
if (remainingWidth >= requiredWidth || visible.length === 0) {
|
|
visible.push(label)
|
|
currentWidth += LABEL_MAX_WIDTH + GAP
|
|
} else {
|
|
hidden.push(...labels.slice(i))
|
|
break
|
|
}
|
|
}
|
|
|
|
return { visibleLabels: visible, hiddenLabels: hidden }
|
|
})
|
|
|
|
const visibleLabels = $derived(labelSplit.visibleLabels || [])
|
|
const hiddenLabels = $derived(labelSplit.hiddenLabels || [])
|
|
|
|
const dropdownItems = $derived(
|
|
hiddenLabels.map(
|
|
(label): Item => ({
|
|
displayName: label,
|
|
action: () => onFilterByLabel(label),
|
|
icon: ListFilterPlus
|
|
})
|
|
)
|
|
)
|
|
</script>
|
|
|
|
{#if labels && labels.length > 0}
|
|
<div class="flex flex-row items-center" style="gap: {GAP}px">
|
|
{#each visibleLabels as label}
|
|
<Tooltip openDelay={500} placement="bottom">
|
|
<button
|
|
class={twMerge(
|
|
activeLabel == label ? 'bg-blue-50 dark:bg-blue-900/50' : '',
|
|
'flex flex-row items-center px-2 group py-1 rounded-md bg-surface-secondary hover:bg-surface'
|
|
)}
|
|
style="gap: {GAP}px; width: {LABEL_MAX_WIDTH}px"
|
|
onclick={() => {
|
|
onFilterByLabel(label)
|
|
}}
|
|
>
|
|
<span class="truncate text-2xs font-normal">{label}</span>
|
|
<ListFilterPlus size={12} class="shrink-0 text-gray-300 group-hover:text-primary" />
|
|
</button>
|
|
{#snippet text()}
|
|
{`Filter by label: ${label}`}
|
|
{/snippet}
|
|
</Tooltip>
|
|
{/each}
|
|
|
|
{#if hiddenLabels.length > 0}
|
|
<DropdownV2 placement="bottom-start" items={dropdownItems} customWidth={224}>
|
|
{#snippet buttonReplacement()}
|
|
<button
|
|
class="flex flex-row items-center justify-center px-2 py-1 text-2xs font-semibold hover:bg-surface bg-surface-secondary text-secondary rounded-md"
|
|
style="gap: {GAP}px; width: {MORE_LABEL_WIDTH}px"
|
|
>
|
|
+{hiddenLabels.length}
|
|
</button>
|
|
{/snippet}
|
|
</DropdownV2>
|
|
{/if}
|
|
</div>
|
|
{:else}
|
|
<span class="text-2xs text-secondary">-</span>
|
|
{/if}
|