mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-20 16:02:19 +00:00
fix: improve performance of flow viewer
This commit is contained in:
@@ -67,7 +67,7 @@
|
||||
let selectedJobStep: string | undefined = $state(undefined)
|
||||
|
||||
let isRunning: boolean = $state(false)
|
||||
let jobProgressReset: (() => void) | undefined = $state(undefined)
|
||||
let progressBar: FlowProgressBar | undefined = $state(undefined)
|
||||
|
||||
export function test() {
|
||||
runPreview(previewArgs, undefined)
|
||||
@@ -80,7 +80,7 @@
|
||||
args: Record<string, any>,
|
||||
restartedFrom: RestartedFrom | undefined
|
||||
) {
|
||||
jobProgressReset?.()
|
||||
progressBar?.reset()
|
||||
const newFlow = { value: { modules }, summary: '' }
|
||||
jobId = await runFlowPreview(args, newFlow, $pathStore, restartedFrom)
|
||||
isRunning = true
|
||||
@@ -161,7 +161,7 @@
|
||||
<div></div>
|
||||
</div>
|
||||
<div class="w-full flex flex-col gap-y-1">
|
||||
<FlowProgressBar {job} bind:reset={jobProgressReset} />
|
||||
<FlowProgressBar {job} bind:this={progressBar} />
|
||||
</div>
|
||||
<div class="overflow-y-auto grow pr-4">
|
||||
<div class="max-h-1/2 overflow-auto border-b">
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
retryStatus.val = {}
|
||||
suspendStatus.val = {}
|
||||
globalRefreshes = {}
|
||||
flowState.val = {}
|
||||
flowState = {}
|
||||
localDurationStatuses = {}
|
||||
localModuleStates = {}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,27 @@
|
||||
import { type Job } from '$lib/gen'
|
||||
import ProgressBar from '../progressBar/ProgressBar.svelte'
|
||||
|
||||
export let job: Job | undefined = undefined
|
||||
export let currentSubJobProgress: number | undefined = undefined
|
||||
interface Props {
|
||||
job?: Job | undefined
|
||||
currentSubJobProgress?: number | undefined
|
||||
class?: string
|
||||
}
|
||||
|
||||
let error: number | undefined = undefined
|
||||
let index = 0
|
||||
let subIndex: number | undefined = undefined
|
||||
let subLength: number | undefined = undefined
|
||||
let length = 1
|
||||
let nextInProgress = false
|
||||
let subIndexIsPercent: boolean = false
|
||||
let {
|
||||
job = undefined,
|
||||
currentSubJobProgress = $bindable(undefined),
|
||||
class: className
|
||||
}: Props = $props()
|
||||
|
||||
$: if (job) updateJobProgress(job)
|
||||
let error: number | undefined = $state(undefined)
|
||||
let index = $state(0)
|
||||
let subIndex: number | undefined = $state(undefined)
|
||||
let subLength: number | undefined = $state(undefined)
|
||||
let length = $state(1)
|
||||
let nextInProgress = $state(false)
|
||||
let subIndexIsPercent: boolean = $state(false)
|
||||
|
||||
let progressBar = $state<ProgressBar | undefined>(undefined)
|
||||
|
||||
function updateJobProgress(job: Job) {
|
||||
const modules = job?.flow_status?.modules
|
||||
@@ -40,8 +49,8 @@
|
||||
newError = maxDone
|
||||
maxDone = maxDone + 1
|
||||
}
|
||||
}
|
||||
subIndexIsPercent = false;
|
||||
}
|
||||
subIndexIsPercent = false
|
||||
|
||||
// Loop is still iterating
|
||||
if (module?.iterator) {
|
||||
@@ -54,12 +63,12 @@
|
||||
} else if (module?.branchall) {
|
||||
subStepIndex = module.branchall.branch
|
||||
subStepLength = module.branchall.len
|
||||
} else if (module?.progress) {
|
||||
} else if (module?.progress) {
|
||||
const clamp = (num, min, max) => Math.min(Math.max(num, min), max)
|
||||
subStepIndex = clamp(module?.progress, subIndex ?? 0, 99)
|
||||
// Jitter protection >^^^^^^^^
|
||||
subStepLength = 100
|
||||
subIndexIsPercent = true;
|
||||
subIndexIsPercent = true
|
||||
currentSubJobProgress = subStepIndex
|
||||
} else {
|
||||
currentSubJobProgress = undefined
|
||||
@@ -73,26 +82,27 @@
|
||||
nextInProgress = newNextInProgress
|
||||
}
|
||||
|
||||
let resetP: any
|
||||
|
||||
export function reset() {
|
||||
resetP?.()
|
||||
progressBar?.resetP()
|
||||
error = undefined
|
||||
subIndex = undefined
|
||||
subLength = undefined
|
||||
length = 1
|
||||
index = 0
|
||||
}
|
||||
$effect(() => {
|
||||
job && updateJobProgress(job)
|
||||
})
|
||||
</script>
|
||||
|
||||
<ProgressBar
|
||||
bind:resetP
|
||||
bind:this={progressBar}
|
||||
{length}
|
||||
{index}
|
||||
{nextInProgress}
|
||||
{subLength}
|
||||
{subIndex}
|
||||
{error}
|
||||
bind:subIndexIsPercent
|
||||
class={$$props.class}
|
||||
{subIndexIsPercent}
|
||||
class={className}
|
||||
/>
|
||||
|
||||
@@ -4,28 +4,43 @@
|
||||
import type { Writable } from 'svelte/store'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export let sourceX: number
|
||||
export let sourceY: number
|
||||
export let sourcePosition: Position
|
||||
export let targetX: number
|
||||
export let targetY: number
|
||||
export let targetPosition: Position
|
||||
export let markerEnd: string | undefined = undefined
|
||||
export let data: { class?: string } = {}
|
||||
interface Props {
|
||||
sourceX: number
|
||||
sourceY: number
|
||||
sourcePosition: Position
|
||||
targetX: number
|
||||
targetY: number
|
||||
targetPosition: Position
|
||||
markerEnd?: string | undefined
|
||||
data?: { class?: string }
|
||||
}
|
||||
|
||||
const { useDataflow } = getContext<{
|
||||
useDataflow: Writable<boolean | undefined>
|
||||
}>('FlowGraphContext')
|
||||
|
||||
$: [edgePath] = getBezierPath({
|
||||
let {
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourcePosition,
|
||||
targetX,
|
||||
targetY,
|
||||
targetPosition,
|
||||
curvature: 0.25
|
||||
})
|
||||
markerEnd = undefined,
|
||||
data = {}
|
||||
}: Props = $props()
|
||||
|
||||
const { useDataflow } = getContext<{
|
||||
useDataflow: Writable<boolean | undefined>
|
||||
}>('FlowGraphContext')
|
||||
|
||||
let [edgePath] = $derived(
|
||||
getBezierPath({
|
||||
sourceX,
|
||||
sourceY,
|
||||
sourcePosition,
|
||||
targetX,
|
||||
targetY,
|
||||
targetPosition,
|
||||
curvature: 0.25
|
||||
})
|
||||
)
|
||||
</script>
|
||||
|
||||
<BaseEdge
|
||||
|
||||
@@ -1,77 +1,88 @@
|
||||
<script lang="ts">
|
||||
import { tweened } from 'svelte/motion'
|
||||
import { Tween } from 'svelte/motion'
|
||||
import { linear } from 'svelte/easing'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
function getTween(initialValue = 0, duration = 200) {
|
||||
return tweened(initialValue, {
|
||||
duration,
|
||||
easing: linear
|
||||
})
|
||||
// Remove padding/margin, border radius and titles
|
||||
|
||||
interface Props {
|
||||
error?: number | undefined
|
||||
index: number
|
||||
subIndex: number | undefined
|
||||
subLength: number | undefined
|
||||
nextInProgress?: boolean
|
||||
// Used for displaying progress of subjob of flow
|
||||
subIndexIsPercent?: boolean
|
||||
// Used in individual job test runs
|
||||
compact?: boolean
|
||||
// Removes `Step 1` and replaces it with `Running`
|
||||
hideStepTitle?: boolean
|
||||
length: number
|
||||
class?: string
|
||||
}
|
||||
|
||||
export let error: number | undefined = undefined
|
||||
export let index: number
|
||||
export let subIndex: number | undefined
|
||||
export let subLength: number | undefined
|
||||
export let nextInProgress: boolean = false
|
||||
// Used for displaying progress of subjob of flow
|
||||
export let subIndexIsPercent: boolean = false
|
||||
// Remove padding/margin, border radius and titles
|
||||
// Used in individual job test runs
|
||||
export let compact: boolean = false
|
||||
// Removes `Step 1` and replaces it with `Running`
|
||||
export let hideStepTitle: boolean = false
|
||||
|
||||
export let length: number
|
||||
let {
|
||||
error = undefined,
|
||||
index,
|
||||
subIndex,
|
||||
subLength,
|
||||
nextInProgress = false,
|
||||
subIndexIsPercent = false,
|
||||
compact = false,
|
||||
hideStepTitle = false,
|
||||
length,
|
||||
class: className = ''
|
||||
}: Props = $props()
|
||||
let duration = 200
|
||||
|
||||
let percent = getTween(0, duration)
|
||||
let percent = new Tween(0, { duration, easing: linear })
|
||||
|
||||
export function resetP() {
|
||||
percent = getTween(0, duration)
|
||||
percent.set(0, { duration: 0 })
|
||||
}
|
||||
|
||||
$: percent.set(
|
||||
(length
|
||||
? index / length + (subIndex && subLength ? subIndex / (subLength ?? 1) / length : 0)
|
||||
: 0) * 100
|
||||
)
|
||||
$effect(() => {
|
||||
percent.set(
|
||||
(length
|
||||
? index / length + (subIndex && subLength ? subIndex / (subLength ?? 1) / length : 0)
|
||||
: 0) * 100
|
||||
)
|
||||
})
|
||||
|
||||
function getPercent(partIndex: number, _pct: number) {
|
||||
if (!length) {
|
||||
return 0
|
||||
}
|
||||
|
||||
const res = Math.min(($percent - (partIndex / length) * 100) * length, 100)
|
||||
const res = Math.min((percent.current - (partIndex / length) * 100) * length, 100)
|
||||
return res
|
||||
}
|
||||
|
||||
$: finished = index == length
|
||||
let finished = $derived(index == length)
|
||||
</script>
|
||||
|
||||
<div class={$$props.class}>
|
||||
<div class={className}>
|
||||
{#if !compact}
|
||||
<div
|
||||
class="flex justify-between items-end font-medium mb-1 {error != undefined
|
||||
? 'text-red-700 dark:text-red-200'
|
||||
: 'text-blue-700 dark:text-blue-200'}"
|
||||
>
|
||||
<span class="text-base">
|
||||
{error != undefined
|
||||
? 'Error occured'
|
||||
: finished
|
||||
? 'Done'
|
||||
: hideStepTitle
|
||||
? `Running`
|
||||
: subIndexIsPercent
|
||||
? `Step ${index + 1} (${subIndex !== undefined ? `${subIndex}%)` : ''}`
|
||||
: `Step ${index + 1}${subIndex !== undefined ? `.${subIndex + 1}` : ''}`}
|
||||
</span>
|
||||
<span class="text-sm">
|
||||
{$percent.toFixed(0)}%
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="flex justify-between items-end font-medium mb-1 {error != undefined
|
||||
? 'text-red-700 dark:text-red-200'
|
||||
: 'text-blue-700 dark:text-blue-200'}"
|
||||
>
|
||||
<span class="text-base">
|
||||
{error != undefined
|
||||
? 'Error occured'
|
||||
: finished
|
||||
? 'Done'
|
||||
: hideStepTitle
|
||||
? `Running`
|
||||
: subIndexIsPercent
|
||||
? `Step ${index + 1} (${subIndex !== undefined ? `${subIndex}%)` : ''}`
|
||||
: `Step ${index + 1}${subIndex !== undefined ? `.${subIndex + 1}` : ''}`}
|
||||
</span>
|
||||
<span class="text-sm">
|
||||
{percent.current.toFixed(0)}%
|
||||
</span>
|
||||
</div>
|
||||
{/if}
|
||||
<!-- {#each state as step, index}
|
||||
{index} {JSON.stringify(step)}
|
||||
@@ -82,10 +93,12 @@
|
||||
{getPercent(index)}
|
||||
|
|
||||
{/each} -->
|
||||
<div class={twMerge(
|
||||
"flex w-full bg-gray-200 overflow-hidden",
|
||||
(compact) ? "rounded-none h-3" : "rounded-full h-4",
|
||||
)}>
|
||||
<div
|
||||
class={twMerge(
|
||||
'flex w-full bg-gray-200 overflow-hidden',
|
||||
compact ? 'rounded-none h-3' : 'rounded-full h-4'
|
||||
)}
|
||||
>
|
||||
{#each new Array(length) as _, partIndex (partIndex)}
|
||||
<div class="h-full relative border-white {partIndex === 0 ? '' : 'border-l'} w-full">
|
||||
{#if partIndex == index && nextInProgress}
|
||||
@@ -101,7 +114,7 @@
|
||||
class="absolute left-0 bottom-0 h-full {error == partIndex
|
||||
? 'bg-red-400'
|
||||
: 'bg-blue-400'}"
|
||||
style="width: {getPercent(partIndex, $percent)}%"
|
||||
style="width: {getPercent(partIndex, percent.current)}%"
|
||||
></div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user