mirror of https://github.com/Budibase/budibase.git
16 changed files with 367 additions and 331 deletions
@ -1,43 +0,0 @@ |
|||
<script> |
|||
import { |
|||
DropdownMenu, |
|||
TextButton as Button, |
|||
Icon, |
|||
Modal, |
|||
ModalContent, |
|||
} from "@budibase/bbui" |
|||
import { backendUiStore } from "builderStore" |
|||
import api from "builderStore/api" |
|||
import EditIntegrationConfig from "../modals/EditIntegrationConfig.svelte" |
|||
|
|||
export let table |
|||
|
|||
$: console.log("The table config is", table) |
|||
|
|||
let modal |
|||
|
|||
// TODO: revisit |
|||
async function saveTable() { |
|||
const SAVE_TABLE_URL = `/api/tables` |
|||
const response = await api.post(SAVE_TABLE_URL, table) |
|||
const savedTable = await response.json() |
|||
await backendUiStore.actions.tables.fetch() |
|||
backendUiStore.actions.tables.select(savedTable) |
|||
} |
|||
</script> |
|||
|
|||
<div> |
|||
<Button text small on:click={modal.show}> |
|||
<Icon name="edit" /> |
|||
Configure Datasource |
|||
</Button> |
|||
</div> |
|||
<Modal bind:this={modal}> |
|||
<ModalContent |
|||
confirmText="Save" |
|||
cancelText="Cancel" |
|||
onConfirm={saveTable} |
|||
title={'Datasource Configuration'}> |
|||
<EditIntegrationConfig onClosed={modal.hide} bind:table /> |
|||
</ModalContent> |
|||
</Modal> |
|||
@ -1,35 +1,62 @@ |
|||
<script> |
|||
import BottomDrawer from "components/common/BottomDrawer.svelte" |
|||
import { store, backendUiStore } from "builderStore" |
|||
import { Button } from "@budibase/bbui" |
|||
import { store, backendUiStore, currentAsset } from "builderStore" |
|||
import { slide } from "svelte/transition" |
|||
import QueryInterface from "components/integration/QueryViewer.svelte" |
|||
import fetchBindableProperties from "builderStore/fetchBindableProperties" |
|||
import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte" |
|||
|
|||
$: query = $backendUiStore.queries.find( |
|||
query => query._id === $backendUiStore.selectedQueryId |
|||
) |
|||
export let query |
|||
export let parameters = {} |
|||
|
|||
$: console.log("CUSTOM PARAMS", parameters) |
|||
|
|||
$: bindableProperties = fetchBindableProperties({ |
|||
componentInstanceId: $store.selectedComponentId, |
|||
components: $store.components, |
|||
screen: $currentAsset, |
|||
tables: $backendUiStore.tables, |
|||
}).map(property => ({ |
|||
...property, |
|||
category: property.type === "instance" ? "Component" : "Table", |
|||
label: property.readableBinding, |
|||
path: property.runtimeBinding, |
|||
})) |
|||
|
|||
function closeDatabindingDrawer() { |
|||
store.update(state => { |
|||
state.bindingDrawerVisible = false |
|||
state.bottomDrawerVisible = false |
|||
return state |
|||
}) |
|||
} |
|||
|
|||
function saveComponentQuery() { |
|||
// save the parameters to the datasource of the component |
|||
} |
|||
</script> |
|||
|
|||
{#if query} |
|||
<BottomDrawer> |
|||
<div class="drawer-contents"> |
|||
<i class="ri-close-fill close" on:click={closeDatabindingDrawer} /> |
|||
<QueryInterface {query} /> |
|||
<BottomDrawer title={'Query'} onClose={closeDatabindingDrawer}> |
|||
<div slot="buttons"> |
|||
<Button blue thin on:click={saveComponentQuery}>Save</Button> |
|||
</div> |
|||
<div class="drawer-contents" slot="body"> |
|||
<pre>{query.queryString}</pre> |
|||
<ParameterBuilder |
|||
bind:customParams={parameters} |
|||
parameters={query.parameters} |
|||
bindings={bindableProperties} /> |
|||
</div> |
|||
</BottomDrawer> |
|||
{/if} |
|||
|
|||
<style> |
|||
i { |
|||
position: absolute; |
|||
top: var(--spacing-xl); |
|||
right: var(--spacing-xl); |
|||
font-size: var(--font-size-m); |
|||
.drawer-contents { |
|||
display: grid; |
|||
grid-auto-flow: column; |
|||
grid-template-columns: 20% 1fr; |
|||
grid-gap: var(--spacing-m); |
|||
height: 100%; |
|||
padding: var(--spacing-xl); |
|||
} |
|||
</style> |
|||
|
|||
@ -0,0 +1,200 @@ |
|||
<script> |
|||
import { |
|||
Button, |
|||
TextButton, |
|||
Body, |
|||
DropdownMenu, |
|||
ModalContent, |
|||
} from "@budibase/bbui" |
|||
import { AddIcon, ArrowDownIcon } from "components/common/Icons/" |
|||
import actionTypes from "./actions" |
|||
import { createEventDispatcher } from "svelte" |
|||
|
|||
const dispatch = createEventDispatcher() |
|||
const eventTypeKey = "##eventHandlerType" |
|||
|
|||
export let event |
|||
|
|||
let addActionButton |
|||
let addActionDropdown |
|||
let selectedAction |
|||
|
|||
let draftEventHandler = { parameters: [] } |
|||
|
|||
$: actions = event || [] |
|||
$: selectedActionComponent = |
|||
selectedAction && |
|||
actionTypes.find(t => t.name === selectedAction[eventTypeKey]).component |
|||
|
|||
const updateEventHandler = (updatedHandler, index) => { |
|||
actions[index] = updatedHandler |
|||
} |
|||
|
|||
const deleteAction = index => { |
|||
actions.splice(index, 1) |
|||
actions = actions |
|||
} |
|||
|
|||
const addAction = actionType => () => { |
|||
const newAction = { |
|||
parameters: {}, |
|||
[eventTypeKey]: actionType.name, |
|||
} |
|||
actions.push(newAction) |
|||
selectedAction = newAction |
|||
actions = actions |
|||
addActionDropdown.hide() |
|||
} |
|||
|
|||
const selectAction = action => () => { |
|||
selectedAction = action |
|||
} |
|||
|
|||
const saveEventData = () => { |
|||
dispatch("change", actions) |
|||
} |
|||
</script> |
|||
|
|||
<div class="actions-container"> |
|||
<div class="actions-list"> |
|||
<div> |
|||
<div bind:this={addActionButton}> |
|||
<TextButton text small blue on:click={addActionDropdown.show}> |
|||
<div style="height: 20px; width: 20px;"> |
|||
<AddIcon /> |
|||
</div> |
|||
Add Action |
|||
</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> |
|||
{/each} |
|||
</div> |
|||
</DropdownMenu> |
|||
</div> |
|||
|
|||
{#if actions && actions.length > 0} |
|||
{#each actions as action, index} |
|||
<div class="action-container"> |
|||
<div class="action-header" on:click={selectAction(action)}> |
|||
<span class:selected={action === selectedAction}> |
|||
{index + 1}. {action[eventTypeKey]} |
|||
</span> |
|||
<!-- <Body small lh>{index + 1}. {action[eventTypeKey]}</Body> --> |
|||
<!-- <div class="row-expander" class:rotate={action !== selectedAction}> |
|||
<ArrowDownIcon /> |
|||
</div> --> |
|||
</div> |
|||
<!-- {#if action === selectedAction} |
|||
<div class="selected-action-container"> |
|||
<svelte:component |
|||
this={selectedActionComponent} |
|||
parameters={selectedAction.parameters} /> |
|||
<div class="delete-action-button"> |
|||
<TextButton text medium on:click={() => deleteAction(index)}> |
|||
Delete |
|||
</TextButton> |
|||
</div> |
|||
</div> |
|||
{/if} --> |
|||
</div> |
|||
{/each} |
|||
{/if} |
|||
</div> |
|||
<div class="action-config"> |
|||
{#if selectedAction} |
|||
<div class="selected-action-container"> |
|||
<svelte:component |
|||
this={selectedActionComponent} |
|||
parameters={selectedAction.parameters} /> |
|||
<div class="delete-action-button"> |
|||
<!-- <TextButton text medium on:click={() => deleteAction(index)}> |
|||
Delete |
|||
</TextButton> --> |
|||
</div> |
|||
</div> |
|||
{/if} |
|||
<Button thin blue on:click={saveEventData}>Save</Button> |
|||
</div> |
|||
</div> |
|||
|
|||
<a href="https://docs.budibase.com">Learn more about Actions</a> |
|||
|
|||
<style> |
|||
.action-header { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
} |
|||
|
|||
.action-header > span { |
|||
margin-bottom: var(--spacing-m); |
|||
} |
|||
|
|||
.action-header > span:hover, |
|||
.selected { |
|||
cursor: pointer; |
|||
font-weight: 500; |
|||
} |
|||
|
|||
.actions-list { |
|||
border: var(--border-light); |
|||
} |
|||
|
|||
.available-action { |
|||
padding: var(--spacing-s); |
|||
font-size: var(--font-size-m); |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.available-action:hover { |
|||
background: var(--grey-2); |
|||
} |
|||
|
|||
.actions-container { |
|||
display: grid; |
|||
grid-gap: var(--spacing-m); |
|||
grid-template-columns: 15% 1fr; |
|||
grid-auto-flow: column; |
|||
min-height: 0; |
|||
padding-top: 0; |
|||
border: var(--border-light); |
|||
border-width: 0 0 1px 0; |
|||
overflow-y: auto; |
|||
} |
|||
|
|||
.action-container { |
|||
border: var(--border-light); |
|||
border-width: 1px 0 0 0; |
|||
} |
|||
|
|||
.selected-action-container { |
|||
padding-bottom: var(--spacing-s); |
|||
padding-top: var(--spacing-s); |
|||
} |
|||
|
|||
.delete-action-button { |
|||
padding-top: var(--spacing-l); |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
flex-direction: row; |
|||
} |
|||
|
|||
a { |
|||
flex: 1; |
|||
color: var(--grey-5); |
|||
font-size: var(--font-size-s); |
|||
text-decoration: none; |
|||
} |
|||
|
|||
a:hover { |
|||
color: var(--blue); |
|||
} |
|||
</style> |
|||
@ -1,176 +0,0 @@ |
|||
<script> |
|||
import { |
|||
Button, |
|||
TextButton, |
|||
Body, |
|||
DropdownMenu, |
|||
ModalContent, |
|||
} from "@budibase/bbui" |
|||
import { AddIcon, ArrowDownIcon } from "components/common/Icons/" |
|||
import actionTypes from "./actions" |
|||
import { createEventDispatcher } from "svelte" |
|||
|
|||
const dispatch = createEventDispatcher() |
|||
const eventTypeKey = "##eventHandlerType" |
|||
|
|||
export let event |
|||
|
|||
let addActionButton |
|||
let addActionDropdown |
|||
let selectedAction |
|||
|
|||
let draftEventHandler = { parameters: [] } |
|||
|
|||
$: actions = event || [] |
|||
$: selectedActionComponent = |
|||
selectedAction && |
|||
actionTypes.find(t => t.name === selectedAction[eventTypeKey]).component |
|||
|
|||
const updateEventHandler = (updatedHandler, index) => { |
|||
actions[index] = updatedHandler |
|||
} |
|||
|
|||
const deleteAction = index => { |
|||
actions.splice(index, 1) |
|||
actions = actions |
|||
} |
|||
|
|||
const addAction = actionType => () => { |
|||
const newAction = { |
|||
parameters: {}, |
|||
[eventTypeKey]: actionType.name, |
|||
} |
|||
actions.push(newAction) |
|||
selectedAction = newAction |
|||
actions = actions |
|||
addActionDropdown.hide() |
|||
} |
|||
|
|||
const selectAction = action => () => { |
|||
selectedAction = action |
|||
} |
|||
|
|||
const saveEventData = () => { |
|||
dispatch("change", actions) |
|||
} |
|||
</script> |
|||
|
|||
<div> |
|||
<div bind:this={addActionButton}> |
|||
<TextButton text small blue on:click={addActionDropdown.show}> |
|||
<div style="height: 20px; width: 20px;"> |
|||
<AddIcon /> |
|||
</div> |
|||
Add Action |
|||
</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> |
|||
{/each} |
|||
</div> |
|||
</DropdownMenu> |
|||
</div> |
|||
|
|||
<div class="actions-container"> |
|||
{#if actions && actions.length > 0} |
|||
{#each actions as action, index} |
|||
<div class="action-container"> |
|||
<div class="action-header" on:click={selectAction(action)}> |
|||
<Body small lh>{index + 1}. {action[eventTypeKey]}</Body> |
|||
<div class="row-expander" class:rotate={action !== selectedAction}> |
|||
<ArrowDownIcon /> |
|||
</div> |
|||
</div> |
|||
{#if action === selectedAction} |
|||
<div class="selected-action-container"> |
|||
<svelte:component |
|||
this={selectedActionComponent} |
|||
parameters={selectedAction.parameters} /> |
|||
<div class="delete-action-button"> |
|||
<TextButton text medium on:click={() => deleteAction(index)}> |
|||
Delete |
|||
</TextButton> |
|||
</div> |
|||
</div> |
|||
{/if} |
|||
</div> |
|||
{/each} |
|||
{/if} |
|||
<Button thin blue on:click={saveEventData}>Save</Button> |
|||
</div> |
|||
|
|||
<a href="https://docs.budibase.com">Learn more about Actions</a> |
|||
|
|||
<style> |
|||
.action-header { |
|||
display: flex; |
|||
flex-direction: row; |
|||
align-items: center; |
|||
} |
|||
|
|||
.action-header > p { |
|||
flex: 1; |
|||
} |
|||
|
|||
.row-expander { |
|||
height: 30px; |
|||
width: 30px; |
|||
} |
|||
|
|||
.available-action { |
|||
padding: var(--spacing-s); |
|||
font-size: var(--font-size-m); |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.available-action:hover { |
|||
background: var(--grey-2); |
|||
} |
|||
|
|||
.actions-container { |
|||
flex: 1; |
|||
min-height: 0; |
|||
padding-top: 0; |
|||
border: var(--border-light); |
|||
border-width: 0 0 1px 0; |
|||
overflow-y: auto; |
|||
} |
|||
|
|||
.action-container { |
|||
border: var(--border-light); |
|||
border-width: 1px 0 0 0; |
|||
} |
|||
|
|||
.selected-action-container { |
|||
padding-bottom: var(--spacing-s); |
|||
padding-top: var(--spacing-s); |
|||
} |
|||
|
|||
.delete-action-button { |
|||
padding-top: var(--spacing-l); |
|||
display: flex; |
|||
justify-content: flex-end; |
|||
flex-direction: row; |
|||
} |
|||
|
|||
a { |
|||
flex: 1; |
|||
color: var(--grey-5); |
|||
font-size: var(--font-size-s); |
|||
text-decoration: none; |
|||
} |
|||
a:hover { |
|||
color: var(--blue); |
|||
} |
|||
|
|||
.rotate :global(svg) { |
|||
transform: rotate(90deg); |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue