forked from tsai/budibase
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> |
<script> |
||||
import BottomDrawer from "components/common/BottomDrawer.svelte" |
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 { 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( |
export let query |
||||
query => query._id === $backendUiStore.selectedQueryId |
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() { |
function closeDatabindingDrawer() { |
||||
store.update(state => { |
store.update(state => { |
||||
state.bindingDrawerVisible = false |
state.bottomDrawerVisible = false |
||||
return state |
return state |
||||
}) |
}) |
||||
} |
} |
||||
|
|
||||
|
function saveComponentQuery() { |
||||
|
// save the parameters to the datasource of the component |
||||
|
} |
||||
</script> |
</script> |
||||
|
|
||||
{#if query} |
{#if query} |
||||
<BottomDrawer> |
<BottomDrawer title={'Query'} onClose={closeDatabindingDrawer}> |
||||
<div class="drawer-contents"> |
<div slot="buttons"> |
||||
<i class="ri-close-fill close" on:click={closeDatabindingDrawer} /> |
<Button blue thin on:click={saveComponentQuery}>Save</Button> |
||||
<QueryInterface {query} /> |
</div> |
||||
|
<div class="drawer-contents" slot="body"> |
||||
|
<pre>{query.queryString}</pre> |
||||
|
<ParameterBuilder |
||||
|
bind:customParams={parameters} |
||||
|
parameters={query.parameters} |
||||
|
bindings={bindableProperties} /> |
||||
</div> |
</div> |
||||
</BottomDrawer> |
</BottomDrawer> |
||||
{/if} |
{/if} |
||||
|
|
||||
<style> |
<style> |
||||
i { |
.drawer-contents { |
||||
position: absolute; |
display: grid; |
||||
top: var(--spacing-xl); |
grid-auto-flow: column; |
||||
right: var(--spacing-xl); |
grid-template-columns: 20% 1fr; |
||||
font-size: var(--font-size-m); |
grid-gap: var(--spacing-m); |
||||
|
height: 100%; |
||||
|
padding: var(--spacing-xl); |
||||
} |
} |
||||
</style> |
</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