Load workflow blocks from server and remove block definitions from builder
This commit is contained in:
parent
32c331f3f8
commit
c280a634fb
|
@ -1,5 +1,4 @@
|
||||||
import mustache from "mustache"
|
import mustache from "mustache"
|
||||||
import blockDefinitions from "components/workflow/WorkflowPanel/blockDefinitions"
|
|
||||||
import { generate } from "shortid"
|
import { generate } from "shortid"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -7,8 +6,9 @@ import { generate } from "shortid"
|
||||||
* Workflow definitions are stored in linked lists.
|
* Workflow definitions are stored in linked lists.
|
||||||
*/
|
*/
|
||||||
export default class Workflow {
|
export default class Workflow {
|
||||||
constructor(workflow) {
|
constructor(workflow, blockDefinitions) {
|
||||||
this.workflow = workflow
|
this.workflow = workflow
|
||||||
|
this.blockDefinitions = blockDefinitions
|
||||||
}
|
}
|
||||||
|
|
||||||
hasTrigger() {
|
hasTrigger() {
|
||||||
|
@ -56,12 +56,14 @@ export default class Workflow {
|
||||||
|
|
||||||
createUiTree() {
|
createUiTree() {
|
||||||
if (!this.workflow.definition) return []
|
if (!this.workflow.definition) return []
|
||||||
return Workflow.buildUiTree(this.workflow.definition)
|
return Workflow.buildUiTree(this.workflow.definition, this.blockDefinitions)
|
||||||
}
|
}
|
||||||
|
|
||||||
static buildUiTree(definition) {
|
static buildUiTree(definition, blockDefinitions) {
|
||||||
const steps = []
|
const steps = []
|
||||||
if (definition.trigger) steps.push(definition.trigger)
|
if (definition.trigger) {
|
||||||
|
steps.push(definition.trigger)
|
||||||
|
}
|
||||||
|
|
||||||
return [...steps, ...definition.steps].map(step => {
|
return [...steps, ...definition.steps].map(step => {
|
||||||
// The client side display definition for the block
|
// The client side display definition for the block
|
||||||
|
|
|
@ -4,11 +4,20 @@ import Workflow from "./Workflow"
|
||||||
|
|
||||||
const workflowActions = store => ({
|
const workflowActions = store => ({
|
||||||
fetch: async () => {
|
fetch: async () => {
|
||||||
const WORKFLOWS_URL = `/api/workflows`
|
const responses = await Promise.all([
|
||||||
const workflowResponse = await api.get(WORKFLOWS_URL)
|
api.get(`/api/workflows`),
|
||||||
const json = await workflowResponse.json()
|
api.get(`/api/workflows/trigger/list`),
|
||||||
|
api.get(`/api/workflows/action/list`),
|
||||||
|
api.get(`/api/workflows/logic/list`),
|
||||||
|
])
|
||||||
|
const jsonResponses = await Promise.all(responses.map(x => x.json()))
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
state.workflows = json
|
state.workflows = jsonResponses[0]
|
||||||
|
state.blockDefinitions = {
|
||||||
|
TRIGGER: jsonResponses[1],
|
||||||
|
ACTION: jsonResponses[2],
|
||||||
|
LOGIC: jsonResponses[3],
|
||||||
|
}
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -24,7 +33,10 @@ const workflowActions = store => ({
|
||||||
const json = await response.json()
|
const json = await response.json()
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
state.workflows = state.workflows.concat(json.workflow)
|
state.workflows = state.workflows.concat(json.workflow)
|
||||||
state.currentWorkflow = new Workflow(json.workflow)
|
state.currentWorkflow = new Workflow(
|
||||||
|
json.workflow,
|
||||||
|
state.blockDefinitions
|
||||||
|
)
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -38,7 +50,10 @@ const workflowActions = store => ({
|
||||||
)
|
)
|
||||||
state.workflows.splice(existingIdx, 1, json.workflow)
|
state.workflows.splice(existingIdx, 1, json.workflow)
|
||||||
state.workflows = state.workflows
|
state.workflows = state.workflows
|
||||||
state.currentWorkflow = new Workflow(json.workflow)
|
state.currentWorkflow = new Workflow(
|
||||||
|
json.workflow,
|
||||||
|
state.blockDefinitions
|
||||||
|
)
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -72,7 +87,7 @@ const workflowActions = store => ({
|
||||||
},
|
},
|
||||||
select: workflow => {
|
select: workflow => {
|
||||||
store.update(state => {
|
store.update(state => {
|
||||||
state.currentWorkflow = new Workflow(workflow)
|
state.currentWorkflow = new Workflow(workflow, state.blockDefinitions)
|
||||||
state.selectedWorkflowBlock = null
|
state.selectedWorkflowBlock = null
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
|
@ -96,11 +111,14 @@ const workflowActions = store => ({
|
||||||
export const getWorkflowStore = () => {
|
export const getWorkflowStore = () => {
|
||||||
const INITIAL_WORKFLOW_STATE = {
|
const INITIAL_WORKFLOW_STATE = {
|
||||||
workflows: [],
|
workflows: [],
|
||||||
|
blockDefinitions: {
|
||||||
|
TRIGGER: [],
|
||||||
|
ACTION: [],
|
||||||
|
LOGIC: [],
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
const store = writable(INITIAL_WORKFLOW_STATE)
|
const store = writable(INITIAL_WORKFLOW_STATE)
|
||||||
|
|
||||||
store.actions = workflowActions(store)
|
store.actions = workflowActions(store)
|
||||||
|
|
||||||
return store
|
return store
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { onMount } from "svelte"
|
import { workflowStore } from "builderStore"
|
||||||
import { backendUiStore, workflowStore } from "builderStore"
|
|
||||||
import WorkflowList from "../WorkflowList/WorkflowList.svelte"
|
|
||||||
import WorkflowBlock from "./WorkflowBlock.svelte"
|
import WorkflowBlock from "./WorkflowBlock.svelte"
|
||||||
import blockDefinitions from "../blockDefinitions"
|
|
||||||
import FlatButtonGroup from "components/userInterface/FlatButtonGroup.svelte"
|
import FlatButtonGroup from "components/userInterface/FlatButtonGroup.svelte"
|
||||||
|
|
||||||
let selectedTab = "TRIGGER"
|
let selectedTab = "TRIGGER"
|
||||||
|
@ -17,7 +14,7 @@
|
||||||
{ value: "LOGIC", text: "Logic" },
|
{ value: "LOGIC", text: "Logic" },
|
||||||
]
|
]
|
||||||
|
|
||||||
$: definitions = Object.entries(blockDefinitions[selectedTab])
|
$: definitions = Object.entries($workflowStore.blockDefinitions[selectedTab])
|
||||||
$: {
|
$: {
|
||||||
if (
|
if (
|
||||||
$workflowStore.currentWorkflow.hasTrigger() &&
|
$workflowStore.currentWorkflow.hasTrigger() &&
|
||||||
|
|
|
@ -1,170 +0,0 @@
|
||||||
const ACTION = {
|
|
||||||
SET_STATE: {
|
|
||||||
name: "Update UI State",
|
|
||||||
tagline: "Update <b>{{path}}</b> to <b>{{value}}</b>",
|
|
||||||
icon: "ri-refresh-line",
|
|
||||||
description: "Update your User Interface with some data.",
|
|
||||||
environment: "CLIENT",
|
|
||||||
params: {
|
|
||||||
path: "string",
|
|
||||||
value: "longText",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
NAVIGATE: {
|
|
||||||
name: "Navigate",
|
|
||||||
tagline: "Navigate to <b>{{url}}</b>",
|
|
||||||
icon: "ri-navigation-line",
|
|
||||||
description: "Navigate to another page.",
|
|
||||||
environment: "CLIENT",
|
|
||||||
params: {
|
|
||||||
url: "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SAVE_RECORD: {
|
|
||||||
name: "Save Record",
|
|
||||||
tagline: "<b>Save</b> a <b>{{record.model.name}}</b> record",
|
|
||||||
icon: "ri-save-3-fill",
|
|
||||||
description: "Save a record to your database.",
|
|
||||||
environment: "SERVER",
|
|
||||||
params: {
|
|
||||||
record: "record",
|
|
||||||
},
|
|
||||||
args: {
|
|
||||||
record: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DELETE_RECORD: {
|
|
||||||
description: "Delete a record from your database.",
|
|
||||||
icon: "ri-delete-bin-line",
|
|
||||||
name: "Delete Record",
|
|
||||||
tagline: "<b>Delete</b> a <b>{{record.model.name}}</b> record",
|
|
||||||
environment: "SERVER",
|
|
||||||
params: {
|
|
||||||
record: "record",
|
|
||||||
},
|
|
||||||
args: {
|
|
||||||
record: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// FIND_RECORD: {
|
|
||||||
// description: "Find a record in your database.",
|
|
||||||
// tagline: "<b>Find</b> a <b>{{record.model.name}}</b> record",
|
|
||||||
// icon: "ri-search-line",
|
|
||||||
// name: "Find Record",
|
|
||||||
// environment: "SERVER",
|
|
||||||
// params: {
|
|
||||||
// record: "string",
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
CREATE_USER: {
|
|
||||||
description: "Create a new user.",
|
|
||||||
tagline: "Create user <b>{{username}}</b>",
|
|
||||||
icon: "ri-user-add-fill",
|
|
||||||
name: "Create User",
|
|
||||||
environment: "SERVER",
|
|
||||||
params: {
|
|
||||||
username: "string",
|
|
||||||
password: "password",
|
|
||||||
accessLevelId: "accessLevel",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
SEND_EMAIL: {
|
|
||||||
description: "Send an email.",
|
|
||||||
tagline: "Send email to <b>{{to}}</b>",
|
|
||||||
icon: "ri-mail-open-fill",
|
|
||||||
name: "Send Email",
|
|
||||||
environment: "SERVER",
|
|
||||||
params: {
|
|
||||||
to: "string",
|
|
||||||
from: "string",
|
|
||||||
subject: "longText",
|
|
||||||
text: "longText",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const TRIGGER = {
|
|
||||||
RECORD_SAVED: {
|
|
||||||
name: "Record Saved",
|
|
||||||
event: "record:save",
|
|
||||||
icon: "ri-save-line",
|
|
||||||
tagline: "Record is added to <b>{{model.name}}</b>",
|
|
||||||
description: "Save a record to your database.",
|
|
||||||
environment: "SERVER",
|
|
||||||
params: {
|
|
||||||
model: "model",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
RECORD_DELETED: {
|
|
||||||
name: "Record Deleted",
|
|
||||||
event: "record:delete",
|
|
||||||
icon: "ri-delete-bin-line",
|
|
||||||
tagline: "Record is deleted from <b>{{model.name}}</b>",
|
|
||||||
description: "Fired when a record is deleted from your database.",
|
|
||||||
environment: "SERVER",
|
|
||||||
params: {
|
|
||||||
model: "model",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
// CLICK: {
|
|
||||||
// name: "Click",
|
|
||||||
// icon: "ri-cursor-line",
|
|
||||||
// tagline: "{{component}} is clicked",
|
|
||||||
// description: "Trigger when you click on an element in the UI.",
|
|
||||||
// environment: "CLIENT",
|
|
||||||
// params: {
|
|
||||||
// component: "component"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// LOAD: {
|
|
||||||
// name: "Load",
|
|
||||||
// icon: "ri-loader-line",
|
|
||||||
// tagline: "{{component}} is loaded",
|
|
||||||
// description: "Trigger an element has finished loading.",
|
|
||||||
// environment: "CLIENT",
|
|
||||||
// params: {
|
|
||||||
// component: "component"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// INPUT: {
|
|
||||||
// name: "Input",
|
|
||||||
// icon: "ri-text",
|
|
||||||
// tagline: "Text entered into {{component}",
|
|
||||||
// description: "Trigger when you type into an input box.",
|
|
||||||
// environment: "CLIENT",
|
|
||||||
// params: {
|
|
||||||
// component: "component"
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
}
|
|
||||||
|
|
||||||
const LOGIC = {
|
|
||||||
FILTER: {
|
|
||||||
name: "Filter",
|
|
||||||
tagline: "{{field}} <b>{{condition}}</b> {{value}}",
|
|
||||||
icon: "ri-git-branch-line",
|
|
||||||
description: "Filter any workflows which do not meet certain conditions.",
|
|
||||||
environment: "CLIENT",
|
|
||||||
params: {
|
|
||||||
filter: "string",
|
|
||||||
condition: ["equals"],
|
|
||||||
value: "string",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
DELAY: {
|
|
||||||
name: "Delay",
|
|
||||||
icon: "ri-time-fill",
|
|
||||||
tagline: "Delay for <b>{{time}}</b> milliseconds",
|
|
||||||
description: "Delay the workflow until an amount of time has passed.",
|
|
||||||
environment: "CLIENT",
|
|
||||||
params: {
|
|
||||||
time: "number",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export default {
|
|
||||||
ACTION,
|
|
||||||
TRIGGER,
|
|
||||||
LOGIC,
|
|
||||||
}
|
|
Loading…
Reference in New Issue