mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-30 16:17:25 +00:00
* feat(frontend): wip * feat(frontend): wip * feat(frontend): wip * fix(frontend): improve buttons * fix(frontend): improve buttons wip * fix(frontend): wip * fix(frontend): rework done * feat(frontend): Fix grey buttons
168 lines
3.9 KiB
Svelte
168 lines
3.9 KiB
Svelte
<script lang="ts">
|
|
import { debounce } from '$lib/utils'
|
|
import { getContext, onDestroy } from 'svelte'
|
|
|
|
import TimelineBar from '$lib/components/TimelineBar.svelte'
|
|
import type { AppViewerContext } from '../types'
|
|
|
|
const { jobs, jobsById } = getContext<AppViewerContext>('AppViewerContext')
|
|
|
|
let min: undefined | number = undefined
|
|
let max: undefined | number = undefined
|
|
let total: number | undefined = undefined
|
|
|
|
let debounced = debounce(() => computeItems($jobs), 30)
|
|
$: $jobs && $jobsById && debounced()
|
|
|
|
let items: Record<
|
|
string,
|
|
{ created_at?: number; started_at?: number; duration_ms?: number; id: string }[]
|
|
> = {}
|
|
|
|
export function reset() {
|
|
min = undefined
|
|
max = undefined
|
|
}
|
|
|
|
function computeItems(jobs: string[]): any {
|
|
let nmin: undefined | number = undefined
|
|
let nmax: undefined | number = undefined
|
|
|
|
let isStillRunning = false
|
|
|
|
let nitems: Record<
|
|
string,
|
|
{ created_at?: number; started_at?: number; duration_ms?: number; id: string }[]
|
|
> = {}
|
|
jobs.forEach((k) => {
|
|
let v = $jobsById[k]
|
|
if (v.created_at) {
|
|
if (!nmin) {
|
|
nmin = v.created_at
|
|
} else {
|
|
nmin = Math.min(nmin, v.created_at)
|
|
}
|
|
}
|
|
if (v.duration_ms == undefined) {
|
|
isStillRunning = true
|
|
}
|
|
if (!isStillRunning) {
|
|
if (v.started_at && v.duration_ms) {
|
|
let lmax = v.started_at + v.duration_ms
|
|
if (!nmax) {
|
|
nmax = lmax
|
|
} else {
|
|
nmax = Math.max(nmax, lmax)
|
|
}
|
|
}
|
|
}
|
|
if (!nitems[v.component]) {
|
|
nitems[v.component] = []
|
|
}
|
|
nitems[v.component].push({
|
|
created_at: v.created_at,
|
|
duration_ms: v.duration_ms,
|
|
started_at: v.started_at,
|
|
id: v.job
|
|
})
|
|
})
|
|
|
|
Object.values(nitems).forEach((v) => {
|
|
v.sort((x, y) => {
|
|
if (!x.created_at) {
|
|
return -1
|
|
} else if (!y.created_at) {
|
|
return 1
|
|
} else {
|
|
return x.created_at - y.created_at
|
|
}
|
|
})
|
|
})
|
|
|
|
min = nmin
|
|
max = isStillRunning ? undefined : nmax
|
|
if (max && min) {
|
|
total = max - min
|
|
}
|
|
items = nitems
|
|
}
|
|
|
|
let now = Date.now()
|
|
|
|
let interval = setInterval((x) => {
|
|
if (!max) {
|
|
now = Date.now()
|
|
}
|
|
if (min && (!max || total == undefined)) {
|
|
total = max ? max - min : Math.max(now - min, 2000)
|
|
}
|
|
}, 30)
|
|
|
|
onDestroy(() => {
|
|
interval && clearInterval(interval)
|
|
})
|
|
</script>
|
|
|
|
<!-- <pre class="text-xs">
|
|
{JSON.stringify(items, null, 4)}
|
|
</pre> -->
|
|
<div class="divide-y">
|
|
<div class="flex flex-row-reverse mb-2 items-center text-sm text-secondary px-2">
|
|
<div class="flex gap-4 items-center">
|
|
<div class="flex gap-2 items-center text-xs">
|
|
<div>Waiting for executor</div>
|
|
<div class="h-4 w-4 bg-gray-300 dark:bg-gray-600 rounded" />
|
|
</div>
|
|
|
|
<div class="flex gap-2 items-center text-xs">
|
|
<div>Execution</div>
|
|
<div class="h-4 w-4 bg-blue-500/90 rounded" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{#each Object.entries(items) as [k, v]}
|
|
<div class="px-2 py-2 grid grid-cols-12 w-full"
|
|
><div class="col-span-2">{k}</div>
|
|
<div class="col-span-10 pt-1 px-2 flex min-h-6 w-full"
|
|
>{#if min && total}
|
|
<div class="flex flex-col gap-2 w-full">
|
|
{#each v ?? [] as b}
|
|
{@const waitingLen = b?.created_at
|
|
? b.started_at
|
|
? b.started_at - b?.created_at
|
|
: b.duration_ms
|
|
? 0
|
|
: now - b?.created_at
|
|
: 0}
|
|
<div class="flex w-full">
|
|
<TimelineBar
|
|
position="left"
|
|
id={b?.id}
|
|
{total}
|
|
{min}
|
|
gray
|
|
started_at={b.created_at}
|
|
len={waitingLen < 100 ? 0 : waitingLen - 100}
|
|
running={b?.started_at == undefined}
|
|
/>
|
|
{#if b.started_at}
|
|
<TimelineBar
|
|
position={waitingLen < 100 ? 'center' : 'right'}
|
|
id={b?.id}
|
|
{total}
|
|
{min}
|
|
concat
|
|
started_at={b.started_at}
|
|
len={b.started_at ? b?.duration_ms ?? now - b?.started_at : 0}
|
|
running={b?.duration_ms == undefined}
|
|
/>
|
|
{/if}
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
{/if}</div
|
|
></div
|
|
>
|
|
{/each}
|
|
</div>
|