forked from tsai/budibase
5 changed files with 0 additions and 113 deletions
@ -1,18 +0,0 @@ |
|||||
const delay = ms => new Promise(resolve => setTimeout(resolve, ms)) |
|
||||
|
|
||||
export default { |
|
||||
NAVIGATE: () => { |
|
||||
// TODO client navigation
|
|
||||
}, |
|
||||
DELAY: async ({ args }) => await delay(args.time), |
|
||||
FILTER: ({ args }) => { |
|
||||
const { field, condition, value } = args |
|
||||
switch (condition) { |
|
||||
case "equals": |
|
||||
if (field !== value) return |
|
||||
break |
|
||||
default: |
|
||||
return |
|
||||
} |
|
||||
}, |
|
||||
} |
|
||||
@ -1,68 +0,0 @@ |
|||||
import renderTemplateString from "../../state/renderTemplateString" |
|
||||
import appStore from "../../state/store" |
|
||||
import Orchestrator from "./orchestrator" |
|
||||
import clientActions from "./actions" |
|
||||
|
|
||||
// Execute a workflow from a running budibase app
|
|
||||
export const clientStrategy = ({ api }) => ({ |
|
||||
context: {}, |
|
||||
bindContextArgs: function(args) { |
|
||||
const mappedArgs = { ...args } |
|
||||
|
|
||||
// bind the workflow action args to the workflow context, if required
|
|
||||
for (let arg in args) { |
|
||||
const argValue = args[arg] |
|
||||
|
|
||||
// We don't want to render mustache templates on non-strings
|
|
||||
if (typeof argValue !== "string") continue |
|
||||
|
|
||||
// Render the string with values from the workflow context and state
|
|
||||
mappedArgs[arg] = renderTemplateString(argValue, { |
|
||||
context: this.context, |
|
||||
state: appStore.get(), |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
return mappedArgs |
|
||||
}, |
|
||||
run: async function(workflow) { |
|
||||
for (let block of workflow.steps) { |
|
||||
// This code gets run in the browser
|
|
||||
if (block.environment === "CLIENT") { |
|
||||
const action = clientActions[block.actionId] |
|
||||
await action({ |
|
||||
context: this.context, |
|
||||
args: this.bindContextArgs(block.args), |
|
||||
id: block.id, |
|
||||
}) |
|
||||
} |
|
||||
|
|
||||
// this workflow block gets executed on the server
|
|
||||
if (block.environment === "SERVER") { |
|
||||
const EXECUTE_WORKFLOW_URL = `/api/workflows/action` |
|
||||
const response = await api.post({ |
|
||||
url: EXECUTE_WORKFLOW_URL, |
|
||||
body: { |
|
||||
action: block.actionId, |
|
||||
args: this.bindContextArgs(block.args, api), |
|
||||
}, |
|
||||
}) |
|
||||
|
|
||||
this.context = { |
|
||||
...this.context, |
|
||||
[block.actionId]: response, |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}, |
|
||||
}) |
|
||||
|
|
||||
export const triggerWorkflow = api => async ({ workflow }) => { |
|
||||
const workflowOrchestrator = new Orchestrator(api) |
|
||||
workflowOrchestrator.strategy = clientStrategy |
|
||||
|
|
||||
const EXECUTE_WORKFLOW_URL = `/api/workflows/${workflow}` |
|
||||
const workflowDefinition = await api.get({ url: EXECUTE_WORKFLOW_URL }) |
|
||||
|
|
||||
workflowOrchestrator.execute(workflowDefinition) |
|
||||
} |
|
||||
@ -1,22 +0,0 @@ |
|||||
/** |
|
||||
* The workflow orchestrator is a class responsible for executing workflows. |
|
||||
* It relies on the strategy pattern, which allows composable behaviour to be |
|
||||
* passed into its execute() function. This allows custom execution behaviour based |
|
||||
* on where the orchestrator is run. |
|
||||
* |
|
||||
*/ |
|
||||
export default class Orchestrator { |
|
||||
constructor(api) { |
|
||||
this.api = api |
|
||||
} |
|
||||
|
|
||||
set strategy(strategy) { |
|
||||
this._strategy = strategy({ api: this.api }) |
|
||||
} |
|
||||
|
|
||||
async execute(workflow) { |
|
||||
if (workflow.live) { |
|
||||
this._strategy.run(workflow.definition) |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
Loading…
Reference in new issue