orchestrator refactor, user creation block
This commit is contained in:
parent
36da2576bc
commit
9a898a8d74
|
@ -1,6 +1,6 @@
|
||||||
import mustache from "mustache"
|
import mustache from "mustache"
|
||||||
// TODO: tidy up import
|
// TODO: tidy up import
|
||||||
import blockDefinitions from "../../../pages/[application]/workflow/WorkflowPanel/blockDefinitions"
|
import blockDefinitions from "../../../components/workflow/WorkflowPanel/blockDefinitions"
|
||||||
import { generate } from "shortid"
|
import { generate } from "shortid"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,7 +79,7 @@ export default class Workflow {
|
||||||
type: block.type,
|
type: block.type,
|
||||||
params: block.params,
|
params: block.params,
|
||||||
args,
|
args,
|
||||||
heading: definition.actionId,
|
heading: block.actionId,
|
||||||
body: mustache.render(tagline, args),
|
body: mustache.render(tagline, args),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
import { isString } from "lodash/fp"
|
// import { isString } from "lodash/fp"
|
||||||
|
|
||||||
import {
|
// import {
|
||||||
BB_STATE_BINDINGPATH,
|
// BB_STATE_BINDINGPATH,
|
||||||
BB_STATE_FALLBACK,
|
// BB_STATE_FALLBACK,
|
||||||
BB_STATE_BINDINGSOURCE,
|
// BB_STATE_BINDINGSOURCE,
|
||||||
isBound,
|
// isBound,
|
||||||
parseBinding,
|
// parseBinding,
|
||||||
} from "@budibase/client/src/state/parseBinding"
|
// } from "@budibase/client/src/state/parseBinding"
|
||||||
|
|
||||||
export const isBinding = isBound
|
// export const isBinding = isBound
|
||||||
|
|
||||||
export const setBinding = ({ path, fallback, source }, binding = {}) => {
|
// export const setBinding = ({ path, fallback, source }, binding = {}) => {
|
||||||
if (isNonEmptyString(path)) binding[BB_STATE_BINDINGPATH] = path
|
// if (isNonEmptyString(path)) binding[BB_STATE_BINDINGPATH] = path
|
||||||
if (isNonEmptyString(fallback)) binding[BB_STATE_FALLBACK] = fallback
|
// if (isNonEmptyString(fallback)) binding[BB_STATE_FALLBACK] = fallback
|
||||||
binding[BB_STATE_BINDINGSOURCE] = source || "store"
|
// binding[BB_STATE_BINDINGSOURCE] = source || "store"
|
||||||
return binding
|
// return binding
|
||||||
}
|
// }
|
||||||
|
|
||||||
export const getBinding = val => {
|
// export const getBinding = val => {
|
||||||
const binding = parseBinding(val)
|
// const binding = parseBinding(val)
|
||||||
return binding
|
// return binding
|
||||||
? binding
|
// ? binding
|
||||||
: {
|
// : {
|
||||||
path: "",
|
// path: "",
|
||||||
source: "store",
|
// source: "store",
|
||||||
fallback: "",
|
// fallback: "",
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
const isNonEmptyString = s => isString(s) && s.length > 0
|
// const isNonEmptyString = s => isString(s) && s.length > 0
|
||||||
|
|
|
@ -43,13 +43,6 @@
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function selectRecord(record) {
|
|
||||||
return await api.loadRecord(record.key, {
|
|
||||||
appname: $store.appname,
|
|
||||||
instanceId: $backendUiStore.selectedDatabase._id,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const ITEMS_PER_PAGE = 10
|
const ITEMS_PER_PAGE = 10
|
||||||
// Internal headers we want to hide from the user
|
// Internal headers we want to hide from the user
|
||||||
const INTERNAL_HEADERS = ["_id", "_rev", "modelId", "type"]
|
const INTERNAL_HEADERS = ["_id", "_rev", "modelId", "type"]
|
||||||
|
|
|
@ -2,8 +2,7 @@
|
||||||
import { backendUiStore } from "builderStore"
|
import { backendUiStore } from "builderStore"
|
||||||
import IconButton from "../common/IconButton.svelte"
|
import IconButton from "../common/IconButton.svelte"
|
||||||
import Input from "../common/Input.svelte"
|
import Input from "../common/Input.svelte"
|
||||||
import PropertyCascader from "./PropertyCascader"
|
// import PropertyCascader from "./PropertyCascader"
|
||||||
import { isBinding, getBinding, setBinding } from "../common/binding"
|
|
||||||
import Colorpicker from "../common/Colorpicker.svelte"
|
import Colorpicker from "../common/Colorpicker.svelte"
|
||||||
|
|
||||||
export let value = ""
|
export let value = ""
|
||||||
|
@ -50,7 +49,7 @@
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
{:else}
|
{:else}
|
||||||
<PropertyCascader {onChanged} {value} />
|
<!-- <PropertyCascader {onChanged} {value} /> -->
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
let params
|
let params
|
||||||
|
|
||||||
|
console.log("wfblock", workflowBlock)
|
||||||
|
|
||||||
$: workflowParams = workflowBlock.params
|
$: workflowParams = workflowBlock.params
|
||||||
? Object.entries(workflowBlock.params)
|
? Object.entries(workflowBlock.params)
|
||||||
: []
|
: []
|
||||||
|
@ -13,7 +15,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label class="uk-form-label">
|
<label class="uk-form-label">
|
||||||
{workflowBlock.type}: {workflowBlock.heading}
|
{workflowBlock.type}: {workflowBlock.actionId}
|
||||||
</label>
|
</label>
|
||||||
{#each workflowParams as [parameter, type]}
|
{#each workflowParams as [parameter, type]}
|
||||||
<div class="uk-margin block-field">
|
<div class="uk-margin block-field">
|
||||||
|
@ -27,6 +29,18 @@
|
||||||
<option value={option}>{option}</option>
|
<option value={option}>{option}</option>
|
||||||
{/each}
|
{/each}
|
||||||
</select>
|
</select>
|
||||||
|
{:else if type === 'accessLevel'}
|
||||||
|
<select
|
||||||
|
class="budibase__input"
|
||||||
|
bind:value={workflowBlock.args[parameter]}>
|
||||||
|
<option value="ADMIN">Admin</option>
|
||||||
|
<option value="POWER_USER">Power User</option>
|
||||||
|
</select>
|
||||||
|
{:else if type === 'password'}
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
class="budibase__input"
|
||||||
|
bind:value={workflowBlock.args[parameter]} />
|
||||||
{:else if type === 'number'}
|
{:else if type === 'number'}
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
|
|
|
@ -49,13 +49,14 @@ const ACTION = {
|
||||||
},
|
},
|
||||||
CREATE_USER: {
|
CREATE_USER: {
|
||||||
description: "Create a new user.",
|
description: "Create a new user.",
|
||||||
|
tagline: "Create user <b>{{username}}</b>",
|
||||||
icon: "ri-user-add-fill",
|
icon: "ri-user-add-fill",
|
||||||
name: "Create User",
|
name: "Create User",
|
||||||
environment: "SERVER",
|
environment: "SERVER",
|
||||||
params: {
|
params: {
|
||||||
name: "string",
|
username: "string",
|
||||||
password: "password",
|
password: "password",
|
||||||
accessLevel: "accessLevel",
|
accessLevelId: "accessLevel",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
SEND_EMAIL: {
|
SEND_EMAIL: {
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import get from "lodash/fp/get"
|
import { get } from "svelte/store";
|
||||||
|
import { setState } from "../../state/setState";
|
||||||
import mustache from "mustache";
|
import mustache from "mustache";
|
||||||
|
import { appStore } from "../../state/store";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The workflow orchestrator is a class responsible for executing workflows.
|
* The workflow orchestrator is a class responsible for executing workflows.
|
||||||
|
@ -15,25 +17,21 @@ export default class Orchestrator {
|
||||||
}
|
}
|
||||||
|
|
||||||
set strategy(strategy) {
|
set strategy(strategy) {
|
||||||
this._strategy = strategy
|
this._strategy = strategy({ api: this.api, instanceId: this.instanceId });
|
||||||
}
|
}
|
||||||
|
|
||||||
async execute(workflowId) {
|
async execute(workflowId) {
|
||||||
const EXECUTE_WORKFLOW_URL = `/api/${this.instanceId}/workflows/${workflowId}`
|
const EXECUTE_WORKFLOW_URL = `/api/${this.instanceId}/workflows/${workflowId}`
|
||||||
const workflow = await this.api.get({ url: EXECUTE_WORKFLOW_URL })
|
const workflow = await this.api.get({ url: EXECUTE_WORKFLOW_URL })
|
||||||
this._strategy.run({
|
this._strategy.run(workflow.definition)
|
||||||
workflow: workflow.definition,
|
|
||||||
api: this.api,
|
|
||||||
instanceId: this.instanceId,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute a workflow from a running budibase app
|
// Execute a workflow from a running budibase app
|
||||||
export const clientStrategy = {
|
export const clientStrategy = ({ api, instanceId }) => ({
|
||||||
delay: ms => new Promise(resolve => setTimeout(resolve, ms)),
|
delay: ms => new Promise(resolve => setTimeout(resolve, ms)),
|
||||||
context: {},
|
context: {},
|
||||||
bindContextArgs: function(args, api) {
|
bindContextArgs: function(args) {
|
||||||
const mappedArgs = { ...args }
|
const mappedArgs = { ...args }
|
||||||
|
|
||||||
console.log("original args", args)
|
console.log("original args", args)
|
||||||
|
@ -42,35 +40,18 @@ export const clientStrategy = {
|
||||||
for (let arg in args) {
|
for (let arg in args) {
|
||||||
const argValue = args[arg]
|
const argValue = args[arg]
|
||||||
// Means that it's bound to state or workflow context
|
// Means that it's bound to state or workflow context
|
||||||
|
console.log(argValue, get(appStore));
|
||||||
mappedArgs[arg] = mustache.render(argValue, {
|
mappedArgs[arg] = mustache.render(argValue, {
|
||||||
context: this.context,
|
context: this.context,
|
||||||
// TODO: map to the real state
|
state: get(appStore)
|
||||||
state: {}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// if (argValue.startsWith("$")) {
|
|
||||||
// // if value is bound to workflow context.
|
|
||||||
// if (argValue.startsWith("$context")) {
|
|
||||||
// const path = argValue.replace("$context.", "")
|
|
||||||
// // pass in the value from context
|
|
||||||
// mappedArgs[arg] = get(path, this.context)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // if the value is bound to state
|
|
||||||
// if (argValue.startsWith("$state")) {
|
|
||||||
// const path = argValue.replace("$state.", "")
|
|
||||||
// // pass in the value from state
|
|
||||||
// // TODO: not working
|
|
||||||
// mappedArgs[arg] = api.getState(path)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
console.log(mappedArgs)
|
console.log(mappedArgs)
|
||||||
|
|
||||||
return Object.values(mappedArgs)
|
return mappedArgs
|
||||||
},
|
},
|
||||||
run: async function({ workflow, api, instanceId }) {
|
run: async function(workflow) {
|
||||||
const block = workflow.next
|
const block = workflow.next
|
||||||
|
|
||||||
console.log("Executing workflow block", block)
|
console.log("Executing workflow block", block)
|
||||||
|
@ -81,7 +62,7 @@ export const clientStrategy = {
|
||||||
if (block.environment === "CLIENT") {
|
if (block.environment === "CLIENT") {
|
||||||
if (block.actionId === "SET_STATE") {
|
if (block.actionId === "SET_STATE") {
|
||||||
// get props from the workflow context if required
|
// get props from the workflow context if required
|
||||||
api.setState(...this.bindContextArgs(block.args))
|
setState(...Object.values(this.bindContextArgs(block.args)))
|
||||||
// update the context with the data
|
// update the context with the data
|
||||||
this.context = {
|
this.context = {
|
||||||
...this.context,
|
...this.context,
|
||||||
|
@ -135,7 +116,6 @@ export const clientStrategy = {
|
||||||
|
|
||||||
console.log("workflowContext", this.context)
|
console.log("workflowContext", this.context)
|
||||||
|
|
||||||
// TODO: clean this up, don't pass all those args
|
await this.run(workflow.next)
|
||||||
await this.run({ workflow: workflow.next, instanceId, api })
|
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import regexparam from "regexparam"
|
import regexparam from "regexparam"
|
||||||
import { routerStore } from "../state/store";
|
import { routerStore } from "../state/store";
|
||||||
|
import { initRouteStore } from "../state/store"
|
||||||
|
|
||||||
// TODO: refactor
|
// TODO: refactor
|
||||||
export const screenRouter = ({ screens, onScreenSelected, appRootPath }) => {
|
export const screenRouter = ({ screens, onScreenSelected, appRootPath }) => {
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
const userController = require("../../user")
|
||||||
|
|
||||||
|
module.exports = async function createUser(user) {
|
||||||
|
console.log("SAVING this user", user)
|
||||||
|
|
||||||
|
const ctx = {
|
||||||
|
params: {
|
||||||
|
instanceId: "inst_60dd510_700f7dc06735403e81d5af91072d7241",
|
||||||
|
},
|
||||||
|
request: {
|
||||||
|
body: user
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await userController.create(ctx)
|
||||||
|
return {
|
||||||
|
user: response
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
return {
|
||||||
|
user: null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,9 +2,11 @@ const viewController = require("../api/controllers/view")
|
||||||
const modelController = require("../api/controllers/model")
|
const modelController = require("../api/controllers/model")
|
||||||
const workflowController = require("../api/controllers/workflow")
|
const workflowController = require("../api/controllers/workflow")
|
||||||
|
|
||||||
|
// Access Level IDs
|
||||||
const ADMIN_LEVEL_ID = "ADMIN"
|
const ADMIN_LEVEL_ID = "ADMIN"
|
||||||
const POWERUSER_LEVEL_ID = "POWER_USER"
|
const POWERUSER_LEVEL_ID = "POWER_USER"
|
||||||
|
|
||||||
|
// Permissions
|
||||||
const READ_MODEL = "read-model"
|
const READ_MODEL = "read-model"
|
||||||
const WRITE_MODEL = "write-model"
|
const WRITE_MODEL = "write-model"
|
||||||
const READ_VIEW = "read-view"
|
const READ_VIEW = "read-view"
|
||||||
|
|
Loading…
Reference in New Issue