diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte
index 584dda361c..49ef579660 100644
--- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte
+++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItemHeader.svelte
@@ -19,6 +19,7 @@
}
}
$: isTrigger = isTrigger || block.type === "TRIGGER"
+ $: status = updateStatus(testResult, isTrigger)
async function onSelect(block) {
await automationStore.update(state => {
@@ -26,6 +27,16 @@
return state
})
}
+
+ function updateStatus(results, isTrigger) {
+ if (results.outputs?.status?.toLowerCase() === "stopped") {
+ return { yellow: true, message: "Stopped" }
+ } else if (results.outputs?.success || isTrigger) {
+ return { positive: true, message: "Success" }
+ } else {
+ return { negative: true, message: "Error" }
+ }
+ }
@@ -69,13 +80,10 @@
{#if showTestStatus && testResult}
{testResult.outputs?.success || isTrigger
- ? "Success"
- : "Error"}{status?.message}
{/if}
diff --git a/packages/builder/src/components/portal/overview/HistoryTab.svelte b/packages/builder/src/components/portal/overview/HistoryTab.svelte
index f77fc0d055..990c899ad2 100644
--- a/packages/builder/src/components/portal/overview/HistoryTab.svelte
+++ b/packages/builder/src/components/portal/overview/HistoryTab.svelte
@@ -8,7 +8,8 @@
import dayjs from "dayjs"
const ERROR = "error",
- SUCCESS = "success"
+ SUCCESS = "success",
+ STOPPED = "stopped"
export let app
let runHistory = null
@@ -37,6 +38,7 @@
const statusOptions = [
{ value: SUCCESS, label: "Success" },
{ value: ERROR, label: "Error" },
+ { value: STOPPED, label: "Stopped" },
]
const runHistorySchema = {
diff --git a/packages/builder/src/components/portal/overview/StatusRenderer.svelte b/packages/builder/src/components/portal/overview/StatusRenderer.svelte
index 13677cfc2d..5f71041809 100644
--- a/packages/builder/src/components/portal/overview/StatusRenderer.svelte
+++ b/packages/builder/src/components/portal/overview/StatusRenderer.svelte
@@ -3,15 +3,28 @@
export let value
$: isError = !value || value.toLowerCase() === "error"
- $: color = isError
- ? "var(--spectrum-semantic-negative-color-background)"
- : "var(--green)"
+ $: isStopped = value?.toLowerCase() === "stopped"
+ $: status = getStatus(isError, isStopped)
+
+ function getStatus(error, stopped) {
+ if (error) {
+ return { color: "var(--red)", message: "Error", icon: "Alert" }
+ } else if (stopped) {
+ return { color: "var(--yellow)", message: "Stopped", icon: "StopCircle" }
+ } else {
+ return {
+ color: "var(--green)",
+ message: "Success",
+ icon: "CheckmarkCircle",
+ }
+ }
+ }
-
-
- {isError ? "Error" : "Success"}
+
+
+ {status.message}
@@ -22,12 +35,4 @@
gap: var(--spacing-m);
align-items: center;
}
-
- .green {
- color: var(--green);
- }
-
- .red {
- color: var(--spectrum-semantic-negative-color-background);
- }
diff --git a/packages/server/src/automations/logging/index.ts b/packages/server/src/automations/logging/index.ts
index c91d2e4950..2467350a4d 100644
--- a/packages/server/src/automations/logging/index.ts
+++ b/packages/server/src/automations/logging/index.ts
@@ -2,8 +2,8 @@ import { getAppId, getProdAppDB } from "@budibase/backend-core/context"
import {
DocumentTypes,
generateAutomationLogID,
- SEPARATOR,
isProdAppID,
+ SEPARATOR,
} from "../../db/utils"
import { Automation, MetadataErrors } from "../../definitions/common"
import { app } from "@budibase/backend-core/cache"
@@ -14,6 +14,7 @@ import {
AutomationResults,
AutomationStatus,
} from "../../definitions/automation"
+
const { logAlert } = require("@budibase/backend-core/logging")
function getStatus(results: AutomationResults) {
@@ -27,6 +28,10 @@ function getStatus(results: AutomationResults) {
}
if (!step.outputs?.success) {
status = AutomationStatus.ERROR
+ break
+ } else if (step.outputs?.status?.toLowerCase() === "stopped") {
+ status = AutomationStatus.STOPPED
+ break
}
}
return status
diff --git a/packages/server/src/automations/steps/filter.js b/packages/server/src/automations/steps/filter.js
index 7dbe0bc649..566bb60f22 100644
--- a/packages/server/src/automations/steps/filter.js
+++ b/packages/server/src/automations/steps/filter.js
@@ -50,43 +50,51 @@ exports.definition = {
outputs: {
properties: {
success: {
+ type: "boolean",
+ description: "Whether the action was successful",
+ },
+ result: {
type: "boolean",
description: "Whether the logic block passed",
},
},
- required: ["success"],
+ required: ["success", "result"],
},
},
}
exports.run = async function filter({ inputs }) {
- let { field, condition, value } = inputs
- // coerce types so that we can use them
- if (!isNaN(value) && !isNaN(field)) {
- value = parseFloat(value)
- field = parseFloat(field)
- } else if (!isNaN(Date.parse(value)) && !isNaN(Date.parse(field))) {
- value = Date.parse(value)
- field = Date.parse(field)
- }
- let success = false
- if (typeof field !== "object" && typeof value !== "object") {
- switch (condition) {
- case FilterConditions.EQUAL:
- success = field === value
- break
- case FilterConditions.NOT_EQUAL:
- success = field !== value
- break
- case FilterConditions.GREATER_THAN:
- success = field > value
- break
- case FilterConditions.LESS_THAN:
- success = field < value
- break
+ try {
+ let { field, condition, value } = inputs
+ // coerce types so that we can use them
+ if (!isNaN(value) && !isNaN(field)) {
+ value = parseFloat(value)
+ field = parseFloat(field)
+ } else if (!isNaN(Date.parse(value)) && !isNaN(Date.parse(field))) {
+ value = Date.parse(value)
+ field = Date.parse(field)
}
- } else {
- success = false
+ let result = false
+ if (typeof field !== "object" && typeof value !== "object") {
+ switch (condition) {
+ case FilterConditions.EQUAL:
+ result = field === value
+ break
+ case FilterConditions.NOT_EQUAL:
+ result = field !== value
+ break
+ case FilterConditions.GREATER_THAN:
+ result = field > value
+ break
+ case FilterConditions.LESS_THAN:
+ result = field < value
+ break
+ }
+ } else {
+ result = false
+ }
+ return { success: true, result }
+ } catch (err) {
+ return { success: false, result: false }
}
- return { success }
}
diff --git a/packages/server/src/definitions/automation.ts b/packages/server/src/definitions/automation.ts
index 1b7eef11e3..8ed339d0a0 100644
--- a/packages/server/src/definitions/automation.ts
+++ b/packages/server/src/definitions/automation.ts
@@ -1,6 +1,7 @@
export enum AutomationStatus {
SUCCESS = "success",
ERROR = "error",
+ STOPPED = "stopped",
}
export interface AutomationResults {
diff --git a/packages/server/src/threads/automation.js b/packages/server/src/threads/automation.js
index a50854732f..4af9461d6a 100644
--- a/packages/server/src/threads/automation.js
+++ b/packages/server/src/threads/automation.js
@@ -14,7 +14,7 @@ const FILTER_STEP_ID = actions.ACTION_DEFINITIONS.FILTER.stepId
const LOOP_STEP_ID = actions.ACTION_DEFINITIONS.LOOP.stepId
const CRON_STEP_ID = triggerDefs.CRON.stepId
-const STOPPED_STATUS = { success: false, status: "STOPPED" }
+const STOPPED_STATUS = { success: true, status: "STOPPED" }
const { cloneDeep } = require("lodash/fp")
const env = require("../environment")
@@ -276,7 +276,7 @@ class Orchestrator {
this._context.steps[stepCount] = outputs
// if filter causes us to stop execution don't break the loop, set a var
// so that we can finish iterating through the steps and record that it stopped
- if (step.stepId === FILTER_STEP_ID && !outputs.success) {
+ if (step.stepId === FILTER_STEP_ID && !outputs.result) {
stopped = true
this.updateExecutionOutput(step.id, step.stepId, step.inputs, {
...outputs,