event panel rework backup

This commit is contained in:
Michael Shanks 2020-09-01 10:12:01 +01:00
parent 235993e1c0
commit 72492da29e
10 changed files with 201 additions and 133 deletions

View File

@ -60,7 +60,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@budibase/bbui": "^1.28.0", "@budibase/bbui": "^1.28.2",
"@budibase/client": "^0.1.19", "@budibase/client": "^0.1.19",
"@budibase/colorpicker": "^1.0.1", "@budibase/colorpicker": "^1.0.1",
"@sentry/browser": "5.19.1", "@sentry/browser": "5.19.1",

View File

@ -1,170 +1,194 @@
<script> <script>
import { store } from "builderStore" import { store } from "builderStore"
import { Button, Select } from "@budibase/bbui" import {
import Modal from "../../common/Modal.svelte" TextButton,
import HandlerSelector from "./HandlerSelector.svelte" Button,
import IconButton from "../../common/IconButton.svelte" Body,
import ActionButton from "../../common/ActionButton.svelte" Heading,
import getIcon from "../../common/icon" DropdownMenu,
import { CloseIcon } from "components/common/Icons/" } from "@budibase/bbui"
import { AddIcon } from "components/common/Icons/"
import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers" import { EVENT_TYPE_MEMBER_NAME } from "../../common/eventHandlers"
import actionTypes from "./actions"
import { createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher()
export let event export let event
export let eventOptions = []
export let onClose
let eventType = "" let addActionButton
let addActionDropdown
let selectedAction
let draftEventHandler = { parameters: [] } let draftEventHandler = { parameters: [] }
$: eventData = event || { handlers: [] } $: actions = event || []
$: if (!eventOptions.includes(eventType) && eventOptions.length > 0) $: selectedActionComponent =
eventType = eventOptions[0].name selectedAction &&
actionTypes.find(t => t.name === selectedAction[EVENT_TYPE_MEMBER_NAME])
.component
const closeModal = () => { const closeModal = () => {
onClose() dispatch("close")
draftEventHandler = { parameters: [] } draftEventHandler = { parameters: [] }
eventData = { handlers: [] } actions = []
} }
const updateEventHandler = (updatedHandler, index) => { const updateEventHandler = (updatedHandler, index) => {
eventData.handlers[index] = updatedHandler actions[index] = updatedHandler
}
const updateDraftEventHandler = updatedHandler => {
draftEventHandler = updatedHandler
} }
const deleteEventHandler = index => { const deleteEventHandler = index => {
eventData.handlers.splice(index, 1) actions.splice(index, 1)
eventData = eventData actions = actions
} }
const createNewEventHandler = handler => { const addAction = actionType => () => {
const newHandler = handler || { const newAction = {
parameters: {}, parameters: {},
[EVENT_TYPE_MEMBER_NAME]: "", [EVENT_TYPE_MEMBER_NAME]: actionType.name,
} }
eventData.handlers.push(newHandler) actions.push(newAction)
eventData = eventData selectedAction = newAction
actions = actions
addActionDropdown.hide()
} }
const deleteEvent = () => { const selectAction = action => () => {
store.setComponentProp(eventType, []) selectedAction = action
closeModal()
} }
const saveEventData = () => { const saveEventData = () => {
store.setComponentProp(eventType, eventData.handlers) dispatch("change", actions)
closeModal() closeModal()
} }
</script> </script>
<div class="container"> <div class="root">
<div class="body">
<div class="heading"> <div class="header">
<h3> <Heading size="s" color="dark">Actions</Heading>
{eventData.name ? `${eventData.name} Event` : 'Create a New Component Event'} <div bind:this={addActionButton}>
</h3> <TextButton text small blue on:click={addActionDropdown.show}>
Add Action
<div style="height: 20px; width: 20px;">
<AddIcon />
</div>
</TextButton>
</div>
<DropdownMenu
bind:this={addActionDropdown}
anchor={addActionButton}
align="right">
<div class="available-actions-container">
{#each actionTypes as actionType}
<div class="available-action" on:click={addAction(actionType)}>
<span>{actionType.name}</span>
</div> </div>
<div class="event-options">
<div class="section">
<h4>Event Type</h4>
<Select bind:value={eventType}>
{#each eventOptions as option}
<option value={option.name}>{option.name}</option>
{/each} {/each}
</Select>
</div> </div>
</DropdownMenu>
</div> </div>
<div class="section"> <div class="actions-container">
<h4>Event Action(s)</h4> {#if actions && actions.length > 0}
<HandlerSelector {#each actions as action, index}
newHandler <div class="action-container">
onChanged={updateDraftEventHandler} <div on:click={selectAction(action)}>
onCreate={() => { <Body size="medium">
createNewEventHandler(draftEventHandler) {index + 1}. {action[EVENT_TYPE_MEMBER_NAME]}
draftEventHandler = { parameters: [] } </Body>
}} </div>
handler={draftEventHandler} /> {#if action === selectedAction}
<div class="selected-action-container">
<svelte:component
this={selectedActionComponent}
parameters={selectedAction.parameters} />
<div class="delete-action-button">
<TextButton text medium>Delete</TextButton>
</div>
</div>
{/if}
</div> </div>
{#if eventData}
{#each eventData.handlers as handler, index}
<HandlerSelector
{index}
onChanged={updateEventHandler}
onRemoved={() => deleteEventHandler(index)}
{handler} />
{/each} {/each}
{/if} {/if}
</div> </div>
<div class="footer"> <div class="footer">
{#if eventData.name} <a href="https://docs.budibase.com">Learn more about Actions</a>
<Button <Button secondary on:click={closeModal}>Cancel</Button>
outline <Button primary on:click={saveEventData}>Save</Button>
on:click={deleteEvent}
disabled={eventData.handlers.length === 0}>
Delete
</Button>
{/if}
<div class="save">
<Button
primary
on:click={saveEventData}
disabled={eventData.handlers.length === 0}>
Save
</Button>
</div>
</div>
<div class="close-button" on:click={closeModal}>
<CloseIcon />
</div> </div>
</div> </div>
<style> <style>
.container { .root {
position: relative; max-height: 50vh;
} width: 700px;
.heading { display: flex;
margin-bottom: 20px; flex-direction: column;
} }
.close-button { .header {
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: space-between;
padding: var(--spacing-xl);
padding-bottom: 0;
}
.available-actions-container {
}
.available-action {
padding: var(--spacing-s);
font-size: var(--font-size-m);
cursor: pointer; cursor: pointer;
position: absolute;
top: 20px;
right: 20px;
}
.close-button :global(svg) {
width: 24px;
height: 24px;
} }
h4 { .available-action:hover {
margin-bottom: 10px; background: var(--grey-2);
} }
h3 { .actions-container {
margin: 0; flex: 1;
font-size: 24px; min-height: 0px;
font-weight: bold; padding: var(--spacing-xl);
padding-bottom: var(--spacing-m);
padding-top: var(--spacing-m);
border: var(--border-light);
border-width: 0 0 1px 0;
} }
.body {
padding: 40px; .action-container {
display: grid; border: var(--border-light);
grid-gap: 20px; border-width: 1px 0 0 0;
} }
.footer {
.delete-action-button {
padding-top: var(--spacing-l);
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
padding: 30px 40px; flex-direction: row;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 50px;
background-color: var(--grey-1);
} }
.save {
margin-left: 20px; .footer {
display: flex;
flex-direction: row;
gap: var(--spacing-s);
padding: var(--spacing-xl);
padding-top: var(--spacing-m);
}
.footer > a {
flex: 1;
color: var(--grey-5);
font-size: var(--font-size-s);
text-decoration: none;
}
.footer > a:hover {
color: var(--blue);
} }
</style> </style>

View File

@ -1,25 +1,22 @@
<script> <script>
import { Button, DropdownMenu } from "@budibase/bbui" import { Button, Modal } from "@budibase/bbui"
import EventEditorModal from "./EventEditorModal.svelte" import EventEditorModal from "./EventEditorModal.svelte"
import { getContext } from "svelte"
export let value export let value
export let name export let name
let button let eventsModal
let dropdown
</script> </script>
<div bind:this={button}> <Button secondary small on:click={eventsModal.show}>Define Actions</Button>
<Button secondary small on:click={dropdown.show}>Define Actions</Button>
</div> <Modal bind:this={eventsModal} maxWidth="100vw" hideCloseButton>
<DropdownMenu bind:this={dropdown} align="right" anchor={button}>
<EventEditorModal <EventEditorModal
event={value} event={value}
eventType={name} eventType={name}
on:change on:change
on:close={dropdown.hide} /> on:close={eventsModal.hide} />
</DropdownMenu> </Modal>
<style> <style>

View File

@ -0,0 +1,5 @@
<script>
</script>
<div>Create Record</div>

View File

@ -0,0 +1,16 @@
<script>
import { Select, Label } from "@budibase/bbui"
import { store } from "builderStore"
export let parameters
</script>
<div>
<Label size="m" color="dark">Screen</Label>
<Select outline bind:value={parameters.url}>
<option value="" />
{#each $store.screens as screen}
<option value={screen.url}>{screen.props._instanceName}</option>
{/each}
</Select>
</div>

View File

@ -0,0 +1,5 @@
<script>
</script>
<div>Update Record</div>

View File

@ -0,0 +1,18 @@
import NavigateTo from "./NavigateTo.svelte"
import UpdateRecord from "./UpdateRecord.svelte"
import CreateRecord from "./CreateRecord.svelte"
export default [
{
name: "Create Record",
component: CreateRecord,
},
{
name: "Navigate To",
component: NavigateTo,
},
{
name: "Update Record",
component: UpdateRecord,
},
]

View File

@ -14,6 +14,7 @@
export let props = {} export let props = {}
export let onChange = () => {} export let onChange = () => {}
const CAPTURE_VAR_INSIDE_MUSTACHE = /{{([^}]+)}}/g
let temporaryBindableValue = value let temporaryBindableValue = value
function handleClose() { function handleClose() {
@ -38,7 +39,6 @@
async function replaceBindings(textWithBindings) { async function replaceBindings(textWithBindings) {
getBindableProperties() getBindableProperties()
// Find all instances of mustasche // Find all instances of mustasche
const CAPTURE_VAR_INSIDE_MUSTACHE = /{{([^}]+)}}/g
const boundValues = textWithBindings.match(CAPTURE_VAR_INSIDE_MUSTACHE) const boundValues = textWithBindings.match(CAPTURE_VAR_INSIDE_MUSTACHE)
// Replace with names: // Replace with names:
@ -72,7 +72,8 @@
const safeValue = () => { const safeValue = () => {
getBindableProperties() getBindableProperties()
let temp = value let temp = value
const boundValues = (value && value.match(/{{([^}]+)}}/g)) || [] const boundValues =
(value && value.match && value.match(CAPTURE_VAR_INSIDE_MUSTACHE)) || []
// Replace with names: // Replace with names:
boundValues.forEach(v => { boundValues.forEach(v => {

View File

@ -688,10 +688,10 @@
lodash "^4.17.13" lodash "^4.17.13"
to-fast-properties "^2.0.0" to-fast-properties "^2.0.0"
"@budibase/bbui@^1.28.0": "@budibase/bbui@^1.28.2":
version "1.28.0" version "1.28.2"
resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.28.0.tgz#200adca026bc3498eafdc17dd0f7da39af4bb732" resolved "https://registry.yarnpkg.com/@budibase/bbui/-/bbui-1.28.2.tgz#b86d10c2c4489e352a391ee55cc6fc5b24492e4c"
integrity sha512-KyzW0BLFl6CWYr4w/U3SoEJlUuMqL0i5wfZ6kdejfHhiou4yS9v4cul1tc0IPUNKioQLpnW1A6NpuVmGc1e16Q== integrity sha512-8Mrh1ZrkGEl7syqMbsalI3pAy/V6Xh4tx14h3SXKx/XKXlzqxS4vq/+3DaphLbLn+0WZmHrxI5MkdfkSIh7nvw==
dependencies: dependencies:
sirv-cli "^0.4.6" sirv-cli "^0.4.6"

View File

@ -10,6 +10,8 @@ export const eventHandlers = routeTo => {
return { return {
"Navigate To": handler(["url"], param => routeTo(param && param.url)), "Navigate To": handler(["url"], param => routeTo(param && param.url)),
"Create Record": handler(["url"], param => param),
"Update Record": handler(["url"], param => param),
"Trigger Workflow": handler(["workflow"], api.triggerWorkflow), "Trigger Workflow": handler(["workflow"], api.triggerWorkflow),
} }
} }