Merge pull request #4390 from Budibase/feature/automation-data-types

Adding ability to toggle between Automation input types.
This commit is contained in:
Peter Clement 2022-03-01 14:00:21 +00:00 committed by GitHub
commit 48d8aaea2a
8 changed files with 212 additions and 77 deletions

View File

@ -33,7 +33,7 @@ filterTests(['smoke', 'all'], () => {
cy.get(".spectrum-Button--cta").click()
})
cy.contains("Setup").click()
cy.get(".spectrum-Picker-label").click()
cy.get(".spectrum-Picker-label").eq(1).click()
cy.contains("dog").click()
cy.get(".spectrum-Textfield-input")
.first()

View File

@ -57,6 +57,7 @@ const automationActions = store => ({
return state
})
},
save: async automation => {
const response = await API.updateAutomation(automation)
store.update(state => {
@ -130,6 +131,12 @@ const automationActions = store => ({
name: block.name,
})
},
toggleFieldControl: value => {
store.update(state => {
state.selectedBlock.rowControl = value
return state
})
},
deleteAutomationBlock: block => {
store.update(state => {
const idx =

View File

@ -3,14 +3,8 @@
import Flowchart from "./FlowChart/FlowChart.svelte"
$: automation = $automationStore.selectedAutomation?.automation
function onSelect(block) {
automationStore.update(state => {
state.selectedBlock = block
return state
})
}
</script>
{#if automation}
<Flowchart {automation} {onSelect} />
<Flowchart {automation} />
{/if}

View File

@ -14,7 +14,7 @@
} from "@budibase/bbui"
export let automation
export let onSelect
let testDataModal
let blocks
let confirmDeleteDialog
@ -45,7 +45,7 @@
<div class="title">
<div class="subtitle">
<Heading size="S">{automation.name}</Heading>
<div style="display:flex;">
<div style="display:flex; align-items: center;">
<div class="iconPadding">
<div class="icon">
<Icon
@ -72,7 +72,7 @@
animate:flip={{ duration: 500 }}
in:fly|local={{ x: 500, duration: 1500 }}
>
<FlowItem {testDataModal} {onSelect} {block} />
<FlowItem {testDataModal} {block} />
</div>
{/each}
</div>

View File

@ -10,6 +10,7 @@
Button,
StatusLight,
ActionButton,
Select,
notifications,
} from "@budibase/bbui"
import AutomationBlockSetup from "../../SetupPanel/AutomationBlockSetup.svelte"
@ -18,7 +19,6 @@
import ActionModal from "./ActionModal.svelte"
import { externalActions } from "./ExternalActions"
export let onSelect
export let block
export let testDataModal
let selected
@ -28,6 +28,10 @@
let setupToggled
let blockComplete
$: rowControl = $automationStore.selectedAutomation.automation.rowControl
$: showBindingPicker =
block.stepId === "CREATE_ROW" || block.stepId === "UPDATE_ROW"
$: testResult = $automationStore.selectedAutomation.testResults?.steps.filter(
step => (block.id ? step.id === block.id : step.stepId === block.stepId)
)
@ -44,12 +48,6 @@
$automationStore.selectedAutomation?.automation?.definition?.steps.length +
1
// Logic for hiding / showing the add button.first we check if it has a child
// then we check to see whether its inputs have been commpleted
$: disableAddButton = isTrigger
? $automationStore.selectedAutomation?.automation?.definition?.steps
.length > 0
: !isTrigger && steps.length - blockIdx > 1
$: hasCompletedInputs = Object.keys(
block.schema?.inputs?.properties || {}
).every(x => block?.inputs[x])
@ -64,6 +62,26 @@
notifications.error("Error saving notification")
}
}
function toggleFieldControl(evt) {
onSelect(block)
let rowControl
if (evt.detail === "Use values") {
rowControl = false
} else {
rowControl = true
}
automationStore.actions.toggleFieldControl(rowControl)
automationStore.actions.save(
$automationStore.selectedAutomation?.automation
)
}
async function onSelect(block) {
await automationStore.update(state => {
state.selectedBlock = block
return state
})
}
</script>
<div
@ -126,15 +144,33 @@
<Layout noPadding gap="S">
<div class="splitHeader">
<ActionButton
on:click={() => (setupToggled = !setupToggled)}
on:click={() => {
onSelect(block)
setupToggled = !setupToggled
}}
quiet
icon={setupToggled ? "ChevronDown" : "ChevronRight"}
>
<Detail size="S">Setup</Detail>
</ActionButton>
{#if !isTrigger}
<div on:click={() => deleteStep()}>
<Icon name="DeleteOutline" />
<div class="block-options">
{#if showBindingPicker}
<div>
<Select
on:change={toggleFieldControl}
quiet
defaultValue="Use values"
autoWidth
value={rowControl ? "Use bindings" : "Use values"}
options={["Use values", "Use bindings"]}
placeholder={null}
/>
</div>
{/if}
<div class="delete-padding" on:click={() => deleteStep()}>
<Icon name="DeleteOutline" />
</div>
</div>
{/if}
</div>
@ -180,6 +216,13 @@
{/if}
<style>
.delete-padding {
padding-left: 30px;
}
.block-options {
display: flex;
align-items: center;
}
.center-items {
display: flex;
align-items: center;

View File

@ -227,6 +227,7 @@
/>
{:else if value.customType === "row"}
<RowSelector
{block}
value={inputData[key]}
on:change={e => onChange(e, key)}
{bindings}

View File

@ -1,26 +1,31 @@
<script>
import { tables } from "stores/backend"
import {
Select,
Toggle,
DatePicker,
Multiselect,
TextArea,
} from "@budibase/bbui"
import { Select } from "@budibase/bbui"
import DrawerBindableInput from "../../common/bindings/DrawerBindableInput.svelte"
import AutomationBindingPanel from "../../common/bindings/ServerBindingPanel.svelte"
import { createEventDispatcher } from "svelte"
import ModalBindableInput from "components/common/bindings/ModalBindableInput.svelte"
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
import { automationStore } from "builderStore"
import RowSelectorTypes from "./RowSelectorTypes.svelte"
const dispatch = createEventDispatcher()
export let value
export let bindings
export let block
let table
let schemaFields
let placeholders = {
number: 10,
boolean: "true",
datetime: "2022-02-16T12:00:00.000Z ",
options: "1",
array: "1 2 3 4",
link: "ro_ta_123_456",
longform: "long form text",
}
$: rowControl = block.rowControl
$: {
table = $tables.list.find(table => table._id === value?.tableId)
schemaFields = Object.entries(table?.schema ?? {})
@ -37,18 +42,48 @@
dispatch("change", value)
}
const onChange = (e, field) => {
value[field] = e.detail
const coerce = (value, type) => {
if (type === "boolean") {
if (typeof value === "boolean") {
return value
}
return value === "true"
}
if (type === "number") {
if (typeof value === "number") {
return value
}
return Number(value)
}
if (type === "options") {
return [value]
}
if (type === "array") {
if (Array.isArray(value)) {
return value
}
return value.split(",").map(x => x.trim())
}
if (type === "link") {
if (Array.isArray(value)) {
return value
}
return [value]
}
return value
}
const onChange = (e, field, type) => {
value[field] = coerce(e.detail, type)
dispatch("change", value)
}
// Ensure any nullish tableId values get set to empty string so
// that the select works
$: if (value?.tableId == null) value = { tableId: "" }
function schemaHasOptions(schema) {
return !!schema.constraints?.inclusion?.length
}
</script>
<Select
@ -62,55 +97,46 @@
<div class="schema-fields">
{#each schemaFields as [field, schema]}
{#if !schema.autocolumn}
{#if schemaHasOptions(schema) && schema.type !== "array"}
<Select
on:change={e => onChange(e, field)}
label={field}
value={value[field]}
options={schema.constraints.inclusion}
/>
{:else if schema.type === "datetime"}
<DatePicker
label={field}
value={value[field]}
on:change={e => onChange(e, field)}
/>
{:else if schema.type === "boolean"}
<Toggle
text={field}
value={value[field]}
on:change={e => onChange(e, field)}
/>
{:else if schema.type === "array"}
<Multiselect
bind:value={value[field]}
label={field}
options={schema.constraints.inclusion}
/>
{:else if schema.type === "longform"}
<TextArea label={field} bind:value={value[field]} />
{:else if schema.type === "link"}
<LinkedRowSelector bind:linkedRows={value[field]} {schema} />
{:else if schema.type === "string" || schema.type === "number"}
{#if schema.type !== "attachment"}
{#if $automationStore.selectedAutomation.automation.testData}
<ModalBindableInput
value={value[field]}
panel={AutomationBindingPanel}
label={field}
type={value.customType}
on:change={e => onChange(e, field)}
{bindings}
/>
{#if !rowControl}
<RowSelectorTypes
{field}
{schema}
{bindings}
{value}
{onChange}
/>
{:else}
<DrawerBindableInput
placeholder={placeholders[schema.type]}
panel={AutomationBindingPanel}
value={Array.isArray(value[field])
? value[field].join(" ")
: value[field]}
on:change={e => onChange(e, field, schema.type)}
label={field}
type="string"
{bindings}
fillWidth={true}
allowJS={true}
/>
{/if}
{:else if !rowControl}
<RowSelectorTypes {field} {schema} {bindings} {value} {onChange} />
{:else}
<DrawerBindableInput
placeholder={placeholders[schema.type]}
panel={AutomationBindingPanel}
value={value[field]}
on:change={e => onChange(e, field)}
value={Array.isArray(value[field])
? value[field].join(" ")
: value[field]}
on:change={e => onChange(e, field, schema.type)}
label={field}
type="string"
{bindings}
fillWidth={true}
allowJS={false}
allowJS={true}
/>
{/if}
{/if}

View File

@ -0,0 +1,64 @@
<script>
import {
Select,
Toggle,
DatePicker,
Multiselect,
TextArea,
} from "@budibase/bbui"
import LinkedRowSelector from "components/common/LinkedRowSelector.svelte"
import DrawerBindableInput from "../../common/bindings/DrawerBindableInput.svelte"
import AutomationBindingPanel from "../../common/bindings/ServerBindingPanel.svelte"
export let onChange
export let field
export let schema
export let value
export let bindings
function schemaHasOptions(schema) {
return !!schema.constraints?.inclusion?.length
}
</script>
{#if schemaHasOptions(schema) && schema.type !== "array"}
<Select
on:change={e => onChange(e, field)}
label={field}
value={value[field]}
options={schema.constraints.inclusion}
/>
{:else if schema.type === "datetime"}
<DatePicker
label={field}
value={value[field]}
on:change={e => onChange(e, field)}
/>
{:else if schema.type === "boolean"}
<Toggle
text={field}
value={value[field]}
on:change={e => onChange(e, field)}
/>
{:else if schema.type === "array"}
<Multiselect
bind:value={value[field]}
label={field}
options={schema.constraints.inclusion}
/>
{:else if schema.type === "longform"}
<TextArea label={field} bind:value={value[field]} />
{:else if schema.type === "link"}
<LinkedRowSelector bind:linkedRows={value[field]} {schema} />
{:else if schema.type === "string" || schema.type === "number"}
<DrawerBindableInput
panel={AutomationBindingPanel}
value={value[field]}
on:change={e => onChange(e, field)}
label={field}
type="string"
{bindings}
fillWidth={true}
allowJS={true}
/>
{/if}