From c049838fd23873c6b8173e452d52c8e30eace28c Mon Sep 17 00:00:00 2001 From: Ruben Fiszel Date: Wed, 2 Nov 2022 10:43:19 +0100 Subject: [PATCH] approvers are available to the step right after approval --- backend/windmill-worker/src/worker_flow.rs | 10 +++++ frontend/src/lib/components/ArgInfo.svelte | 2 +- frontend/src/lib/components/JobStatus.svelte | 4 +- .../src/lib/components/ScriptBuilder.svelte | 41 +++++++++-------- .../components/common/button/Button.svelte | 5 ++- .../flows/content/FlowBranchOneWrapper.svelte | 9 ++-- .../flows/content/FlowBranchesWrapper.svelte | 10 +++-- .../flows/content/FlowEditorPanel.svelte | 5 +-- .../flows/content/FlowInputs.svelte | 20 ++++----- .../components/flows/content/FlowLoop.svelte | 17 ++++--- .../flows/content/FlowModuleComponent.svelte | 17 ++++--- .../flows/content/FlowModuleEarlyStop.svelte | 4 +- .../flows/content/FlowModuleWrapper.svelte | 28 +++++++----- .../lib/components/flows/previousResults.ts | 22 ++++++---- frontend/src/lib/script_helpers.ts | 19 ++++---- frontend/src/lib/utils.ts | 2 +- .../[job]/[resume]/[hmac]@none.svelte | 22 ++++++---- frontend/src/routes/run/[...run].svelte | 44 ++++--------------- 18 files changed, 149 insertions(+), 132 deletions(-) diff --git a/backend/windmill-worker/src/worker_flow.rs b/backend/windmill-worker/src/worker_flow.rs index 5f501c4498..0d340ca784 100644 --- a/backend/windmill-worker/src/worker_flow.rs +++ b/backend/windmill-worker/src/worker_flow.rs @@ -656,6 +656,7 @@ async fn transform_input( token: &str, steps: Vec, resumes: &[Value], + approvers: Vec, by_id: &IdContext, base_internal_url: &str, ) -> anyhow::Result> { @@ -682,6 +683,7 @@ async fn transform_input( resumes.last().map(|v| json!(v)).unwrap_or_default(), ), ("resumes".to_string(), resumes.clone().into()), + ("approvers".to_string(), json!(approvers.clone())), ]; let v = eval_timeout( @@ -854,6 +856,7 @@ async fn push_next_flow_job( }; let mut resume_messages: Vec = vec![]; + let mut approvers: Vec = vec![]; /* (suspend / resume), when starting a module, if previous module has a * non-zero `suspend` value, collect `resume_job`s for the previous module job. @@ -886,6 +889,12 @@ async fn push_next_flow_job( .await?; resume_messages.extend(resumes.iter().map(|r| r.value.clone())); + approvers.extend(resumes.iter().map(|r| { + r.approver + .as_deref() + .unwrap_or_else(|| "anonymous") + .to_string() + })); let required_events = suspend.required_events.unwrap() as u16; if resume_messages.len() >= required_events as usize { @@ -1087,6 +1096,7 @@ async fn push_next_flow_job( &token, steps.to_vec(), resume_messages.as_slice(), + approvers, by_id, base_internal_url, ) diff --git a/frontend/src/lib/components/ArgInfo.svelte b/frontend/src/lib/components/ArgInfo.svelte index 6ba7149161..d2a6f3d097 100644 --- a/frontend/src/lib/components/ArgInfo.svelte +++ b/frontend/src/lib/components/ArgInfo.svelte @@ -40,7 +40,7 @@ class="text-xs text-blue-500" on:click={async () => { await getResource(value.substring('$res:'.length)) - jsonViewer.openModal() + jsonViewer.toggleDrawer() }}>{value}{:else if asJson.length > 40} {truncate(asJson, 40)} - Job ran in {msToSec(job.duration_ms)} s + Ran in {msToSec(job.duration_ms)} s {:else if job && 'success' in job} @@ -39,7 +39,7 @@ - Job ran in {msToSec(job.duration_ms)}s + Ran in {msToSec(job.duration_ms)}s {:else if job && 'running' in job && job.running} diff --git a/frontend/src/lib/components/ScriptBuilder.svelte b/frontend/src/lib/components/ScriptBuilder.svelte index aca08aabcf..ef2e7b0891 100644 --- a/frontend/src/lib/components/ScriptBuilder.svelte +++ b/frontend/src/lib/components/ScriptBuilder.svelte @@ -200,16 +200,18 @@ />

Metadata

- +
+ +
{#if viewScriptKind} -
+
{/if} {#if script.language == 'deno' && script.kind == Script.kind.SCRIPT} - - +
+
{#if viewTemplate} -
+
} export let parentModule: FlowModule | undefined - export let previousModuleId: string | undefined + export let previousModule: FlowModule | undefined const { previewArgs } = getContext('FlowEditorContext') let editor: SimpleEditor | undefined = undefined @@ -25,9 +25,10 @@ $: pickableProperties = getStepPropPicker( $flowStateStore, parentModule, - previousModuleId, + previousModule, $flowStore, - previewArgs + previewArgs, + true ).pickableProperties @@ -43,7 +44,7 @@ Branch predicate
{ editor?.insertAtCursor(detail) diff --git a/frontend/src/lib/components/flows/content/FlowBranchesWrapper.svelte b/frontend/src/lib/components/flows/content/FlowBranchesWrapper.svelte index e0cbae8c11..691a1c7cc1 100644 --- a/frontend/src/lib/components/flows/content/FlowBranchesWrapper.svelte +++ b/frontend/src/lib/components/flows/content/FlowBranchesWrapper.svelte @@ -12,7 +12,7 @@ export let flowModule: FlowModule export let parentModule: FlowModule | undefined - export let previousModuleId: string | undefined + export let previousModule: FlowModule | undefined let selected: string = 'early-stop' @@ -77,13 +77,17 @@
- +
- +
diff --git a/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte b/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte index 99bfeed27c..ff99ef089e 100644 --- a/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte +++ b/frontend/src/lib/components/flows/content/FlowEditorPanel.svelte @@ -24,10 +24,7 @@ {:else} {#each $flowStore.value.modules as flowModule, index (flowModule.id ?? index)} - + {/each} {/if} {/key} diff --git a/frontend/src/lib/components/flows/content/FlowInputs.svelte b/frontend/src/lib/components/flows/content/FlowInputs.svelte index 495c31b2ee..ae1b2c3f75 100644 --- a/frontend/src/lib/components/flows/content/FlowInputs.svelte +++ b/frontend/src/lib/components/flows/content/FlowInputs.svelte @@ -14,7 +14,7 @@
-
Common script
+
{failureModule ? 'Error handler' : 'Common script'}
{ dispatch('new', { language: RawScript.language.PYTHON3, - kind: 'script', - subkind: failureModule ? 'failure' : 'flow' + kind: failureModule ? 'failure' : 'script', + subkind: 'flow' }) }} /> @@ -36,8 +36,8 @@ on:click={() => { dispatch('new', { language: RawScript.language.DENO, - kind: 'script', - subkind: failureModule ? 'failure' : 'flow' + kind: failureModule ? 'failure' : 'script', + subkind: 'flow' }) }} /> @@ -49,8 +49,8 @@ on:click={() => { dispatch('new', { language: RawScript.language.GO, - kind: 'script', - subkind: failureModule ? 'failure' : 'flow' + kind: failureModule ? 'failure' : 'script', + subkind: 'flow' }) }} /> @@ -81,9 +81,9 @@
Trigger script - Used as a first step most commonly with an internal state and a schedule to watch for changes - on an external system, compute the diff since last time, set the new state. The diffs are - then treated one by one with a for-loop. + Used as a first step most commonly with an internal state and a schedule to watch for + changes on an external system, compute the diff since last time, set the new state. The + diffs are then treated one by one with a for-loop.
diff --git a/frontend/src/lib/components/flows/content/FlowLoop.svelte b/frontend/src/lib/components/flows/content/FlowLoop.svelte index 3648d85fba..2667af8629 100644 --- a/frontend/src/lib/components/flows/content/FlowLoop.svelte +++ b/frontend/src/lib/components/flows/content/FlowLoop.svelte @@ -20,7 +20,7 @@ export let mod: FlowModule export let parentModule: FlowModule | undefined - export let previousModuleId: string | undefined + export let previousModule: FlowModule | undefined let editor: SimpleEditor | undefined = undefined let selected: string = 'early-stop' @@ -28,9 +28,10 @@ $: pickableProperties = getStepPropPicker( $flowStateStore, parentModule, - previousModuleId, + previousModule, $flowStore, - previewArgs + previewArgs, + true ).pickableProperties @@ -52,7 +53,7 @@ {#if mod.value.iterator.type == 'javascript'}
{ editor?.insertAtCursor(detail) @@ -106,13 +107,17 @@
- +
- +
diff --git a/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte b/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte index b535eb4d99..29e8cac4d3 100644 --- a/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte +++ b/frontend/src/lib/components/flows/content/FlowModuleComponent.svelte @@ -31,7 +31,7 @@ export let failureModule: boolean = false export let parentModule: FlowModule | undefined = undefined - export let previousModuleId: string | undefined = undefined + export let previousModule: FlowModule | undefined let editor: Editor let modulePreview: ModulePreview @@ -54,7 +54,14 @@ $: stepPropPicker = failureModule ? { pickableProperties: { previous_result: { error: 'the error message' } }, extraLib: '' } - : getStepPropPicker($flowStateStore, parentModule, previousModuleId, $flowStore, previewArgs) + : getStepPropPicker( + $flowStateStore, + parentModule, + previousModule, + $flowStore, + previewArgs, + true + ) function onKeyDown(event: KeyboardEvent) { if ((event.ctrlKey || event.metaKey) && event.key == 'Enter') { @@ -178,7 +185,7 @@ {#if selected === 'inputs'}
{:else if selected === 'early-stop'} {:else if selected === 'suspend'}
- +
{/if}
diff --git a/frontend/src/lib/components/flows/content/FlowModuleEarlyStop.svelte b/frontend/src/lib/components/flows/content/FlowModuleEarlyStop.svelte index 595294da49..09976cd487 100644 --- a/frontend/src/lib/components/flows/content/FlowModuleEarlyStop.svelte +++ b/frontend/src/lib/components/flows/content/FlowModuleEarlyStop.svelte @@ -12,9 +12,9 @@ const { previewArgs } = getContext('FlowEditorContext') - export let previousModuleId: string | undefined export let flowModule: FlowModule export let parentModule: FlowModule | undefined + export let previousModuleId: string | undefined let editor: SimpleEditor | undefined = undefined @@ -26,7 +26,7 @@ const propPicker = getStepPropPicker( $flowStateStore, parentModule, - flowModule.id, + flowModule, $flowStore, previewArgs ).pickableProperties diff --git a/frontend/src/lib/components/flows/content/FlowModuleWrapper.svelte b/frontend/src/lib/components/flows/content/FlowModuleWrapper.svelte index d6a76b2772..72c8f04470 100644 --- a/frontend/src/lib/components/flows/content/FlowModuleWrapper.svelte +++ b/frontend/src/lib/components/flows/content/FlowModuleWrapper.svelte @@ -28,14 +28,14 @@ // Pointer to parent module, only defined within Branches or Loops. export let parentModule: FlowModule | undefined = undefined // Pointer to previous module, for easy access to testing results - export let previousModuleId: string | undefined = undefined + export let previousModule: FlowModule | undefined = undefined {#if flowModule.id === $selectedId} {#if flowModule.value.type === 'forloopflow'} - + {:else if flowModule.value.type === 'branchone' || flowModule.value.type === 'branchall'} - + {:else if flowModule.value.type === 'identity'} {#if $selectedId == 'failure'} @@ -46,15 +46,19 @@ Steps are retried until they succeed, or until the maximum number of retries defined for that spec is reached, at which point the error handler is called. + {:else} +

Select a step kind Until being defined, this step acts as an identify function, returning as result its + input and assigning it a key 'previous_result' if the input is not a json object

{/if} -

Select a step kind Until being defined, this step acts as an identify function, returning as result its input - and assigning it a key 'previous_result' if the input is not a json object

+ { const [module, state] = await createLoop(flowModule.id) flowModule = module @@ -101,7 +105,7 @@ failureModule={$selectedId === 'failure'} /> {:else if flowModule.value.type === 'rawscript' || flowModule.value.type === 'script'} - + {/if} {:else if flowModule.value.type === 'forloopflow'} {#each flowModule.value.modules as submodule, index (index)} @@ -125,7 +129,7 @@ {/if} {#each flowModule.value.branches as branch, branchIndex (branchIndex)} {#if $selectedId === `${flowModule?.id}-branch-${branchIndex}`} - + {:else} {#each branch.modules as submodule, index} 0)) { + pickableProperties["approvers"] = "The list of approvers" + } return { extraLib: buildExtraLib(objectToTsType(flowInput), objectToTsType(previousResults)), - pickableProperties: { - flow_input: flowInput, - previous_result: previousResults - } + pickableProperties } } diff --git a/frontend/src/lib/script_helpers.ts b/frontend/src/lib/script_helpers.ts index 881fdadc7e..416e39d5f2 100644 --- a/frontend/src/lib/script_helpers.ts +++ b/frontend/src/lib/script_helpers.ts @@ -166,7 +166,7 @@ export async function main(approver?: string) { return wmill.getResumeEndpoints(approver) }` -const ALL_INITIAL_CODE = [PYTHON_INIT_CODE, DENO_INIT_CODE, POSTGRES_INIT_CODE, DENO_INIT_CODE_TRIGGER, DENO_INIT_CODE_CLEAR, PYTHON_INIT_CODE_CLEAR, DENO_INIT_CODE_APPROVAL] +const ALL_INITIAL_CODE = [PYTHON_INIT_CODE, DENO_INIT_CODE, POSTGRES_INIT_CODE, DENO_INIT_CODE_TRIGGER, DENO_INIT_CODE_CLEAR, PYTHON_INIT_CODE_CLEAR, DENO_INIT_CODE_APPROVAL, DENO_FAILURE_MODULE_CODE] export function isInitialCode(content: string): boolean { for (const code of ALL_INITIAL_CODE) { @@ -177,36 +177,37 @@ export function isInitialCode(content: string): boolean { return false } -export function initialCode(language: 'deno' | 'python3' | 'go', kind: Script.kind, subkind: 'pgsql' | 'flow' | 'script' | 'failure' | 'approval' | undefined): string { +export function initialCode(language: 'deno' | 'python3' | 'go', kind: Script.kind, subkind: 'pgsql' | 'flow' | 'script' | undefined): string { if (language === 'deno') { if (kind === 'trigger') { return DENO_INIT_CODE_TRIGGER } else if (kind === 'script') { if (subkind === 'flow') { return DENO_INIT_CODE_CLEAR - } else if (subkind === 'failure') { - return DENO_FAILURE_MODULE_CODE - } else if (subkind === 'approval') { - return DENO_INIT_CODE_APPROVAL } else if (subkind === 'pgsql') { return POSTGRES_INIT_CODE } else { return DENO_INIT_CODE } - } else { + } else if (kind === 'failure') { + return DENO_FAILURE_MODULE_CODE + } else if (kind === 'approval') { + return DENO_INIT_CODE_APPROVAL + } + else { return DENO_INIT_CODE } } else if (language === 'python3') { if (subkind === 'flow') { return PYTHON_INIT_CODE_CLEAR - } else if (subkind === 'failure') { + } else if (kind === 'failure') { return PYTHON_FAILURE_MODULE_CODE } else { return PYTHON_INIT_CODE } } else { - if (subkind === 'failure') { + if (kind === 'failure') { return GO_FAILURE_MODULE_CODE } else { return GO_INIT_CODE diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index 91635b3f63..5c73d063ec 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -276,7 +276,7 @@ export function groupBy( export function truncate(s: string, n: number, suffix: string = '...'): string { if (!s) { - return suffix + return '' } if (s.length <= n) { return s diff --git a/frontend/src/routes/approve/[workspace]/[job]/[resume]/[hmac]@none.svelte b/frontend/src/routes/approve/[workspace]/[job]/[resume]/[hmac]@none.svelte index 11c6bd66bc..9cb5222b8a 100644 --- a/frontend/src/routes/approve/[workspace]/[job]/[resume]/[hmac]@none.svelte +++ b/frontend/src/routes/approve/[workspace]/[job]/[resume]/[hmac]@none.svelte @@ -45,15 +45,19 @@ }) async function getJob() { - const suspendedJobFlow = await JobService.getSuspendedJobFlow({ - workspace: $page.params.workspace, - id: $page.params.job, - resumeId: new Number($page.params.resume).valueOf(), - signature: $page.params.hmac, - approver - }) - job = suspendedJobFlow.job - currentApprovers = suspendedJobFlow.approvers + try { + const suspendedJobFlow = await JobService.getSuspendedJobFlow({ + workspace: $page.params.workspace, + id: $page.params.job, + resumeId: new Number($page.params.resume).valueOf(), + signature: $page.params.hmac, + approver + }) + job = suspendedJobFlow.job + currentApprovers = suspendedJobFlow.approvers + } catch (e) { + sendUserToast(e.message, true) + } } async function resume() { diff --git a/frontend/src/routes/run/[...run].svelte b/frontend/src/routes/run/[...run].svelte index 1d87d93a0d..2c0383ded6 100644 --- a/frontend/src/routes/run/[...run].svelte +++ b/frontend/src/routes/run/[...run].svelte @@ -25,7 +25,6 @@ faScroll, faFastForward } from '@fortawesome/free-solid-svg-icons' - import Tooltip from '$lib/components/Tooltip.svelte' import DisplayResult from '$lib/components/DisplayResult.svelte' import { userStore, workspaceStore } from '$lib/stores' import CenteredPage from '$lib/components/CenteredPage.svelte' @@ -33,10 +32,11 @@ import HighlightCode from '$lib/components/HighlightCode.svelte' import TestJobLoader from '$lib/components/TestJobLoader.svelte' import LogViewer from '$lib/components/LogViewer.svelte' - import { Button, ActionRow, Skeleton } from '$lib/components/common' + import { Button, ActionRow, Skeleton, Tab } from '$lib/components/common' import FlowMetadata from '$lib/components/FlowMetadata.svelte' import JobArgs from '$lib/components/JobArgs.svelte' import FlowProgressBar from '$lib/components/flows/FlowProgressBar.svelte' + import Tabs from '$lib/components/common/tabs/Tabs.svelte' let workspace_id_query: string | undefined = $page.url.searchParams.get('workspace') ?? undefined let workspace_id: string | undefined @@ -252,40 +252,14 @@ {#if job?.job_kind !== 'flow' && job?.job_kind !== 'flowpreview'}