1
0
Fork 0
mirror of synced 2024-06-28 02:50:50 +12:00

tidy up, styling

This commit is contained in:
Martin McKeaveney 2020-06-02 11:08:53 +01:00
parent 1df1d76d7a
commit 7137362302
14 changed files with 98 additions and 119 deletions

View file

@ -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%;

View file

@ -119,4 +119,8 @@
font-size: 12px;
font-weight: 500;
}
.new-workflow-button:hover {
background: var(--light-grey);
}
</style>

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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