Action drawer updates. Actions now grouped by type and filterable in the action drawer
This commit is contained in:
parent
8a7b4fdd2c
commit
1d1de31c35
|
@ -6,8 +6,8 @@
|
||||||
Button,
|
Button,
|
||||||
Layout,
|
Layout,
|
||||||
DrawerContent,
|
DrawerContent,
|
||||||
ActionMenu,
|
ActionButton,
|
||||||
MenuItem,
|
Search,
|
||||||
} from "@budibase/bbui"
|
} from "@budibase/bbui"
|
||||||
import { getAvailableActions } from "./index"
|
import { getAvailableActions } from "./index"
|
||||||
import { generate } from "shortid"
|
import { generate } from "shortid"
|
||||||
|
@ -22,8 +22,24 @@
|
||||||
export let actions
|
export let actions
|
||||||
export let bindings = []
|
export let bindings = []
|
||||||
|
|
||||||
|
let showAvailableActions = false
|
||||||
|
|
||||||
|
let actionQuery
|
||||||
|
$: parsedQuery =
|
||||||
|
typeof actionQuery === "string" ? actionQuery.toLowerCase().trim() : ""
|
||||||
|
|
||||||
let selectedAction = actions?.length ? actions[0] : null
|
let selectedAction = actions?.length ? actions[0] : null
|
||||||
|
|
||||||
|
$: mappedActionTypes = actionTypes.reduce((acc, action) => {
|
||||||
|
let parsedName = action.name.toLowerCase().trim()
|
||||||
|
if (parsedQuery.length && parsedName.indexOf(parsedQuery) < 0) {
|
||||||
|
return acc
|
||||||
|
}
|
||||||
|
acc[action.type] = acc[action.type] || []
|
||||||
|
acc[action.type].push(action)
|
||||||
|
return acc
|
||||||
|
}, {})
|
||||||
|
|
||||||
// These are ephemeral bindings which only exist while executing actions
|
// These are ephemeral bindings which only exist while executing actions
|
||||||
$: buttonContextBindings = getButtonContextBindings(
|
$: buttonContextBindings = getButtonContextBindings(
|
||||||
$currentAsset,
|
$currentAsset,
|
||||||
|
@ -61,7 +77,12 @@
|
||||||
actions = actions
|
actions = actions
|
||||||
}
|
}
|
||||||
|
|
||||||
const addAction = actionType => () => {
|
const toggleActionList = () => {
|
||||||
|
actionQuery = null
|
||||||
|
showAvailableActions = !showAvailableActions
|
||||||
|
}
|
||||||
|
|
||||||
|
const addAction = actionType => {
|
||||||
const newAction = {
|
const newAction = {
|
||||||
parameters: {},
|
parameters: {},
|
||||||
[EVENT_TYPE_KEY]: actionType.name,
|
[EVENT_TYPE_KEY]: actionType.name,
|
||||||
|
@ -78,6 +99,11 @@
|
||||||
selectedAction = action
|
selectedAction = action
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onAddAction = actionType => {
|
||||||
|
addAction(actionType)
|
||||||
|
toggleActionList()
|
||||||
|
}
|
||||||
|
|
||||||
function handleDndConsider(e) {
|
function handleDndConsider(e) {
|
||||||
actions = e.detail.items
|
actions = e.detail.items
|
||||||
}
|
}
|
||||||
|
@ -88,7 +114,29 @@
|
||||||
|
|
||||||
<DrawerContent>
|
<DrawerContent>
|
||||||
<Layout noPadding gap="S" slot="sidebar">
|
<Layout noPadding gap="S" slot="sidebar">
|
||||||
{#if actions && actions.length > 0}
|
{#if showAvailableActions}
|
||||||
|
<div>
|
||||||
|
<ActionButton secondary icon={"ArrowLeft"} on:click={toggleActionList}>
|
||||||
|
Back
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
<Search placeholder="Search" bind:value={actionQuery} />
|
||||||
|
{#each Object.entries(mappedActionTypes) as [categoryId, category]}
|
||||||
|
<div class="heading">{categoryId}</div>
|
||||||
|
<ul>
|
||||||
|
{#each category as actionType}
|
||||||
|
<li on:click={onAddAction(actionType)}>
|
||||||
|
<span class="binding__label">{actionType.name}</span>
|
||||||
|
</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
{#if actions && actions.length > 0 && !showAvailableActions}
|
||||||
|
<div>
|
||||||
|
<Button secondary on:click={toggleActionList}>Add Action</Button>
|
||||||
|
</div>
|
||||||
<div
|
<div
|
||||||
class="actions"
|
class="actions"
|
||||||
use:dndzone={{
|
use:dndzone={{
|
||||||
|
@ -120,17 +168,9 @@
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
<ActionMenu>
|
|
||||||
<Button slot="control" secondary>Add Action</Button>
|
|
||||||
{#each actionTypes as actionType}
|
|
||||||
<MenuItem on:click={addAction(actionType)}>
|
|
||||||
{actionType.name}
|
|
||||||
</MenuItem>
|
|
||||||
{/each}
|
|
||||||
</ActionMenu>
|
|
||||||
</Layout>
|
</Layout>
|
||||||
<Layout noPadding>
|
<Layout noPadding>
|
||||||
{#if selectedActionComponent}
|
{#if selectedActionComponent && !showAvailableActions}
|
||||||
{#key selectedAction.id}
|
{#key selectedAction.id}
|
||||||
<div class="selected-action-container">
|
<div class="selected-action-container">
|
||||||
<svelte:component
|
<svelte:component
|
||||||
|
@ -152,13 +192,10 @@
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
gap: var(--spacing-s);
|
gap: var(--spacing-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-header {
|
.action-header {
|
||||||
color: var(--spectrum-global-color-gray-700);
|
color: var(--spectrum-global-color-gray-700);
|
||||||
|
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-container {
|
.action-container {
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
padding: var(--spacing-s) var(--spacing-m);
|
padding: var(--spacing-s) var(--spacing-m);
|
||||||
|
@ -182,4 +219,45 @@
|
||||||
.action-container.selected .action-header {
|
.action-container.selected .action-header {
|
||||||
color: var(--spectrum-global-color-gray-900);
|
color: var(--spectrum-global-color-gray-900);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-size: var(--font-size-s);
|
||||||
|
padding: var(--spacing-m);
|
||||||
|
border-radius: 4px;
|
||||||
|
border: var(--border-light);
|
||||||
|
transition: background-color 130ms ease-in-out, color 130ms ease-in-out,
|
||||||
|
border-color 130ms ease-in-out;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
li:not(:last-of-type) {
|
||||||
|
margin-bottom: var(--spacing-s);
|
||||||
|
}
|
||||||
|
li :global(*) {
|
||||||
|
transition: color 130ms ease-in-out;
|
||||||
|
}
|
||||||
|
li:hover {
|
||||||
|
color: var(--spectrum-global-color-gray-900);
|
||||||
|
background-color: var(--spectrum-global-color-gray-50);
|
||||||
|
border-color: var(--spectrum-global-color-gray-500);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
li:hover :global(*) {
|
||||||
|
color: var(--spectrum-global-color-gray-900) !important;
|
||||||
|
}
|
||||||
|
.binding__label {
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
.heading {
|
||||||
|
font-size: var(--font-size-s);
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--spectrum-global-color-gray-600);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -69,9 +69,15 @@
|
||||||
notifications.error("Error creating automation")
|
notifications.error("Error creating automation")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: actionCount = value?.length
|
||||||
|
$: actionText = `${actionCount || "No"} action${
|
||||||
|
actionCount !== 1 ? "s" : ""
|
||||||
|
} set`
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ActionButton on:click={openDrawer}>Define actions</ActionButton>
|
<ActionButton on:click={openDrawer}>Define actions</ActionButton>
|
||||||
|
<div class="action-count">{actionText}</div>
|
||||||
<Drawer bind:this={drawer} title={"Actions"}>
|
<Drawer bind:this={drawer} title={"Actions"}>
|
||||||
<svelte:fragment slot="description">
|
<svelte:fragment slot="description">
|
||||||
Define what actions to run.
|
Define what actions to run.
|
||||||
|
@ -85,3 +91,9 @@
|
||||||
{key}
|
{key}
|
||||||
/>
|
/>
|
||||||
</Drawer>
|
</Drawer>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.action-count {
|
||||||
|
padding-top: var(--spacing-s);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{
|
||||||
"name": "Save Row",
|
"name": "Save Row",
|
||||||
|
"type": "data",
|
||||||
"component": "SaveRow",
|
"component": "SaveRow",
|
||||||
"context": [
|
"context": [
|
||||||
{
|
{
|
||||||
|
@ -12,6 +13,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Duplicate Row",
|
"name": "Duplicate Row",
|
||||||
|
"type": "data",
|
||||||
"component": "DuplicateRow",
|
"component": "DuplicateRow",
|
||||||
"context": [
|
"context": [
|
||||||
{
|
{
|
||||||
|
@ -22,14 +24,17 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Delete Row",
|
"name": "Delete Row",
|
||||||
|
"type": "data",
|
||||||
"component": "DeleteRow"
|
"component": "DeleteRow"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Navigate To",
|
"name": "Navigate To",
|
||||||
|
"type": "ui/ux",
|
||||||
"component": "NavigateTo"
|
"component": "NavigateTo"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Execute Query",
|
"name": "Execute Query",
|
||||||
|
"type": "data",
|
||||||
"component": "ExecuteQuery",
|
"component": "ExecuteQuery",
|
||||||
"context": [
|
"context": [
|
||||||
{
|
{
|
||||||
|
@ -40,43 +45,53 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Trigger Automation",
|
"name": "Trigger Automation",
|
||||||
|
"type": "ui/ux",
|
||||||
"component": "TriggerAutomation"
|
"component": "TriggerAutomation"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Update Field Value",
|
"name": "Update Field Value",
|
||||||
|
"type": "form",
|
||||||
"component": "UpdateFieldValue"
|
"component": "UpdateFieldValue"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Validate Form",
|
"name": "Validate Form",
|
||||||
|
"type": "form",
|
||||||
"component": "ValidateForm"
|
"component": "ValidateForm"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Change Form Step",
|
"name": "Change Form Step",
|
||||||
|
"type": "form",
|
||||||
"component": "ChangeFormStep"
|
"component": "ChangeFormStep"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Clear Form",
|
"name": "Clear Form",
|
||||||
|
"type": "form",
|
||||||
"component": "ClearForm"
|
"component": "ClearForm"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Log Out",
|
"name": "Log Out",
|
||||||
|
"type": "ui/ux",
|
||||||
"component": "LogOut"
|
"component": "LogOut"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Close Screen Modal",
|
"name": "Close Screen Modal",
|
||||||
|
"type": "ui/ux",
|
||||||
"component": "CloseScreenModal"
|
"component": "CloseScreenModal"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Refresh Data Provider",
|
"name": "Refresh Data Provider",
|
||||||
|
"type": "data",
|
||||||
"component": "RefreshDataProvider"
|
"component": "RefreshDataProvider"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Update State",
|
"name": "Update State",
|
||||||
|
"type": "data",
|
||||||
"component": "UpdateState",
|
"component": "UpdateState",
|
||||||
"dependsOnFeature": "state"
|
"dependsOnFeature": "state"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Upload File to S3",
|
"name": "Upload File to S3",
|
||||||
|
"type": "data",
|
||||||
"component": "S3Upload",
|
"component": "S3Upload",
|
||||||
"context": [
|
"context": [
|
||||||
{
|
{
|
||||||
|
@ -87,10 +102,12 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Export Data",
|
"name": "Export Data",
|
||||||
|
"type": "data",
|
||||||
"component": "ExportData"
|
"component": "ExportData"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Continue if / Stop if",
|
"name": "Continue if / Stop if",
|
||||||
|
"type": "ui/ux",
|
||||||
"component": "ContinueIf",
|
"component": "ContinueIf",
|
||||||
"dependsOnFeature": "continueIfAction"
|
"dependsOnFeature": "continueIfAction"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue