diff --git a/frontend/src/lib/components/FlowStatusWaitingForEvents.svelte b/frontend/src/lib/components/FlowStatusWaitingForEvents.svelte index 195a1d6fad..1b219153da 100644 --- a/frontend/src/lib/components/FlowStatusWaitingForEvents.svelte +++ b/frontend/src/lib/components/FlowStatusWaitingForEvents.svelte @@ -3,7 +3,7 @@ import { type Job, JobService } from '$lib/gen' import { workspaceStore } from '$lib/stores' import { sendUserToast } from '$lib/toast' - import { X } from 'lucide-svelte' + import { ExternalLink, X } from 'lucide-svelte' import DisplayResult from './DisplayResult.svelte' import Tooltip from './Tooltip.svelte' import { Button } from './common' @@ -23,6 +23,7 @@ let default_payload: object = $state({}) let description: any = $state(undefined) let hide_cancel = $state(false) + let approvalPageUrl: string | undefined = $state(undefined) let defaultValues = $state({}) @@ -47,6 +48,8 @@ defaultValues = JSON.parse(JSON.stringify(args)) default_payload = args + approvalPageUrl = job_result?.['approvalPage'] + actionTaken = false hide_cancel = job?.raw_flow?.modules?.[approvalStep]?.suspend?.hide_cancel ?? false schema = mergeSchema( job?.raw_flow?.modules?.[approvalStep]?.suspend?.resume_form?.schema ?? {}, @@ -55,6 +58,7 @@ } let loading = $state(false) + let actionTaken = $state(false) async function continu(approve: boolean) { loading = true try { @@ -66,6 +70,7 @@ approved: approve } }) + actionTaken = true } catch (e: any) { sendUserToast(e?.body ?? e?.message ?? 'Failed', true) } finally { @@ -84,7 +89,7 @@
{/if}
-
+
{#if !hide_cancel}
{/if}
-
+ {#if approvalPageUrl} + + Approval page + + {/if} + {#if job?.raw_flow?.modules?.[approvalStep]?.suspend?.resume_form?.schema}
`${v}`, @@ -36,8 +36,14 @@ } run(() => { - if (value === null) { - value = 0 + if (value === null || value === undefined || Number.isNaN(value)) { + const fallback = + initialValue !== undefined + ? typeof initialValue === 'string' + ? parseInt(initialValue) + : initialValue + : (min ?? 0) + value = Number.isNaN(fallback) ? (min ?? 0) : fallback } }) diff --git a/frontend/src/routes/approve/[workspace]/[job]/+page.svelte b/frontend/src/routes/approve/[workspace]/[job]/+page.svelte index ff664a0297..4055b4e62b 100644 --- a/frontend/src/routes/approve/[workspace]/[job]/+page.svelte +++ b/frontend/src/routes/approve/[workspace]/[job]/+page.svelte @@ -33,6 +33,7 @@ let default_payload: any = $state({}) let loading = $state(false) let valid = $state(true) + let actionTaken: 'approved' | 'denied' | undefined = $state(undefined) let pollInterval: number | undefined = undefined let scheduleEditor: ScheduleEditor | undefined = $state(undefined) @@ -81,6 +82,9 @@ id: page.params.job ?? '' })) as Job completed = job?.type === 'CompletedJob' + if (completed) { + pollInterval && clearInterval(pollInterval) + } } catch { // Job details are optional — page works with just approvalInfo } @@ -103,7 +107,7 @@ } }) sendUserToast('Flow approved') - pollInterval && clearInterval(pollInterval) + actionTaken = 'approved' loadData() } catch (e: any) { sendUserToast(e?.body ?? e?.message ?? 'Failed to approve', true) @@ -125,7 +129,7 @@ } }) sendUserToast('Flow denied!') - pollInterval && clearInterval(pollInterval) + actionTaken = 'denied' loadData() } catch (e: any) { sendUserToast(e?.body ?? e?.message ?? 'Failed to cancel', true) @@ -259,6 +263,12 @@ The flow is not running anymore. You cannot cancel or resume it. + {:else if actionTaken} + + {actionTaken === 'approved' + ? 'You have approved this flow. Waiting for it to complete...' + : 'You have denied this flow. Waiting for it to complete...'} + {/if} {#if approvalInfo.description != undefined} @@ -279,31 +289,20 @@ {/if} {/if} - {#if !completed && approvalInfo.can_approve} + {#if !completed && !actionTaken && approvalInfo.can_approve}
{#if approvalInfo.hide_cancel !== true} - {:else}
{/if} -
- {:else if !completed && !approvalInfo.can_approve} + {:else if !completed && !actionTaken && !approvalInfo.can_approve} {#if approvalInfo.user_auth_required && !$userStore} {:else}