feat(frontend): show runs using a time chart

This commit is contained in:
Ruben Fiszel
2022-11-05 16:46:23 +01:00
parent 8b45924abf
commit d83425ab9c
3 changed files with 75 additions and 7 deletions
+11 -2
View File
@@ -15,9 +15,12 @@
LogarithmicScale
} from 'chart.js'
import type { CompletedJob } from '$lib/gen'
import { createEventDispatcher } from 'svelte'
export let jobs: CompletedJob[] | undefined = []
const dispatch = createEventDispatcher()
$: success = jobs?.filter((x) => x.success)
$: failed = jobs?.filter((x) => !x.success)
ChartJS.register(
@@ -54,13 +57,19 @@
const zoomOptions = {
pan: {
enabled: true,
modifierKey: 'ctrl' as 'ctrl'
modifierKey: 'ctrl' as 'ctrl',
onPan: ({ chart }) => {
console.log('XXX')
}
},
zoom: {
drag: {
enabled: true
},
mode: 'x' as 'x'
mode: 'x' as 'x',
onZoom: ({ chart }) => {
dispatch('zoom', { min: new Date(chart.scales.x.min), max: new Date(chart.scales.x.max) })
}
}
}
</script>
@@ -1,4 +1,6 @@
<script lang="ts">
import { goto } from '$app/navigation'
import { page } from '$app/stores'
import type { Job } from '$lib/gen'
import {
displayDate,
@@ -15,13 +17,14 @@
faFastForward,
faHourglassHalf,
faRobot,
faSearch,
faTimes,
faUser,
faWind
} from '@fortawesome/free-solid-svg-icons'
import Icon from 'svelte-awesome'
import { check } from 'svelte-awesome/icons'
import { Badge } from '../common'
import { Badge, Button } from '../common'
const SMALL_ICON_SCALE = 0.7
@@ -94,6 +97,12 @@
{:else if 'job_kind' in job && job.job_kind == 'identity'}
<a href="/run/{job.id}">no op</a>
{/if}
<button
class="ml-1"
on:click={() => {
goto(`/runs/${job.script_path}?${$page.url.searchParams.toString()}`)
}}><Badge><Icon scale={0.7} data={faSearch} /></Badge></button
>
</div>
<div class="whitespace-nowrap">
{#if 'job_kind' in job}<a href="/run/{job.id}"
+54 -4
View File
@@ -18,10 +18,12 @@
import Tabs from '$lib/components/common/tabs/Tabs.svelte'
import Tab from '$lib/components/common/tabs/Tab.svelte'
import JobDetail from '$lib/components/jobs/JobDetail.svelte'
import { Skeleton } from '$lib/components/common'
import { Button, Skeleton } from '$lib/components/common'
import { goto } from '$app/navigation'
import PageHeader from '$lib/components/PageHeader.svelte'
import RunChart from '$lib/components/RunChart.svelte'
import { faSearch, faSearchMinus } from '@fortawesome/free-solid-svg-icons'
import Icon from 'svelte-awesome'
let jobs: Job[] | undefined
let error: Error | undefined
@@ -118,7 +120,7 @@
date.setSeconds(date.getSeconds() + 1)
ts = date.toISOString()
}
const newJobs = await fetchJobs(undefined, ts)
const newJobs = await fetchJobs(maxTs, minTs ?? ts)
if (newJobs && newJobs.length > 0) {
const oldJobs = jobs.map((x) => x.id)
jobs = newJobs.filter((x) => !oldJobs.includes(x.id)).concat(jobs)
@@ -133,6 +135,7 @@
$: {
if ($workspaceStore) {
loadJobs(createdBefore)
path // trigger on path change
success && isSkipped && jobKinds
if (intervalId) {
clearInterval(intervalId)
@@ -154,6 +157,10 @@
clearInterval(intervalId)
}
})
let searchPath = ''
$: searchPath = path
let minTs = undefined
let maxTs = undefined
</script>
<CenteredPage>
@@ -162,8 +169,25 @@
tooltip="All past and schedule executions of scripts and flows, including previews.
You only see your own runs or runs of groups you belong to unless you are an admin."
/>
<div class="flex flex-row gap-x-2">
<input placeholder="Search jobs at a given path" type="text" bind:value={searchPath} />
<Button
variant="border"
on:click={() => {
goto('/runs?' + $page.url.searchParams.toString())
}}
size="xs"><Icon data={faSearchMinus} /></Button
>
<Button
variant="border"
on:click={() => {
goto('/runs?' + $page.url.searchParams.toString())
}}
size="xs"><Icon data={faSearch} /></Button
>
</div>
<div class="max-w-7x mt-6">
<div class="max-w-7x mt-2">
<div class="flex flex-row space-x-4">
<select
bind:value={success}
@@ -199,7 +223,33 @@
</Tabs>
</div>
<div class="border mb-4">
<RunChart jobs={completedJobs} />
<RunChart
jobs={completedJobs}
on:zoom={async (e) => {
minTs = e.detail.min.toISOString()
maxTs = e.detail.max.toISOString()
jobs = await fetchJobs(maxTs, minTs)
}}
/>
</div>
<div class="flex flex-row gap-x-2 w-full mb-2">
<div class="relative"
><span class="text-xs absolute -top-4">min datetime</span>
<input type="text" value={minTs ?? 'zoom x axis to set min'} disabled />
</div>
<div class="relative"
><span class="text-xs absolute -top-4">max datetime</span>
<input type="text" value={maxTs ?? 'zoom x axis to set max'} disabled />
</div>
<Button
variant="border"
on:click={async () => {
minTs = undefined
maxTs = undefined
jobs = await fetchJobs(maxTs, minTs)
}}
size="xs"><Icon data={faSearchMinus} /></Button
>
</div>
<Skeleton loading={!jobs} layout={[[6], 1, [6], 1, [6], 1, [6], 1, [6]]} />
{#if jobs}