mirror of https://github.com/Budibase/budibase.git
9 changed files with 292 additions and 13 deletions
@ -0,0 +1,113 @@ |
|||
<script> |
|||
import { Input } from "@budibase/bbui" |
|||
|
|||
export let value = {} |
|||
$: fieldsArray = Object.entries(value).map(([name, type]) => ({ |
|||
name, |
|||
type, |
|||
})) |
|||
|
|||
let addNewName = "" |
|||
let addNewType = "string" |
|||
|
|||
function addField() { |
|||
if (!addNewName) return |
|||
if (value[addNewName.trim()]) { |
|||
addNewName = "" |
|||
return |
|||
} |
|||
const newValue = { ...value } |
|||
newValue[addNewName.trim()] = "string" |
|||
value = newValue |
|||
addNewName = "" |
|||
} |
|||
|
|||
function onInputEnter(e) { |
|||
if (e.key === "Enter") { |
|||
addField() |
|||
} |
|||
} |
|||
|
|||
function removeField(name) { |
|||
const newValues = { ...value } |
|||
delete newValues[name] |
|||
value = newValues |
|||
} |
|||
|
|||
const fieldNameChanged = originalName => e => { |
|||
// reconstruct using fieldsArray, so field order is preserved |
|||
let entries = [...fieldsArray] |
|||
const newName = e.target.value |
|||
if (newName) { |
|||
entries.find(f => f.name === originalName).name = newName |
|||
} else { |
|||
entries = entries.filter(f => f.name !== originalName) |
|||
} |
|||
value = entries.reduce((newVals, current) => { |
|||
newVals[current.name] = current.type |
|||
return newVals |
|||
}, {}) |
|||
} |
|||
</script> |
|||
|
|||
<div class="root"> |
|||
{#each fieldsArray as field} |
|||
<i |
|||
class="remove-field ri-delete-bin-line" |
|||
on:click={() => removeField(field.name)} /> |
|||
<input |
|||
value={field.name} |
|||
on:change={fieldNameChanged(field.name)} |
|||
class="grid-field" /> |
|||
<select |
|||
value={field.type} |
|||
on:blur={e => (value[field.name] = e.target.value)} |
|||
class="grid-field"> |
|||
<option>string</option> |
|||
<option>number</option> |
|||
<option>boolean</option> |
|||
<option>datetime</option> |
|||
</select> |
|||
{/each} |
|||
<div class="new-field" on:keyup={onInputEnter}> |
|||
<Input |
|||
outline |
|||
small |
|||
bind:value={addNewName} |
|||
placeholder="Enter field name" /> |
|||
</div> |
|||
<!--button on:click={addField}>Add</button--> |
|||
</div> |
|||
|
|||
<style> |
|||
.root { |
|||
display: grid; |
|||
grid-template-columns: auto 1fr auto; |
|||
} |
|||
|
|||
.remove-field { |
|||
cursor: pointer; |
|||
color: var(--grey-6); |
|||
margin: auto 4px auto 0; |
|||
} |
|||
|
|||
.remove-field:hover { |
|||
color: var(--black); |
|||
} |
|||
|
|||
.new-field { |
|||
grid-column: 1 / span 3; |
|||
max-width: 100%; |
|||
} |
|||
|
|||
.grid-field { |
|||
min-width: 50px; |
|||
font-family: inherit; |
|||
font-size: inherit; |
|||
padding: 0.4em; |
|||
margin: 0 0 0.5em 0; |
|||
box-sizing: border-box; |
|||
border: 1px solid var(--grey-4); |
|||
border-radius: 0px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,84 @@ |
|||
<script> |
|||
import { Select, Label } from "@budibase/bbui" |
|||
import { automationStore } from "builderStore" |
|||
import SaveFields from "./SaveFields.svelte" |
|||
|
|||
// parameters.contextPath used in the client handler to determine which row to save |
|||
// this could be "data" or "data.parent", "data.parent.parent" etc |
|||
export let parameters |
|||
|
|||
let idFields |
|||
let schemaFields |
|||
|
|||
const automationSchema = automation => { |
|||
const schema = Object.entries( |
|||
automation.definition.trigger.inputs.fields |
|||
).map(([name, type]) => ({ name, type })) |
|||
|
|||
return { |
|||
name: automation.name, |
|||
_id: automation._id, |
|||
schema, |
|||
} |
|||
} |
|||
|
|||
$: automations = $automationStore.automations |
|||
.filter(a => a.definition.trigger && a.definition.trigger.stepId === "APP") |
|||
.map(automationSchema) |
|||
|
|||
$: selectedAutomation = |
|||
parameters && |
|||
parameters.automationId && |
|||
automations.find(a => a._id === parameters.automationId) |
|||
|
|||
const onFieldsChanged = e => { |
|||
parameters.fields = e.detail |
|||
} |
|||
</script> |
|||
|
|||
<div class="root"> |
|||
|
|||
{#if !automations || automations.length === 0} |
|||
<div class="cannot-use"> |
|||
You must have an automation that has an "App Action" trigger. |
|||
</div> |
|||
{:else} |
|||
<Label size="m" color="dark">Automation</Label> |
|||
<Select secondary bind:value={parameters.automationId}> |
|||
<option value="" /> |
|||
{#each automations as automation} |
|||
<option value={automation._id}>{automation.name}</option> |
|||
{/each} |
|||
</Select> |
|||
|
|||
{#if selectedAutomation} |
|||
<SaveFields |
|||
parameterFields={parameters.fields} |
|||
schemaFields={selectedAutomation.schema} |
|||
on:fieldschanged={onFieldsChanged} /> |
|||
{/if} |
|||
{/if} |
|||
</div> |
|||
|
|||
<style> |
|||
.root { |
|||
display: grid; |
|||
column-gap: var(--spacing-s); |
|||
row-gap: var(--spacing-s); |
|||
grid-template-columns: auto 1fr auto 1fr auto; |
|||
align-items: baseline; |
|||
} |
|||
|
|||
.root :global(> div:nth-child(2)) { |
|||
grid-column-start: 2; |
|||
grid-column-end: 6; |
|||
} |
|||
|
|||
.cannot-use { |
|||
color: var(--red); |
|||
font-size: var(--font-size-s); |
|||
text-align: center; |
|||
width: 70%; |
|||
margin: auto; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,10 @@ |
|||
import API from "./api" |
|||
/** |
|||
* Executes an automation. Must have "App Action" trigger. |
|||
*/ |
|||
export const triggerAutomation = async (automationId, fields) => { |
|||
return await API.post({ |
|||
url: `/api/automations/${automationId}/trigger`, |
|||
body: { fields }, |
|||
}) |
|||
} |
|||
Loading…
Reference in new issue