pass field values in binding drawer
This commit is contained in:
parent
267e85c2bf
commit
1b51113c44
|
@ -9,6 +9,7 @@ const INITIAL_BACKEND_UI_STATE = {
|
|||
roles: [],
|
||||
datasources: [],
|
||||
queries: [],
|
||||
integrations: {},
|
||||
selectedDatabase: {},
|
||||
selectedTable: {},
|
||||
draftTable: {},
|
||||
|
@ -27,11 +28,15 @@ export const getBackendUiStore = () => {
|
|||
const datasources = await datasourcesResponse.json()
|
||||
const queriesResponse = await api.get(`/api/queries`)
|
||||
const queries = await queriesResponse.json()
|
||||
const integrationsResponse = await api.get("/api/integrations")
|
||||
const integrations = await integrationsResponse.json()
|
||||
|
||||
store.update(state => {
|
||||
state.selectedDatabase = db
|
||||
state.tables = tables
|
||||
state.datasources = datasources
|
||||
state.queries = queries
|
||||
state.integrations = integrations
|
||||
return state
|
||||
})
|
||||
},
|
||||
|
@ -132,6 +137,7 @@ export const getBackendUiStore = () => {
|
|||
state.selectedQueryId = json._id
|
||||
return state
|
||||
})
|
||||
return json
|
||||
},
|
||||
select: queryId =>
|
||||
store.update(state => {
|
||||
|
|
|
@ -1,26 +1,33 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import { backendUiStore } from "builderStore"
|
||||
import { Input, TextArea, Spacer } from "@budibase/bbui"
|
||||
import api from "builderStore/api"
|
||||
import ICONS from "../icons"
|
||||
|
||||
const INTEGRATION_ICON_MAP = {
|
||||
POSTGRES: "ri-database-2-line",
|
||||
}
|
||||
|
||||
export let integration = {}
|
||||
|
||||
let integrationsPromise = fetchIntegrations()
|
||||
let selectedIntegrationConfig
|
||||
let schema
|
||||
let integrations = []
|
||||
|
||||
async function fetchIntegrations() {
|
||||
const response = await api.get("/api/integrations")
|
||||
const json = await response.json()
|
||||
|
||||
integrations = json
|
||||
return json
|
||||
}
|
||||
|
||||
function selectIntegration(integrationType) {
|
||||
schema = integrations[integrationType].datasource
|
||||
integration = {
|
||||
type: integrationType,
|
||||
...Object.keys(schema).reduce(
|
||||
(acc, next) => ({ ...acc, [next]: schema[next].default }),
|
||||
{}
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
fetchIntegrations()
|
||||
})
|
||||
|
@ -32,18 +39,7 @@
|
|||
<div
|
||||
class="integration hoverable"
|
||||
class:selected={integration.type === integrationType}
|
||||
on:click={() => {
|
||||
selectedIntegrationConfig = integrations[integrationType].datasource
|
||||
integration = { type: integrationType, ...Object.keys(selectedIntegrationConfig).reduce(
|
||||
(acc, next) => {
|
||||
return {
|
||||
...acc,
|
||||
[next]: selectedIntegrationConfig[next].default,
|
||||
}
|
||||
},
|
||||
{}
|
||||
) }
|
||||
}}>
|
||||
on:click={() => selectIntegration(integrationType)}>
|
||||
<svelte:component
|
||||
this={ICONS[integrationType]}
|
||||
height="100"
|
||||
|
@ -53,11 +49,11 @@
|
|||
{/each}
|
||||
</div>
|
||||
|
||||
{#if selectedIntegrationConfig}
|
||||
{#each Object.keys(selectedIntegrationConfig) as configKey}
|
||||
{#if schema}
|
||||
{#each Object.keys(schema) as configKey}
|
||||
<Input
|
||||
thin
|
||||
type={selectedIntegrationConfig[configKey].type}
|
||||
type={schema[configKey].type}
|
||||
label={configKey}
|
||||
bind:value={integration[configKey]} />
|
||||
<Spacer medium />
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
export let fields = {}
|
||||
export let schema
|
||||
export let editable
|
||||
|
||||
let customSchema = {}
|
||||
let draftField = {}
|
||||
|
@ -29,12 +30,13 @@
|
|||
{#each Object.keys(schema.fields) as field}
|
||||
<Label extraSmall grey>{field}</Label>
|
||||
<Input
|
||||
disabled={!editable}
|
||||
type={schema.fields[field]?.type}
|
||||
required={schema.fields[field]?.required}
|
||||
bind:value={fields[field]} />
|
||||
<Spacer medium />
|
||||
{/each}
|
||||
{#if schema.customisable}
|
||||
{#if schema.customisable && editable}
|
||||
<Spacer large />
|
||||
<Label>Add Custom Field</Label>
|
||||
{#each Object.keys(customSchema) as field}
|
||||
|
|
|
@ -40,8 +40,8 @@
|
|||
<div />
|
||||
{/if}
|
||||
{#each parameters as parameter, idx}
|
||||
<Input thin bind:value={parameter.name} />
|
||||
<Input thin bind:value={parameter.default} />
|
||||
<Input thin disabled={bindable} bind:value={parameter.name} />
|
||||
<Input thin disabled={bindable} bind:value={parameter.default} />
|
||||
{#if bindable}
|
||||
<BindableInput
|
||||
type="string"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import { goto } from "@sveltech/routify"
|
||||
import {
|
||||
Select,
|
||||
Button,
|
||||
|
@ -55,8 +56,9 @@
|
|||
{}
|
||||
)
|
||||
|
||||
$: datasourceType = datasource.source
|
||||
$: datasourceType && fetchQueryConfig()
|
||||
$: datasourceType = datasource?.source
|
||||
|
||||
$: config = $backendUiStore.integrations[datasourceType]?.query
|
||||
|
||||
$: shouldShowQueryConfig = config && query.queryVerb && query.queryType
|
||||
|
||||
|
@ -69,17 +71,6 @@
|
|||
fields = fields
|
||||
}
|
||||
|
||||
async function fetchQueryConfig() {
|
||||
try {
|
||||
const response = await api.get(`/api/integrations/${datasource.source}`)
|
||||
const json = await response.json()
|
||||
config = json.query
|
||||
} catch (err) {
|
||||
notifier.danger("Error fetching integration configuration.")
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
async function previewQuery() {
|
||||
try {
|
||||
const response = await api.post(`/api/queries/preview`, {
|
||||
|
@ -115,8 +106,12 @@
|
|||
|
||||
async function saveQuery() {
|
||||
try {
|
||||
await backendUiStore.actions.queries.save(query.datasourceId, query)
|
||||
const { _id } = await backendUiStore.actions.queries.save(
|
||||
query.datasourceId,
|
||||
query
|
||||
)
|
||||
notifier.success(`Query saved successfully.`)
|
||||
$goto(`../../${_id}`)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
notifier.danger(`Error creating query. ${err.message}`)
|
||||
|
@ -161,9 +156,10 @@
|
|||
<Spacer medium />
|
||||
|
||||
<IntegrationQueryEditor
|
||||
schema={config[query.queryVerb][query.queryType]}
|
||||
{query}
|
||||
bind:parameters />
|
||||
schema={config[query.queryVerb][query.queryType]}
|
||||
bind:parameters
|
||||
/>
|
||||
|
||||
<Spacer medium />
|
||||
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
<script>
|
||||
import CodeMirror from "./codemirror"
|
||||
import { onMount, createEventDispatcher } from "svelte"
|
||||
import { themeStore } from "builderStore"
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const THEMES = {
|
||||
DARK: "tomorrow-night-eighties",
|
||||
LIGHT: "default",
|
||||
}
|
||||
|
||||
export let value = ""
|
||||
export let readonly = false
|
||||
export let errorLoc = null
|
||||
export let readOnly = false
|
||||
export let lineNumbers = true
|
||||
export let tab = true
|
||||
export let mode
|
||||
|
||||
let w
|
||||
let h
|
||||
let width
|
||||
let height
|
||||
|
||||
// We have to expose set and update methods, rather
|
||||
// than making this state-driven through props,
|
||||
|
@ -72,43 +77,10 @@
|
|||
let error_line
|
||||
let destroyed = false
|
||||
|
||||
$: if (editor && w && h) {
|
||||
$: if (editor && width && height) {
|
||||
editor.refresh()
|
||||
}
|
||||
|
||||
$: {
|
||||
if (marker) marker.clear()
|
||||
|
||||
if (errorLoc) {
|
||||
const line = errorLoc.line - 1
|
||||
const ch = errorLoc.column
|
||||
|
||||
marker = editor.markText(
|
||||
{ line, ch },
|
||||
{ line, ch: ch + 1 },
|
||||
{
|
||||
className: "error-loc",
|
||||
}
|
||||
)
|
||||
|
||||
error_line = line
|
||||
} else {
|
||||
error_line = null
|
||||
}
|
||||
}
|
||||
|
||||
let previous_error_line
|
||||
$: if (editor) {
|
||||
if (previous_error_line != null) {
|
||||
editor.removeLineClass(previous_error_line, "wrap", "error-line")
|
||||
}
|
||||
|
||||
if (error_line && error_line !== previous_error_line) {
|
||||
editor.addLineClass(error_line, "wrap", "error-line")
|
||||
previous_error_line = error_line
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
createEditor(mode).then(() => {
|
||||
if (editor) editor.setValue(value || "")
|
||||
|
@ -137,9 +109,10 @@
|
|||
mode: modes[mode] || {
|
||||
name: mode,
|
||||
},
|
||||
readOnly: readonly,
|
||||
readOnly,
|
||||
autoCloseBrackets: true,
|
||||
autoCloseTags: true,
|
||||
theme: $themeStore.darkMode ? THEMES.DARK : THEMES.LIGHT,
|
||||
}
|
||||
|
||||
if (!tab)
|
||||
|
@ -182,6 +155,7 @@
|
|||
}
|
||||
|
||||
:global(.CodeMirror) {
|
||||
height: auto !important;
|
||||
border-radius: var(--border-radius-m);
|
||||
font-family: var(--font-sans) !important;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import CodeMirror from "codemirror"
|
||||
import "codemirror/lib/codemirror.css"
|
||||
import "codemirror/theme/tomorrow-night-eighties.css"
|
||||
import "codemirror/theme/neo.css"
|
||||
import "codemirror/mode/sql/sql"
|
||||
import "codemirror/mode/css/css"
|
||||
import "codemirror/mode/handlebars/handlebars"
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script>
|
||||
import { onMount } from "svelte"
|
||||
import { TextArea, Label, Input, Heading, Spacer } from "@budibase/bbui"
|
||||
import Editor from "./SvelteEditor.svelte"
|
||||
import ParameterBuilder from "./QueryParameterBuilder.svelte"
|
||||
|
@ -12,14 +13,17 @@
|
|||
|
||||
export let query
|
||||
export let schema
|
||||
export let editable = true
|
||||
|
||||
function updateQuery({ detail }) {
|
||||
query.fields[schema.type] = detail.value
|
||||
}
|
||||
</script>
|
||||
|
||||
<ParameterBuilder bind:parameters={query.parameters} bindable={false} />
|
||||
<Spacer large />
|
||||
{#if editable}
|
||||
<ParameterBuilder bind:parameters={query.parameters} bindable={false} />
|
||||
<Spacer large />
|
||||
{/if}
|
||||
|
||||
<Heading extraSmall black>Query</Heading>
|
||||
<Spacer large />
|
||||
|
@ -30,6 +34,7 @@
|
|||
label="Query"
|
||||
mode="sql"
|
||||
on:change={updateQuery}
|
||||
readOnly={!editable}
|
||||
value={query.fields.sql} />
|
||||
{:else if schema.type === QueryTypes.JSON}
|
||||
<Spacer large />
|
||||
|
@ -37,8 +42,9 @@
|
|||
label="Query"
|
||||
mode="json"
|
||||
on:change={updateQuery}
|
||||
readOnly={!editable}
|
||||
value={query.fields.json} />
|
||||
{:else if schema.type === QueryTypes.FIELDS}
|
||||
<FieldsBuilder bind:fields={query.fields} {schema} />
|
||||
<FieldsBuilder bind:fields={query.fields} {schema} {editable} />
|
||||
{/if}
|
||||
{/if}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
import { notifier } from "builderStore/store/notifications"
|
||||
import BottomDrawer from "components/common/BottomDrawer.svelte"
|
||||
import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte"
|
||||
import IntegrationQueryEditor from "components/integration/index.svelte"
|
||||
import fetchBindableProperties from "../../builderStore/fetchBindableProperties"
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
@ -13,18 +14,6 @@
|
|||
|
||||
export let value = {}
|
||||
|
||||
function handleSelected(selected) {
|
||||
dispatch("change", selected)
|
||||
dropdownRight.hide()
|
||||
}
|
||||
|
||||
function openBindingDrawer() {
|
||||
bindingDrawerOpen = true
|
||||
}
|
||||
|
||||
function closeDatabindingDrawer() {
|
||||
bindingDrawerOpen = false
|
||||
}
|
||||
|
||||
$: tables = $backendUiStore.tables.map(m => ({
|
||||
label: m.name,
|
||||
|
@ -78,6 +67,24 @@
|
|||
type: "link",
|
||||
}
|
||||
})
|
||||
|
||||
function handleSelected(selected) {
|
||||
dispatch("change", selected)
|
||||
dropdownRight.hide()
|
||||
}
|
||||
|
||||
function openBindingDrawer() {
|
||||
bindingDrawerOpen = true
|
||||
}
|
||||
|
||||
function closeDatabindingDrawer() {
|
||||
bindingDrawerOpen = false
|
||||
}
|
||||
|
||||
function fetchDatasourceSchema(query) {
|
||||
const source = $backendUiStore.datasources.find(ds => ds._id === query.datasourceId).source
|
||||
return $backendUiStore.integrations[source].query[query.queryVerb][query.queryType];
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
|
@ -98,11 +105,18 @@
|
|||
}}>Save</Button>
|
||||
</div>
|
||||
<div class="drawer-contents" slot="body">
|
||||
<pre>{value.queryString}</pre>
|
||||
<ParameterBuilder
|
||||
bind:customParams={value.queryParams}
|
||||
parameters={value.parameters || []}
|
||||
bindings={queryBindableProperties} />
|
||||
<IntegrationQueryEditor
|
||||
query={value}
|
||||
schema={fetchDatasourceSchema(value)}
|
||||
editable={false}
|
||||
/>
|
||||
<Spacer large />
|
||||
{#if value.parameters.length > 0}
|
||||
<ParameterBuilder
|
||||
bind:customParams={value.queryParams}
|
||||
parameters={value.parameters}
|
||||
bindings={queryBindableProperties} />
|
||||
{/if}
|
||||
</div>
|
||||
</BottomDrawer>
|
||||
{/if}
|
||||
|
@ -229,6 +243,8 @@
|
|||
|
||||
.drawer-contents {
|
||||
padding: var(--spacing-xl);
|
||||
height: 40vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
i {
|
||||
|
|
|
@ -17,24 +17,33 @@
|
|||
}
|
||||
}
|
||||
|
||||
$: {
|
||||
if ($params.query !== "new") {
|
||||
query = $backendUiStore.queries.find(query => query._id === $params.query)
|
||||
} else {
|
||||
// New query
|
||||
query = {
|
||||
datasourceId: $params.selectedDatasource,
|
||||
name: "New Query",
|
||||
parameters: [],
|
||||
fields: {},
|
||||
}
|
||||
}
|
||||
$: selectedQuery = $backendUiStore.queries.find(
|
||||
query => query._id === $backendUiStore.selectedQueryId
|
||||
) || {
|
||||
datasourceId: $params.selectedDatasource,
|
||||
name: "New Query",
|
||||
parameters: [],
|
||||
fields: {},
|
||||
}
|
||||
|
||||
// $: {
|
||||
// if ($params.query !== "new") {
|
||||
// query = $backendUiStore.queries.find(query => query._id === $params.query)
|
||||
// } else {
|
||||
// // New query
|
||||
// query = {
|
||||
// datasourceId: $params.selectedDatasource,
|
||||
// name: "New Query",
|
||||
// parameters: [],
|
||||
// fields: {},
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
</script>
|
||||
|
||||
<section>
|
||||
{#if $backendUiStore.selectedDatabase._id && query}
|
||||
<QueryInterface {query} />
|
||||
{#if $backendUiStore.selectedDatabase._id && selectedQuery}
|
||||
<QueryInterface query={selectedQuery} />
|
||||
{/if}
|
||||
</section>
|
||||
|
||||
|
|
Loading…
Reference in New Issue