Merge branch 'server-workflows' of https://github.com/Budibase/budibase into server-workflows

This commit is contained in:
mike12345567 2020-09-10 11:44:59 +01:00
commit 9c20dba77b
11 changed files with 16 additions and 122 deletions

View File

@ -15,7 +15,6 @@
</script> </script>
<div class="container"> <div class="container">
<!-- <label class="selected-label">{workflowBlock.type}: {workflowBlock.name}</label> -->
{#each workflowParams as [parameter, type]} {#each workflowParams as [parameter, type]}
<div class="block-field"> <div class="block-field">
<label class="label">{parameter}</label> <label class="label">{parameter}</label>

View File

@ -13,8 +13,6 @@
$: selected = $: selected =
$workflowStore.selectedWorkflowBlock != null && $workflowStore.selectedWorkflowBlock != null &&
$workflowStore.selectedWorkflowBlock.id === block.id $workflowStore.selectedWorkflowBlock.id === block.id
console.log(selected)
</script> </script>
<div <div

View File

@ -1,12 +1,9 @@
<script> <script>
import { onMount } from "svelte" import { workflowStore } from "builderStore"
import { backendUiStore, workflowStore } from "builderStore"
import WorkflowList from "./WorkflowList/WorkflowList.svelte" import WorkflowList from "./WorkflowList/WorkflowList.svelte"
import BlockList from "./BlockList/BlockList.svelte" import BlockList from "./BlockList/BlockList.svelte"
import blockDefinitions from "./blockDefinitions"
let selectedTab = "WORKFLOWS" let selectedTab = "WORKFLOWS"
let definitions = []
</script> </script>
<header> <header>

View File

@ -1,5 +1,4 @@
import { authenticate } from "./authenticate" import { authenticate } from "./authenticate"
import { triggerWorkflow } from "./workflow"
import appStore from "../state/store" import appStore from "../state/store"
const apiCall = method => async ({ url, body }) => { const apiCall = method => async ({ url, body }) => {
@ -55,5 +54,4 @@ const apiOpts = {
export default { export default {
authenticate: authenticate(apiOpts), authenticate: authenticate(apiOpts),
triggerWorkflow: triggerWorkflow(apiOpts),
} }

View File

@ -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
}
},
}

View File

@ -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)
}

View File

@ -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)
}
}
}

View File

@ -1,5 +1,3 @@
import api from "../api"
export const EVENT_TYPE_MEMBER_NAME = "##eventHandlerType" export const EVENT_TYPE_MEMBER_NAME = "##eventHandlerType"
export const eventHandlers = routeTo => { export const eventHandlers = routeTo => {
@ -10,7 +8,6 @@ export const eventHandlers = routeTo => {
return { return {
"Navigate To": handler(["url"], param => routeTo(param && param.url)), "Navigate To": handler(["url"], param => routeTo(param && param.url)),
"Trigger Workflow": handler(["workflow"], api.triggerWorkflow),
} }
} }

View File

@ -0,0 +1,5 @@
const wait = ms => new Promise(resolve => setTimeout(resolve, ms))
module.exports = async function delay({ args }) {
await wait(args.time)
}

View File

@ -0,0 +1,10 @@
module.exports = async function filter({ args }) {
const { field, condition, value } = args
switch (condition) {
case "equals":
if (field !== value) return
break
default:
return
}
}

View File

@ -37,8 +37,6 @@ exports.serverStrategy = () => ({
}, },
run: async function(workflow, context) { run: async function(workflow, context) {
for (let block of workflow.steps) { for (let block of workflow.steps) {
if (block.type === "CLIENT") continue
const action = require(`../api/controllers/workflow/actions/${block.actionId}`) const action = require(`../api/controllers/workflow/actions/${block.actionId}`)
const response = await action({ const response = await action({
args: this.bindContextArgs(block.args), args: this.bindContextArgs(block.args),