budibase/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte

259 lines
6.4 KiB
Svelte
Raw Normal View History

<script>
import { getBindableProperties } from "builderStore/dataBinding"
import {
Button,
Popover,
Divider,
Select,
2021-04-28 15:31:41 +02:00
Layout,
Heading,
Drawer,
2021-04-28 15:31:41 +02:00
DrawerContent,
} from "@budibase/bbui"
import { createEventDispatcher } from "svelte"
2021-03-23 11:54:03 +01:00
import { store, currentAsset } from "builderStore"
2021-04-01 11:29:47 +02:00
import {
tables as tablesStore,
queries as queriesStore,
} from "stores/backend"
import { datasources, integrations } from "stores/backend"
import { notifications } from "@budibase/bbui"
2021-01-08 19:22:03 +01:00
import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte"
2021-01-14 15:22:24 +01:00
import IntegrationQueryEditor from "components/integration/index.svelte"
const dispatch = createEventDispatcher()
let anchorRight, dropdownRight
let drawer
export let value = {}
export let otherSources
2021-02-24 12:57:53 +01:00
export let showAllQueries
$: text = value?.label ?? "Choose an option"
2021-05-04 12:32:22 +02:00
$: tables = $tablesStore.list.map(m => ({
label: m.name,
tableId: m._id,
type: "table",
}))
2021-03-23 11:54:03 +01:00
$: views = $tablesStore.list.reduce((acc, cur) => {
let viewsArr = Object.entries(cur.views).map(([key, value]) => ({
label: key,
name: key,
...value,
type: "view",
}))
return [...acc, ...viewsArr]
}, [])
2021-03-23 13:04:54 +01:00
$: queries = $queriesStore.list
2021-02-24 16:34:52 +01:00
.filter(
2021-05-04 12:32:22 +02:00
query => showAllQueries || query.queryVerb === "read" || query.readable
2021-02-24 16:34:52 +01:00
)
2021-05-04 12:32:22 +02:00
.map(query => ({
2021-01-27 18:29:30 +01:00
label: query.name,
name: query.name,
tableId: query._id,
...query,
schema: query.schema,
parameters: query.parameters,
type: "query",
}))
$: bindableProperties = getBindableProperties(
$currentAsset,
$store.selectedComponentId
)
2021-05-04 12:32:22 +02:00
$: queryBindableProperties = bindableProperties.map(property => ({
2021-01-08 19:22:03 +01:00
...property,
category: property.type === "instance" ? "Component" : "Table",
label: property.readableBinding,
2021-01-12 11:28:41 +01:00
path: property.readableBinding,
2021-01-08 19:22:03 +01:00
}))
$: links = bindableProperties
2021-05-04 12:32:22 +02:00
.filter(x => x.fieldSchema?.type === "link")
.map(property => {
return {
providerId: property.providerId,
label: property.readableBinding,
fieldName: property.fieldSchema.name,
tableId: property.fieldSchema.tableId,
type: "link",
// These properties will be enriched by the client library and provide
// details of the parent row of the relationship field, from context
rowId: `{{ ${property.providerId}._id }}`,
rowTableId: `{{ ${property.providerId}.tableId }}`,
}
})
2021-01-14 15:22:24 +01:00
function handleSelected(selected) {
dispatch("change", selected)
dropdownRight.hide()
}
function fetchQueryDefinition(query) {
2021-05-04 12:32:22 +02:00
const source = $datasources.list.find(ds => ds._id === query.datasourceId)
2021-04-01 11:29:47 +02:00
.source
return $integrations[source].query[query.queryVerb]
2021-01-14 15:22:24 +01:00
}
</script>
<div class="container" bind:this={anchorRight}>
<Select
readonly
value={text}
options={[text]}
on:click={dropdownRight.show}
/>
{#if value?.type === "query"}
<i class="ri-settings-5-line" on:click={drawer.show} />
<Drawer title={"Query Parameters"} bind:this={drawer}>
2021-04-28 15:31:41 +02:00
<Button
slot="buttons"
cta
on:click={() => {
notifications.success("Query parameters saved.")
2021-04-28 15:31:41 +02:00
handleSelected(value)
drawer.hide()
}}
>
2021-04-28 15:31:41 +02:00
Save
</Button>
<DrawerContent slot="body">
<Layout>
{#if value.parameters.length > 0}
<ParameterBuilder
bind:customParams={value.queryParams}
2021-05-04 12:32:22 +02:00
parameters={queries.find(query => query._id === value._id)
.parameters}
bindings={queryBindableProperties}
/>
2021-04-28 15:31:41 +02:00
{/if}
<IntegrationQueryEditor
height={200}
query={value}
schema={fetchQueryDefinition(value)}
datasource={$datasources.list.find(
2021-05-04 12:32:22 +02:00
ds => ds._id === value.datasourceId
)}
editable={false}
/>
2021-04-28 15:31:41 +02:00
</Layout>
</DrawerContent>
</Drawer>
{/if}
</div>
<Popover bind:this={dropdownRight} anchor={anchorRight}>
<div class="dropdown">
<div class="title">
<Heading size="XS">Tables</Heading>
</div>
<ul>
{#each tables as table}
2021-04-29 10:01:24 +02:00
<li on:click={() => handleSelected(table)}>{table.label}</li>
{/each}
</ul>
2021-04-27 16:25:39 +02:00
<Divider size="S" />
<div class="title">
<Heading size="XS">Views</Heading>
</div>
<ul>
{#each views as view}
2021-04-29 10:01:24 +02:00
<li on:click={() => handleSelected(view)}>{view.label}</li>
{/each}
</ul>
2021-04-27 16:25:39 +02:00
<Divider size="S" />
<div class="title">
<Heading size="XS">Relationships</Heading>
</div>
<ul>
{#each links as link}
2021-04-29 10:01:24 +02:00
<li on:click={() => handleSelected(link)}>{link.label}</li>
{/each}
</ul>
2021-04-27 16:25:39 +02:00
<Divider size="S" />
2020-12-18 19:19:43 +01:00
<div class="title">
<Heading size="XS">Queries</Heading>
2020-12-18 19:19:43 +01:00
</div>
<ul>
{#each queries as query}
<li
class:selected={value === query}
on:click={() => handleSelected(query)}
>
2020-12-18 19:19:43 +01:00
{query.label}
</li>
{/each}
</ul>
{#if otherSources?.length}
2021-04-27 16:25:39 +02:00
<Divider size="S" />
<div class="title">
<Heading size="XS">Other</Heading>
</div>
<ul>
{#each otherSources as source}
2021-04-29 10:01:24 +02:00
<li on:click={() => handleSelected(source)}>{source.label}</li>
{/each}
</ul>
{/if}
</div>
</Popover>
<style>
.container {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
}
.container :global(:first-child) {
flex: 1 1 auto;
}
.dropdown {
padding: var(--spacing-m) 0;
z-index: 99999999;
}
.title {
padding: 0 var(--spacing-m) var(--spacing-s) var(--spacing-m);
}
ul {
list-style: none;
padding-left: 0px;
margin: 0px;
}
li {
cursor: pointer;
margin: 0px;
padding: var(--spacing-s) var(--spacing-m);
2021-04-29 10:01:24 +02:00
font-size: var(--font-size-m);
}
.selected {
2021-04-29 10:01:24 +02:00
color: var(--spectrum-global-color-blue-600);
}
li:hover {
2021-04-29 10:01:24 +02:00
background-color: var(--spectrum-global-color-gray-200);
}
2021-01-08 19:22:03 +01:00
.drawer-contents {
padding: var(--spacing-l);
height: calc(40vh - 2 * var(--spacing-l));
2021-01-14 15:22:24 +01:00
overflow-y: auto;
2021-01-08 19:22:03 +01:00
}
2021-01-11 21:17:56 +01:00
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>