diff --git a/packages/bbui/src/Label/Label.svelte b/packages/bbui/src/Label/Label.svelte index a3a94b2836..7ec378fc29 100644 --- a/packages/bbui/src/Label/Label.svelte +++ b/packages/bbui/src/Label/Label.svelte @@ -19,6 +19,7 @@
(showTooltip = true)} on:mouseleave={() => (showTooltip = false)} > @@ -44,6 +45,7 @@ } .container { display: flex; + align-items: center; } .icon-container { position: relative; @@ -64,4 +66,8 @@ .icon { transform: scale(0.75); } + .icon-small { + margin-top: -2px; + margin-bottom: -5px; + } diff --git a/packages/builder/assets/bb-spaceship.svg b/packages/builder/assets/bb-spaceship.svg new file mode 100755 index 0000000000..a0bc5a49cd --- /dev/null +++ b/packages/builder/assets/bb-spaceship.svg @@ -0,0 +1,227 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte index 220bd41205..62a89af5b4 100644 --- a/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte +++ b/packages/builder/src/components/design/PropertiesPanel/PropertyControls/DataSourceSelect.svelte @@ -17,7 +17,7 @@ queries as queriesStore, } from "stores/backend" import { datasources, integrations } from "stores/backend" - import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte" + import BindingBuilder from "components/integration/QueryBindingBuilder.svelte" import IntegrationQueryEditor from "components/integration/index.svelte" import { makePropSafe as safe } from "@budibase/string-templates" @@ -148,15 +148,15 @@ /> {#if value?.type === "query"} - + - + {#if getQueryParams(value).length > 0} - {/if} import { Select, Layout, Input, Checkbox } from "@budibase/bbui" import { datasources, integrations, queries } from "stores/backend" - import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte" + import BindingBuilder from "components/integration/QueryBindingBuilder.svelte" import IntegrationQueryEditor from "components/integration/index.svelte" export let parameters @@ -53,10 +53,10 @@ {#if query?.parameters?.length > 0}
- ({ name, value })) let fieldActivity = [] @@ -76,8 +79,8 @@ {#if Object.keys(object || {}).length > 0} {#if headings}
- - + + {#if toggle} {/if} @@ -85,12 +88,16 @@ {/if}
{#each fields as field, idx} - + {#if options} diff --git a/packages/builder/src/components/integration/QueryParameterBuilder.svelte b/packages/builder/src/components/integration/QueryBindingBuilder.svelte similarity index 52% rename from packages/builder/src/components/integration/QueryParameterBuilder.svelte rename to packages/builder/src/components/integration/QueryBindingBuilder.svelte index 618cb2b442..dd688dceb6 100644 --- a/packages/builder/src/components/integration/QueryParameterBuilder.svelte +++ b/packages/builder/src/components/integration/QueryBindingBuilder.svelte @@ -1,5 +1,5 @@ - -
- Parameters + +
+ Bindings {#if !bindable} - + {/if}
{#if !bindable} - Parameters come in two parts: the parameter name, and a default/fallback - value. + Bindings come in two parts: the binding name, and a default/fallback + value. These bindings can be used as Handlebars expressions throughout the + query. {:else} - Enter a value for each parameter. The default values will be used for any + Enter a value for each binding. The default values will be used for any values left blank. {/if} -
- {#each parameters as parameter, idx} +
+ {#each bindings as binding, idx} {#if bindable} onBindingChange(parameter.name, evt.detail)} + on:change={evt => onBindingChange(binding.name, evt.detail)} value={runtimeToReadableBinding( - bindings, - customParams?.[parameter.name] + bindableOptions, + customParams?.[binding.name] )} - {bindings} + {bindableOptions} /> {:else} - deleteQueryParameter(idx)} - /> + deleteQueryBinding(idx)} /> {/if} {/each}
diff --git a/packages/builder/src/components/integration/QueryViewer.svelte b/packages/builder/src/components/integration/QueryViewer.svelte index aed3c4730d..f14d1d2b88 100644 --- a/packages/builder/src/components/integration/QueryViewer.svelte +++ b/packages/builder/src/components/integration/QueryViewer.svelte @@ -17,7 +17,7 @@ import ExtraQueryConfig from "./ExtraQueryConfig.svelte" import IntegrationQueryEditor from "components/integration/index.svelte" import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte" - import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte" + import BindingBuilder from "components/integration/QueryBindingBuilder.svelte" import { datasources, integrations, queries } from "stores/backend" import { capitalise } from "../../helpers" import CodeMirrorEditor from "components/common/CodeMirrorEditor.svelte" @@ -120,7 +120,7 @@ config={integrationInfo.extra} /> {/if} - + {/if}
{#if shouldShowQueryConfig} diff --git a/packages/builder/src/helpers/data/utils.js b/packages/builder/src/helpers/data/utils.js index b1c4139d52..03ee2bc602 100644 --- a/packages/builder/src/helpers/data/utils.js +++ b/packages/builder/src/helpers/data/utils.js @@ -49,3 +49,23 @@ export function buildQueryString(obj) { } return str } + +export function keyValueToQueryParameters(obj) { + let array = [] + if (obj && typeof obj === "object") { + for (let [key, value] of Object.entries(obj)) { + array.push({ name: key, default: value }) + } + } + return array +} + +export function queryParametersToKeyValue(array) { + let obj = {} + if (Array.isArray(array)) { + for (let param of array) { + obj[param.name] = param.default + } + } + return obj +} diff --git a/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/rest/[query]/index.svelte b/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/rest/[query]/index.svelte index 7d30b8a0a0..d1900aba67 100644 --- a/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/rest/[query]/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/data/datasource/[selectedDatasource]/rest/[query]/index.svelte @@ -13,6 +13,7 @@ Heading, RadioGroup, Label, + Body, TextArea, Table, notifications, @@ -30,6 +31,8 @@ schemaToFields, breakQueryString, buildQueryString, + keyValueToQueryParameters, + queryParametersToKeyValue, } from "helpers/data/utils" import { RestBodyTypes as bodyTypes, @@ -37,9 +40,11 @@ } from "constants/backend" import JSONPreview from "components/integration/JSONPreview.svelte" import AccessLevelSelect from "components/integration/AccessLevelSelect.svelte" + import Placeholder from "assets/bb-spaceship.svg" let query, datasource - let breakQs = {} + let breakQs = {}, + bindings = {} let url = "" let saveId let response, schema, isGet @@ -93,6 +98,7 @@ newQuery.fields.path = url.split("?")[0] newQuery.fields.queryString = queryString newQuery.schema = fieldsToSchema(schema) + newQuery.parameters = keyValueToQueryParameters(bindings) return newQuery } @@ -127,6 +133,7 @@ breakQs = breakQueryString(qs) url = buildUrl(query.fields.path, breakQs) schema = schemaToFields(query.schema) + bindings = queryParametersToKeyValue(query.parameters) if (query && !query.transformer) { query.transformer = "return data" } @@ -172,7 +179,17 @@
- + + + + @@ -223,6 +240,14 @@ {#if !response} Response +
+
+ placeholder + {"enter a url in the textbox above and click send to get a response".toUpperCase()} +
+
{:else} @@ -319,4 +344,15 @@ gap: var(--spacing-m); align-items: center; } + .placeholder-internal { + display: flex; + flex-direction: column; + width: 200px; + gap: var(--spacing-l); + } + .placeholder { + display: flex; + margin-top: var(--spacing-xl); + justify-content: center; + } diff --git a/packages/server/src/api/controllers/query/validation.js b/packages/server/src/api/controllers/query/validation.js index 2613e6806a..a17a752ca5 100644 --- a/packages/server/src/api/controllers/query/validation.js +++ b/packages/server/src/api/controllers/query/validation.js @@ -19,6 +19,7 @@ exports.queryValidation = () => { extra: Joi.object().optional(), schema: Joi.object({}).required().unknown(true), transformer: Joi.string().optional(), + flags: Joi.object().optional(), }) }