styling, async data fetching

This commit is contained in:
Martin McKeaveney 2021-01-11 20:17:56 +00:00
parent 391dabf7a1
commit 49477d3ac9
8 changed files with 79 additions and 44 deletions

View File

@ -13,7 +13,6 @@
$backendUiStore.selectedView && $backendUiStore.selectedView.name $backendUiStore.selectedView && $backendUiStore.selectedView.name
function selectDatasource(datasource) { function selectDatasource(datasource) {
// You can't actually select a datasource, just edit it
backendUiStore.actions.datasources.select(datasource._id) backendUiStore.actions.datasources.select(datasource._id)
$goto(`./datasource/${datasource._id}`) $goto(`./datasource/${datasource._id}`)
} }

View File

@ -2,6 +2,7 @@
import { Button, TextArea, Label, Input, Heading } from "@budibase/bbui" import { Button, TextArea, Label, Input, Heading } from "@budibase/bbui"
import BindableInput from "components/userInterface/BindableInput.svelte" import BindableInput from "components/userInterface/BindableInput.svelte"
export let bindable = true
export let parameters = [] export let parameters = []
export let bindings = [] export let bindings = []
export let customParams = {} export let customParams = {}
@ -18,19 +19,23 @@
<section> <section>
<Heading extraSmall black>Parameters</Heading> <Heading extraSmall black>Parameters</Heading>
<div class="parameters"> <div class="parameters" class:bindable>
<Label extraSmall grey>Parameter Name</Label> <Label extraSmall grey>Parameter Name</Label>
<Label extraSmall grey>Default</Label> <Label extraSmall grey>Default</Label>
{#if bindable}
<Label extraSmall grey>Value</Label> <Label extraSmall grey>Value</Label>
{/if}
<div /> <div />
{#each parameters as parameter, idx} {#each parameters as parameter, idx}
<Input thin bind:value={parameter.name} /> <Input thin bind:value={parameter.name} />
<Input thin bind:value={parameter.default} /> <Input thin bind:value={parameter.default} />
{#if bindable}
<BindableInput <BindableInput
type="string" type="string"
thin thin
bind:value={customParams[parameter.name]} bind:value={customParams[parameter.name]}
{bindings} /> {bindings} />
{/if}
<i <i
class="ri-close-circle-line delete" class="ri-close-circle-line delete"
on:click={() => deleteQueryParameter(idx)} /> on:click={() => deleteQueryParameter(idx)} />
@ -40,9 +45,13 @@
</section> </section>
<style> <style>
.parameters.bindable {
grid-template-columns: 1fr 1fr 1fr 5%;
}
.parameters { .parameters {
display: grid; display: grid;
grid-template-columns: 1fr 1fr 1fr 5%; grid-template-columns: 1fr 1fr 5%;
grid-gap: 10px; grid-gap: 10px;
align-items: center; align-items: center;
margin-bottom: var(--spacing-xl); margin-bottom: var(--spacing-xl);

View File

@ -117,7 +117,7 @@
async function saveQuery() { async function saveQuery() {
try { try {
await backendUiStore.actions.queries.save(query.datasourceId, query) await backendUiStore.actions.queries.save(query.datasourceId, query)
notifier.success(`Query created successfully.`) notifier.success(`Query saved successfully.`)
} catch (err) { } catch (err) {
console.error(err) console.error(err)
notifier.danger(`Error creating query. ${err.message}`) notifier.danger(`Error creating query. ${err.message}`)
@ -146,12 +146,12 @@
<Spacer medium /> <Spacer medium />
<section class="viewer">
<div class="viewer-controls"> <div class="viewer-controls">
<Button wide thin blue on:click={previewQuery}>Run</Button> <Button wide thin blue disabled={!data} on:click={saveQuery}>Save</Button>
<Button wide thin primary on:click={saveQuery}>Save</Button> <Button wide thin primary on:click={previewQuery}>Run</Button>
</div> </div>
<section class="viewer">
{#if data} {#if data}
<Switcher headings={PREVIEW_HEADINGS} bind:value={tab}> <Switcher headings={PREVIEW_HEADINGS} bind:value={tab}>
{#if tab === 'JSON'} {#if tab === 'JSON'}
@ -208,14 +208,14 @@
} }
.viewer { .viewer {
position: relative;
} }
.viewer-controls { .viewer-controls {
position: absolute;
right: 0;
display: grid; display: grid;
grid-gap: var(--spacing-m); grid-gap: var(--spacing-m);
grid-auto-flow: column; grid-auto-flow: column;
direction: rtl;
grid-template-columns: 10% 10% 1fr;
margin-bottom: var(--spacing-m);
} }
</style> </style>

View File

@ -15,7 +15,8 @@
</script> </script>
{#if query.queryType === QueryTypes.SQL} {#if query.queryType === QueryTypes.SQL}
<ParameterBuilder bind:parameters={query.parameters} /> <ParameterBuilder bind:parameters={query.parameters} bindable={false} />
<Spacer large /> <Spacer large />
<Editor label="Query" on:change={updateQuery} value={query.queryString} /> <TextArea bind:value={query.queryString} />
<!-- <Editor label="Query" on:change={updateQuery} value={query.queryString} /> -->
{/if} {/if}

View File

@ -132,6 +132,7 @@
display: flex; display: flex;
flex-direction: row; flex-direction: row;
align-items: center; align-items: center;
margin-top: var(--spacing-m);
} }
.action-header > span { .action-header > span {
@ -146,6 +147,7 @@
.actions-list { .actions-list {
border: var(--border-light); border: var(--border-light);
padding: var(--spacing-s);
} }
.available-action { .available-action {
@ -159,14 +161,13 @@
} }
.actions-container { .actions-container {
height: 40vh;
display: grid; display: grid;
grid-gap: var(--spacing-m); grid-gap: var(--spacing-m);
grid-template-columns: 15% 1fr; grid-template-columns: 15% 1fr;
grid-auto-flow: column; grid-auto-flow: column;
min-height: 0; min-height: 0;
padding-top: 0; padding-top: 0;
border: var(--border-light);
border-width: 0 0 1px 0;
overflow-y: auto; overflow-y: auto;
} }

View File

@ -89,6 +89,23 @@
<span>{value.label ? value.label : 'Table / View / Query'}</span> <span>{value.label ? value.label : 'Table / View / Query'}</span>
<Icon name="arrowdown" /> <Icon name="arrowdown" />
</div> </div>
{#if value.type === "query"}
<i class="ri-settings-5-line" on:click={openBindingDrawer}/>
{#if bindingDrawerOpen}
<BottomDrawer title={'Query'} onClose={closeDatabindingDrawer}>
<div slot="buttons">
<Button blue thin on:click={() => handleSelected(value)}>Save</Button>
</div>
<div class="drawer-contents" slot="body">
<pre>{value.queryString}</pre>
<ParameterBuilder
bind:customParams={value.queryParams}
parameters={value.parameters || []}
bindings={queryBindableProperties} />
</div>
</BottomDrawer>
{/if}
{/if}
<DropdownMenu bind:this={dropdownRight} anchor={anchorRight}> <DropdownMenu bind:this={dropdownRight} anchor={anchorRight}>
<div class="dropdown"> <div class="dropdown">
<div class="title"> <div class="title">
@ -146,24 +163,6 @@
</div> </div>
</DropdownMenu> </DropdownMenu>
{#if value.type === "query"}
<Button blue on:click={openBindingDrawer}/>
{#if bindingDrawerOpen}
<BottomDrawer title={'Query'} onClose={closeDatabindingDrawer}>
<div slot="buttons">
<Button blue thin on:click={() => handleSelected(value)}>Save</Button>
</div>
<div class="drawer-contents" slot="body">
<pre>{value.queryString}</pre>
<ParameterBuilder
bind:customParams={value.queryParams}
parameters={value.parameters || []}
bindings={queryBindableProperties} />
</div>
</BottomDrawer>
{/if}
{/if}
<style> <style>
.dropdownbutton { .dropdownbutton {
@ -230,4 +229,17 @@
.drawer-contents { .drawer-contents {
padding: var(--spacing-xl); padding: var(--spacing-xl);
} }
i {
margin-left: 5px;
display: flex;
align-items: center;
transition: all 0.2s;
}
i:hover {
transform: scale(1.1);
font-weight: 500;
cursor: pointer;
}
</style> </style>

View File

@ -24,11 +24,18 @@ export const fetchDatasource = async (datasource, dataContext) => {
rows = await fetchViewData(datasource) rows = await fetchViewData(datasource)
} else if (type === "query") { } else if (type === "query") {
const bindings = get(bindingStore) const bindings = get(bindingStore)
const fullContext = {
// TODO: refactor. Set these defaults up somewhere else
let queryParams = datasource.queryParams || {}
for (let param of datasource.parameters) {
if (!queryParams[param.name]) {
queryParams[param.name] = param.default
}
}
const parameters = enrichDataBindings(queryParams, {
...bindings, ...bindings,
...dataContext, ...dataContext,
} })
const parameters = enrichDataBindings(datasource.queryParams, fullContext)
return await executeQuery({ queryId: datasource._id, parameters }) return await executeQuery({ queryId: datasource._id, parameters })
} else if (type === "link") { } else if (type === "link") {
const row = dataContext[datasource.providerId] const row = dataContext[datasource.providerId]

View File

@ -10,9 +10,15 @@
let rows = [] let rows = []
$: datasource && fetchData()
async function fetchData() {
rows = await API.fetchDatasource(datasource, $dataContext)
}
onMount(async () => { onMount(async () => {
if (!isEmpty(datasource)) { if (!isEmpty(datasource)) {
rows = await API.fetchDatasource(datasource, $dataContext) fetchData()
} }
}) })
</script> </script>