forked from tsai/budibase
10 changed files with 198 additions and 130 deletions
@ -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> |
</div> |
||||
<div class="event-options"> |
<DropdownMenu |
||||
<div class="section"> |
bind:this={addActionDropdown} |
||||
<h4>Event Type</h4> |
anchor={addActionButton} |
||||
<Select bind:value={eventType}> |
align="right"> |
||||
{#each eventOptions as option} |
<div class="available-actions-container"> |
||||
<option value={option.name}>{option.name}</option> |
{#each actionTypes as actionType} |
||||
{/each} |
<div class="available-action" on:click={addAction(actionType)}> |
||||
</Select> |
<span>{actionType.name}</span> |
||||
|
</div> |
||||
|
{/each} |
||||
</div> |
</div> |
||||
</div> |
</DropdownMenu> |
||||
|
</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> |
<div class="selected-action-container"> |
||||
{#if eventData} |
<svelte:component |
||||
{#each eventData.handlers as handler, index} |
this={selectedActionComponent} |
||||
<HandlerSelector |
parameters={selectedAction.parameters} /> |
||||
{index} |
<div class="delete-action-button"> |
||||
onChanged={updateEventHandler} |
<TextButton text medium>Delete</TextButton> |
||||
onRemoved={() => deleteEventHandler(index)} |
</div> |
||||
{handler} /> |
</div> |
||||
|
{/if} |
||||
|
</div> |
||||
{/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; |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
} |
} |
||||
.heading { |
|
||||
margin-bottom: 20px; |
.header { |
||||
|
display: flex; |
||||
|
flex-direction: row; |
||||
|
align-items: flex-start; |
||||
|
justify-content: space-between; |
||||
|
padding: var(--spacing-xl); |
||||
|
padding-bottom: 0; |
||||
} |
} |
||||
|
|
||||
.close-button { |
.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; |
.available-action:hover { |
||||
height: 24px; |
background: var(--grey-2); |
||||
} |
} |
||||
|
|
||||
h4 { |
.actions-container { |
||||
margin-bottom: 10px; |
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; |
||||
} |
} |
||||
|
|
||||
h3 { |
.action-container { |
||||
margin: 0; |
border: var(--border-light); |
||||
font-size: 24px; |
border-width: 1px 0 0 0; |
||||
font-weight: bold; |
|
||||
} |
} |
||||
.body { |
|
||||
padding: 40px; |
.delete-action-button { |
||||
display: grid; |
padding-top: var(--spacing-l); |
||||
grid-gap: 20px; |
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
flex-direction: row; |
||||
} |
} |
||||
|
|
||||
.footer { |
.footer { |
||||
display: flex; |
display: flex; |
||||
justify-content: flex-end; |
flex-direction: row; |
||||
padding: 30px 40px; |
gap: var(--spacing-s); |
||||
border-bottom-left-radius: 5px; |
padding: var(--spacing-xl); |
||||
border-bottom-right-radius: 50px; |
padding-top: var(--spacing-m); |
||||
background-color: var(--grey-1); |
|
||||
} |
} |
||||
.save { |
|
||||
margin-left: 20px; |
.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> |
||||
|
|||||
@ -0,0 +1,5 @@ |
|||||
|
<script> |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<div>Create Record</div> |
||||
@ -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> |
||||
@ -0,0 +1,5 @@ |
|||||
|
<script> |
||||
|
|
||||
|
</script> |
||||
|
|
||||
|
<div>Update Record</div> |
||||
@ -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, |
||||
|
}, |
||||
|
] |
||||
Loading…
Reference in new issue