budibase/packages/builder/src/components/integration/index.svelte

199 lines
4.9 KiB
Svelte

<script>
import Editor from "./QueryEditor.svelte"
import FieldsBuilder from "./QueryFieldsBuilder.svelte"
import {
Label,
Input,
Divider,
Layout,
Icon,
Button,
ActionButton,
} from "@budibase/bbui"
const QueryTypes = {
SQL: "sql",
JSON: "json",
FIELDS: "fields",
FLOW: "flow",
}
export let query
export let datasource
export let schema
export let editable = true
export let height = 500
$: urlDisplay =
schema.urlDisplay &&
`${datasource.config.url}${
query.fields.path ? "/" + query.fields.path : ""
}${query.fields.queryString ? "?" + query.fields.queryString : ""}`
function updateQuery({ detail }) {
query.fields[schema.type] = detail.value
}
</script>
{#if schema}
{#key query._id}
{#if schema.type === QueryTypes.SQL}
<Editor
editorHeight={height}
label="Query"
mode="sql"
on:change={updateQuery}
readOnly={!editable}
value={query.fields.sql}
parameters={query.parameters}
/>
{:else if schema.type === QueryTypes.JSON}
<Editor
editorHeight={height}
label="Query"
mode="json"
on:change={updateQuery}
readOnly={!editable}
value={query.fields.json}
parameters={query.parameters}
/>
{:else if schema.type === QueryTypes.FIELDS}
<FieldsBuilder bind:fields={query.fields} {schema} {editable} />
{#if schema.urlDisplay}
<div class="url-row">
<Label small>URL</Label>
<Input thin outline disabled value={urlDisplay} />
</div>
{/if}
{:else if schema.type === QueryTypes.FLOW}
<br />
{#if !query.fields.steps}
<div class="controls">
<Button
secondary
slot="buttons"
on:click={() => {
query.fields.steps = [
{
key: "$match",
value: "{\n\t\n}",
},
]
}}>Add stage</Button
>
</div>
<br />
{:else}
{#each query.fields.steps as step, index}
<div class="block">
<div class="subblock">
<Divider noMargin />
<div class="blockSection">
<div class="block-options">
Stage {index + 1}
<ActionButton on:click={() => {}} icon="DeleteOutline" />
</div>
<Layout noPadding gap="S">
<div class="fields">
<div class="block-field">
<Input
value={step.key}
on:change={({ detail }) => {
query.fields.steps[index].key = detail
}}
/>
<Editor
editorHeight={height / 2}
mode="json"
value={step.value}
on:change={({ detail }) => {
query.fields.steps[index].value = detail
}}
/>
</div>
</div>
</Layout>
</div>
</div>
<div class="separator" />
{#if index === query.fields.steps.length - 1}
<Icon
hoverable
name="AddCircle"
size="S"
on:click={() => {
query.fields.steps = [
...query.fields.steps,
{
key: "$match",
value: "{\n\t\n}",
},
]
}}
/>
<br />
{/if}
</div>
{/each}
{/if}
{/if}
{/key}
{/if}
<style>
.url-row {
display: grid;
grid-template-columns: 20% 1fr;
grid-gap: var(--spacing-l);
align-items: center;
}
.blockSection {
padding: var(--spacing-xl);
}
.block {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
margin-top: -6px;
}
.subblock {
width: 480px;
font-size: 16px;
background-color: var(--background);
border: 1px solid var(--spectrum-global-color-gray-300);
border-radius: 4px 4px 4px 4px;
}
.block-options {
justify-content: space-between;
display: flex;
align-items: center;
padding-bottom: 24px;
}
.fields {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
gap: var(--spacing-s);
}
.block-field {
display: grid;
grid-gap: 5px;
}
.separator {
width: 1px;
height: 25px;
border-left: 1px dashed var(--grey-4);
color: var(--grey-4);
/* center horizontally */
align-self: center;
}
.controls {
display: flex;
align-items: center;
justify-content: right;
}
</style>