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

This commit is contained in:
mike12345567 2020-09-18 16:45:50 +01:00
commit d39a88e3dd
5 changed files with 80 additions and 54 deletions

View File

@ -21,17 +21,25 @@ context("Create a workflow", () => {
// Add trigger // Add trigger
cy.get("[data-cy=add-workflow-component]").click() cy.get("[data-cy=add-workflow-component]").click()
cy.get("[data-cy=RECORD_SAVED]").click() cy.get("[data-cy=RECORD_SAVED]").click()
cy.get(".budibase__input").select("dog") cy.get("[data-cy=workflow-block-setup]").within(() => {
cy.get("select")
.first()
.select("dog")
})
// Create action // Create action
cy.get("[data-cy=SAVE_RECORD]").click() cy.get("[data-cy=SAVE_RECORD]").click()
cy.get(".budibase__input").select("dog") cy.get("[data-cy=workflow-block-setup]").within(() => {
cy.get(".container input") cy.get("select")
.first() .first()
.type("goodboy") .select("dog")
cy.get(".container input") cy.get("input")
.eq(1) .first()
.type("11") .type("goodboy")
cy.get("input")
.eq(1)
.type("11")
})
// Save // Save
cy.contains("Save Workflow").click() cy.contains("Save Workflow").click()
@ -44,7 +52,6 @@ context("Create a workflow", () => {
it("should add record when a new record is added", () => { it("should add record when a new record is added", () => {
cy.contains("backend").click() cy.contains("backend").click()
cy.addRecord(["Rover", 15]) cy.addRecord(["Rover", 15])
cy.reload() cy.reload()
cy.contains("goodboy").should("have.text", "goodboy") cy.contains("goodboy").should("have.text", "goodboy")

View File

@ -12,17 +12,6 @@
// Ensure any nullish modelId values get set to empty string so // Ensure any nullish modelId values get set to empty string so
// that the select works // that the select works
$: if (value?.modelId == null) value = { modelId: "" } $: if (value?.modelId == null) value = { modelId: "" }
function setParsedValue(evt, field) {
const fieldSchema = model?.schema[field]
if (fieldSchema) {
if (fieldSchema.type === "number") {
value[field] = parseInt(evt.target.value)
return
}
}
value[field] = evt.target.value
}
</script> </script>
<div class="block-field"> <div class="block-field">
@ -49,12 +38,12 @@
<option value={option}>{option}</option> <option value={option}>{option}</option>
{/each} {/each}
</Select> </Select>
{:else} {:else if schema.type === "string"}
<BindableInput <BindableInput
thin thin
bind:value={value[field]} bind:value={value[field]}
on:change={e => setParsedValue(e, field)}
label={field} label={field}
type={schema.type}
{bindings} /> {bindings} />
{/if} {/if}
</div> </div>

View File

@ -44,7 +44,7 @@
} }
</script> </script>
<div class="container"> <div class="container" data-cy="workflow-block-setup">
<div class="block-label">{block.name}</div> <div class="block-label">{block.name}</div>
{#each inputs as [key, value]} {#each inputs as [key, value]}
<div class="bb-margin-xl block-field"> <div class="bb-margin-xl block-field">

View File

@ -1,5 +1,5 @@
<script> <script>
import { workflowStore, backendUiStore } from "builderStore" import { workflowStore } from "builderStore"
import WorkflowBlockTagline from "./WorkflowBlockTagline.svelte" import WorkflowBlockTagline from "./WorkflowBlockTagline.svelte"
export let onSelect export let onSelect
@ -9,29 +9,12 @@
$: selected = $workflowStore.selectedBlock?.id === block.id $: selected = $workflowStore.selectedBlock?.id === block.id
$: steps = $workflowStore.selectedWorkflow?.workflow?.definition?.steps ?? [] $: steps = $workflowStore.selectedWorkflow?.workflow?.definition?.steps ?? []
$: blockIdx = steps.findIndex(step => step.id === block.id) $: blockIdx = steps.findIndex(step => step.id === block.id)
function selectBlock() {
onSelect(block)
}
function enrichInputs(inputs) {
let enrichedInputs = { ...inputs, enriched: {} }
const modelId = inputs.modelId || inputs.record?.modelId
if (modelId) {
enrichedInputs.enriched.model = $backendUiStore.models.find(
model => model._id === modelId
)
}
return enrichedInputs
}
$: inputs = enrichInputs(block.inputs)
</script> </script>
<div <div
class={`block ${block.type} hoverable`} class={`block ${block.type} hoverable`}
class:selected class:selected
on:click={selectBlock}> on:click={() => onSelect(block)}>
<header> <header>
{#if block.type === 'TRIGGER'} {#if block.type === 'TRIGGER'}
<i class="ri-lightbulb-fill" /> <i class="ri-lightbulb-fill" />
@ -49,13 +32,13 @@
</header> </header>
<hr /> <hr />
<p> <p>
<WorkflowBlockTagline tagline={block.tagline} {inputs} /> <WorkflowBlockTagline {block} />
</p> </p>
</div> </div>
<style> <style>
.block { .block {
width: 320px; width: 360px;
padding: 20px; padding: 20px;
border-radius: var(--border-radius-m); border-radius: var(--border-radius-m);
transition: 0.3s all ease; transition: 0.3s all ease;

View File

@ -1,19 +1,61 @@
<script> <script>
import mustache from "mustache" import mustache from "mustache"
import { get } from "lodash/fp"
import { backendUiStore } from "builderStore"
export let tagline export let block
export let inputs
// Add bolt tags around inputs $: inputs = enrichInputs(block.inputs)
$: boldTagline = tagline.replace(/{{/g, "<b>{{").replace(/}}/, "}}</b>") $: tagline = formatTagline(block.tagline, block.schema, inputs)
$: html = (tagline || "")
.replace(/{{\s*/g, "<span>")
.replace(/\s*}}/g, "</span>")
// Fill in inputs with mustache function enrichInputs(inputs) {
$: parsedTagline = mustache.render(boldTagline, { inputs }) let enrichedInputs = { ...inputs, enriched: {} }
const modelId = inputs.modelId || inputs.record?.modelId
if (modelId) {
enrichedInputs.enriched.model = $backendUiStore.models.find(
model => model._id === modelId
)
}
return enrichedInputs
}
// Wrap bound fields inside spans to highlight them function formatTagline(tagline, schema, inputs) {
$: html = (parsedTagline || "") // Add bold tags around inputs
.replace(/{{\s/g, "<span>") let formattedTagline = tagline
.replace(/\s}}/g, "</span>") .replace(/{{/g, "<b>{{")
.replace(/}}/, "}}</b>")
// Extract schema paths for any input bindings
const inputPaths = formattedTagline
.match(/{{\s*\S+\s*}}/g)
.map(x => x.replace(/[{}]/g, "").trim())
const schemaPaths = inputPaths.map(x => x.replace(/\./g, ".properties."))
// Replace any enum bindings with their pretty equivalents
schemaPaths.forEach((path, idx) => {
const prettyValues = get(`${path}.pretty`, schema)
if (prettyValues) {
const enumValues = get(`${path}.enum`, schema)
const inputPath = inputPaths[idx]
const value = get(inputPath, { inputs })
const valueIdx = enumValues.indexOf(value)
const prettyValue = prettyValues[valueIdx]
if (prettyValue == null) {
return
}
formattedTagline = formattedTagline.replace(
new RegExp(`{{\s*${inputPath}\s*}}`),
prettyValue
)
}
})
// Fill in bindings with mustache
return mustache.render(formattedTagline, { inputs })
}
</script> </script>
<div> <div>
@ -21,10 +63,15 @@
</div> </div>
<style> <style>
div {
line-height: 1.25;
}
div :global(span) { div :global(span) {
font-size: 0.9em; font-size: 0.9em;
background-color: var(--purple-light); background-color: var(--purple-light);
padding: var(--spacing-xs); padding: var(--spacing-xs);
border-radius: var(--border-radius-m); border-radius: var(--border-radius-m);
display: inline-block;
margin: 1px;
} }
</style> </style>