tidy up, styling
This commit is contained in:
parent
401b6689bc
commit
3a983cea8a
|
@ -9,6 +9,17 @@
|
|||
|
||||
const { open, close } = getContext("simple-modal")
|
||||
|
||||
const ACCESS_LEVELS = [
|
||||
{
|
||||
name: "Admin",
|
||||
key: "ADMIN"
|
||||
},
|
||||
{
|
||||
name: "Power User",
|
||||
key: "POWER_USER"
|
||||
}
|
||||
];
|
||||
|
||||
let selectedTab = "SETUP"
|
||||
let testResult
|
||||
|
||||
|
@ -92,16 +103,14 @@
|
|||
</div>
|
||||
<div class="uk-margin config-item">
|
||||
<label class="uk-form-label">User Access</label>
|
||||
<label>
|
||||
<input class="uk-checkbox" type="checkbox" name="radio1" />
|
||||
Admin
|
||||
</label>
|
||||
<br />
|
||||
<label>
|
||||
<input class="uk-checkbox" type="checkbox" name="radio1" />
|
||||
Power User
|
||||
</label>
|
||||
<br />
|
||||
<div class="access-levels">
|
||||
{#each ACCESS_LEVELS as { name, key }}
|
||||
<span class="access-level">
|
||||
<label>{name}</label>
|
||||
<input class="uk-checkbox" type="checkbox" />
|
||||
</span>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="workflow-button hoverable" on:click={deleteWorkflow}>
|
||||
|
@ -161,6 +170,21 @@
|
|||
font-weight: 500;
|
||||
}
|
||||
|
||||
.workflow-button:hover {
|
||||
background: var(--light-grey);
|
||||
}
|
||||
|
||||
.access-level {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.access-level label {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.test-result {
|
||||
border: none;
|
||||
width: 100%;
|
||||
|
|
|
@ -119,4 +119,8 @@
|
|||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.new-workflow-button:hover {
|
||||
background: var(--light-grey);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -46,16 +46,16 @@ const ACTION = {
|
|||
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",
|
||||
},
|
||||
},
|
||||
// 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>",
|
||||
|
|
|
@ -5,7 +5,7 @@ import Orchestrator from "./orchestrator"
|
|||
import clientActions from "./actions"
|
||||
|
||||
// Execute a workflow from a running budibase app
|
||||
export const clientStrategy = ({ api, instanceId }) => ({
|
||||
export const clientStrategy = ({ api }) => ({
|
||||
context: {},
|
||||
bindContextArgs: function(args) {
|
||||
const mappedArgs = { ...args }
|
||||
|
@ -40,7 +40,7 @@ export const clientStrategy = ({ api, instanceId }) => ({
|
|||
|
||||
// this workflow block gets executed on the server
|
||||
if (block.environment === "SERVER") {
|
||||
const EXECUTE_WORKFLOW_URL = `/api/${instanceId}/workflows/action`
|
||||
const EXECUTE_WORKFLOW_URL = `/api/workflows/action`
|
||||
const response = await api.post({
|
||||
url: EXECUTE_WORKFLOW_URL,
|
||||
body: {
|
||||
|
@ -58,8 +58,8 @@ export const clientStrategy = ({ api, instanceId }) => ({
|
|||
},
|
||||
})
|
||||
|
||||
export const triggerWorkflow = api => async ({ workflow, instanceId }) => {
|
||||
const workflowOrchestrator = new Orchestrator(api, instanceId)
|
||||
export const triggerWorkflow = api => async ({ workflow }) => {
|
||||
const workflowOrchestrator = new Orchestrator(api)
|
||||
workflowOrchestrator.strategy = clientStrategy
|
||||
|
||||
const EXECUTE_WORKFLOW_URL = `/api/workflows/${workflow}`
|
||||
|
|
|
@ -1,8 +1,3 @@
|
|||
import { get } from "svelte/store"
|
||||
import mustache from "mustache"
|
||||
import { appStore } from "../../state/store"
|
||||
import clientActions from "./actions"
|
||||
|
||||
/**
|
||||
* The workflow orchestrator is a class responsible for executing workflows.
|
||||
* It relies on the strategy pattern, which allows composable behaviour to be
|
||||
|
@ -11,13 +6,12 @@ import clientActions from "./actions"
|
|||
*
|
||||
*/
|
||||
export default class Orchestrator {
|
||||
constructor(api, instanceId) {
|
||||
constructor(api) {
|
||||
this.api = api
|
||||
this.instanceId = instanceId
|
||||
}
|
||||
|
||||
set strategy(strategy) {
|
||||
this._strategy = strategy({ api: this.api, instanceId: this.instanceId })
|
||||
this._strategy = strategy({ api: this.api })
|
||||
}
|
||||
|
||||
async execute(workflow) {
|
||||
|
@ -26,59 +20,3 @@ export default class Orchestrator {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute a workflow from a running budibase app
|
||||
export const clientStrategy = ({ api, instanceId }) => ({
|
||||
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] = mustache.render(argValue, {
|
||||
context: this.context,
|
||||
state: get(appStore),
|
||||
})
|
||||
}
|
||||
|
||||
return mappedArgs
|
||||
},
|
||||
run: async function(workflow) {
|
||||
for (let block of workflow.steps) {
|
||||
console.log("Executing workflow block", block)
|
||||
|
||||
// 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/${instanceId}/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,
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
|
|
|
@ -65,7 +65,6 @@ const _setup = ({ handlerTypes, getCurrentState, bb, store }) => node => {
|
|||
const isBound = typeof propValue === "string" && propValue.startsWith("{{")
|
||||
|
||||
if (isBound) {
|
||||
console.log("NODE IS BOUND", node)
|
||||
initialProps[propName] = mustache.render(propValue, {
|
||||
state: currentStoreState,
|
||||
context,
|
||||
|
|
|
@ -43,10 +43,11 @@ exports.save = async function(ctx) {
|
|||
const response = await db.post(record)
|
||||
record._rev = response.rev
|
||||
|
||||
ctx.eventEmitter.emit(`record:save`, {
|
||||
record,
|
||||
instanceId: ctx.params.instanceId,
|
||||
})
|
||||
ctx.eventEmitter &&
|
||||
ctx.eventEmitter.emit(`record:save`, {
|
||||
record,
|
||||
instanceId: ctx.params.instanceId,
|
||||
})
|
||||
ctx.body = record
|
||||
ctx.status = 200
|
||||
ctx.message = `${model.name} created successfully`
|
||||
|
@ -86,7 +87,7 @@ exports.destroy = async function(ctx) {
|
|||
return
|
||||
}
|
||||
ctx.body = await db.remove(ctx.params.recordId, ctx.params.revId)
|
||||
ctx.eventEmitter.emit(`record:delete`, record)
|
||||
ctx.eventEmitter && ctx.eventEmitter.emit(`record:delete`, record)
|
||||
}
|
||||
|
||||
exports.validate = async function(ctx) {
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
const userController = require("../../user")
|
||||
|
||||
module.exports = async function createUser(user) {
|
||||
console.log("SAVING this user", user)
|
||||
|
||||
module.exports = async function createUser({ args, instanceId }) {
|
||||
const ctx = {
|
||||
params: {
|
||||
instanceId: "inst_60dd510_700f7dc06735403e81d5af91072d7241",
|
||||
instanceId,
|
||||
},
|
||||
request: {
|
||||
body: user,
|
||||
body: args.user,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
export default async function() {
|
||||
const response = await fetch("www.google.com")
|
||||
console.log(response)
|
||||
console.log("CUSTOM ACTION")
|
||||
return {
|
||||
message: "CUSTOM_WORKFLOW_SCRIPT",
|
||||
response,
|
||||
}
|
||||
}
|
|
@ -1,18 +1,29 @@
|
|||
const recordController = require("../../record")
|
||||
|
||||
module.exports = async function saveRecord(args) {
|
||||
module.exports = async function saveRecord({ args, instanceId }) {
|
||||
const { model, ...record } = args.record
|
||||
|
||||
const ctx = {
|
||||
params: {
|
||||
instanceId: "inst_60dd510_700f7dc06735403e81d5af91072d7241",
|
||||
instanceId,
|
||||
modelId: model._id,
|
||||
},
|
||||
request: {
|
||||
body: args.record,
|
||||
body: record,
|
||||
},
|
||||
}
|
||||
|
||||
await recordController.save(ctx)
|
||||
|
||||
return {
|
||||
record: ctx.body,
|
||||
try {
|
||||
return {
|
||||
record: ctx.body,
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
return {
|
||||
record: null,
|
||||
error: err.message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ const sgMail = require("@sendgrid/mail")
|
|||
|
||||
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
|
||||
|
||||
module.exports = async function sendEmail(args) {
|
||||
module.exports = async function sendEmail({ args }) {
|
||||
const msg = {
|
||||
to: args.to,
|
||||
from: args.from,
|
||||
|
@ -20,7 +20,7 @@ module.exports = async function sendEmail(args) {
|
|||
console.error(err)
|
||||
return {
|
||||
success: false,
|
||||
err,
|
||||
error: err.message,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,8 +54,12 @@ exports.find = async function(ctx) {
|
|||
}
|
||||
|
||||
exports.executeAction = async function(ctx) {
|
||||
const workflowAction = require(`./actions/${ctx.request.body.action}`)
|
||||
const response = await workflowAction(ctx.request.body.args)
|
||||
const { args, action } = ctx.request.body
|
||||
const workflowAction = require(`./actions/${action}`)
|
||||
const response = await workflowAction({
|
||||
args,
|
||||
instanceId: ctx.user.instanceId,
|
||||
})
|
||||
ctx.body = response
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ router
|
|||
)
|
||||
.put("/api/:instanceId/workflows", authorized(BUILDER), controller.update)
|
||||
.post("/api/:instanceId/workflows", authorized(BUILDER), controller.create)
|
||||
.post("/api/:instanceId/workflows/action", controller.executeAction)
|
||||
.post("/api/workflows/action", controller.executeAction)
|
||||
.delete(
|
||||
"/api/:instanceId/workflows/:id/:rev",
|
||||
authorized(BUILDER),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const { app, BrowserWindow } = require("electron")
|
||||
const { app, BrowserWindow, shell } = require("electron")
|
||||
const { join } = require("path")
|
||||
const { homedir } = require("os")
|
||||
const isDev = require("electron-is-dev")
|
||||
|
@ -18,6 +18,11 @@ const APP_TITLE = "Budibase Builder"
|
|||
|
||||
let win
|
||||
|
||||
function handleRedirect(e, url) {
|
||||
e.preventDefault()
|
||||
shell.openExternal(url)
|
||||
}
|
||||
|
||||
async function createWindow() {
|
||||
app.server = await require("./app")()
|
||||
win = new BrowserWindow({ width: 1920, height: 1080 })
|
||||
|
@ -28,6 +33,10 @@ async function createWindow() {
|
|||
} else {
|
||||
autoUpdater.checkForUpdatesAndNotify()
|
||||
}
|
||||
|
||||
// open _blank in default browser
|
||||
win.webContents.on("new-window", handleRedirect)
|
||||
win.webContents.on("will-navigate", handleRedirect)
|
||||
}
|
||||
|
||||
app.whenReady().then(createWindow)
|
||||
|
|
Loading…
Reference in New Issue