event panel rework backup

This commit is contained in:
Michael Shanks 2020-09-01 10:12:01 +01:00
parent 838144c5b3
commit f988d2d9c7
10 changed files with 201 additions and 133 deletions

View File

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

View File

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

View File

@ -1,25 +1,22 @@
<script>
import { Button, DropdownMenu } from "@budibase/bbui"
import { Button, Modal } from "@budibase/bbui"
import EventEditorModal from "./EventEditorModal.svelte"
import { getContext } from "svelte"
export let value
export let name
let button
let dropdown
let eventsModal
</script>
<div bind:this={button}>
<Button secondary small on:click={dropdown.show}>Define Actions</Button>
</div>
<DropdownMenu bind:this={dropdown} align="right" anchor={button}>
<Button secondary small on:click={eventsModal.show}>Define Actions</Button>
<Modal bind:this={eventsModal} maxWidth="100vw" hideCloseButton>
<EventEditorModal
event={value}
eventType={name}
on:change
on:close={dropdown.hide} />
</DropdownMenu>
on:close={eventsModal.hide} />
</Modal>
<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 onChange = () => {}
const CAPTURE_VAR_INSIDE_MUSTACHE = /{{([^}]+)}}/g
let temporaryBindableValue = value
function handleClose() {
@ -38,7 +39,6 @@
async function replaceBindings(textWithBindings) {
getBindableProperties()
// Find all instances of mustasche
const CAPTURE_VAR_INSIDE_MUSTACHE = /{{([^}]+)}}/g
const boundValues = textWithBindings.match(CAPTURE_VAR_INSIDE_MUSTACHE)
// Replace with names:
@ -72,7 +72,8 @@
const safeValue = () => {
getBindableProperties()
let temp = value
const boundValues = (value && value.match(/{{([^}]+)}}/g)) || []
const boundValues =
(value && value.match && value.match(CAPTURE_VAR_INSIDE_MUSTACHE)) || []
// Replace with names:
boundValues.forEach(v => {

View File

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

View File

@ -10,6 +10,8 @@ export const eventHandlers = routeTo => {
return {
"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),
}
}