Update entire builder backend UI to work with new spectrum components and fix multiple issues

This commit is contained in:
Andrew Kingston 2021-04-20 11:53:19 +01:00
parent a49d54fb1a
commit 9482112d6b
13 changed files with 105 additions and 195 deletions

View File

@ -1,14 +1,16 @@
<script>
import "@spectrum-css/divider/dist/index-vars.css"
export let l = false
export let m = false
export let s = false
export let vertical = false
import "@spectrum-css/divider/dist/index-vars.css"
export let l = false
export let m = false
export let s = false
export let vertical = false
$: useDefault = ![l, m, s].includes(true)
</script>
<hr
class:spectrum-Divider--sizeL={l}
class:spectrum-Divider--sizeM={m}
class:spectrum-Divider--sizeS={s}
class="spectrum-Divider spectrum-Divider--{vertical ? 'vertical' : 'horizontal'} spectrum-Dialog-divider">
class:spectrum-Divider--sizeL={l}
class:spectrum-Divider--sizeM={m || useDefault}
class:spectrum-Divider--sizeS={s}
class="spectrum-Divider spectrum-Divider--{vertical ? 'vertical' : 'horizontal'} spectrum-Dialog-divider" />

View File

@ -72,6 +72,7 @@
placeholder={placeholder || ''}
on:blur={onBlur}
on:focus={onFocus}
on:input
{type}
class="spectrum-Textfield-input" />
</div>

View File

@ -28,5 +28,6 @@
{placeholder}
{type}
on:change={onChange}
on:click />
on:click
on:input />
</Field>

View File

@ -1,78 +1,28 @@
<script>
import "@spectrum-css/typography/dist/index-vars.css"
import "@spectrum-css/typography/dist/index-vars.css"
// Level
export let h1 = false;
export let h2 = false;
export let h3 = false;
export let h4 = false;
// Sizes
export let xxxl = false;
export let xxl = false;
export let xl = false;
export let l = false;
export let m = false;
export let s = false;
export let xs = false;
export let xxs = false;
export let serif = false;
// Sizes
export let xxxl = false
export let xxl = false
export let xl = false
export let l = false
export let m = false
export let s = false
export let xs = false
export let xxs = false
$: useDefault = ![xxxl, xxl, xl, l, m, s, xs, xxs].includes(true)
</script>
{#if h1}
<h1 class="spectrum-Heading"
class:spectrum-Heading--serif={serif}
class:spectrum-Heading--sizeXXXL={xxxl}
class:spectrum-Heading--sizeXXL={xxl}
class:spectrum-Heading--sizeXL={xl}
class:spectrum-Heading--sizeL={l}
class:spectrum-Heading--sizeM={m}
class:spectrum-Heading--sizeS={s}
class:spectrum-Heading--sizeXS={xs}
class:spectrum-Heading--sizeXXS={xxs}>
<slot />
</h1>
{:else if h2}
<h2 class="spectrum-Heading"
class:spectrum-Heading--serif={serif}
class:spectrum-Heading--sizeXXXL={xxxl}
class:spectrum-Heading--sizeXXL={xxl}
class:spectrum-Heading--sizeXL={xl}
class:spectrum-Heading--sizeL={l}
class:spectrum-Heading--sizeM={m}
class:spectrum-Heading--sizeS={s}
class:spectrum-Heading--sizeXS={xs}
class:spectrum-Heading--sizeXXS={xxs}>
<slot />
</h2>
{:else if h3}
<h3 class="spectrum-Heading"
class:spectrum-Heading--serif={serif}
class:spectrum-Heading--sizeXXXL={xxxl}
class:spectrum-Heading--sizeXXL={xxl}
class:spectrum-Heading--sizeXL={xl}
class:spectrum-Heading--sizeL={l}
class:spectrum-Heading--sizeM={m}
class:spectrum-Heading--sizeS={s}
class:spectrum-Heading--sizeXS={xs}
class:spectrum-Heading--sizeXXS={xxs}>
<slot />
</h3>
{:else if h4}
<h4 class="spectrum-Heading"
class:spectrum-Heading--serif={serif}
class:spectrum-Heading--sizeXXXL={xxxl}
class:spectrum-Heading--sizeXXL={xxl}
class:spectrum-Heading--sizeXL={xl}
class:spectrum-Heading--sizeL={l}
class:spectrum-Heading--sizeM={m}
class:spectrum-Heading--sizeS={s}
class:spectrum-Heading--sizeXS={xs}
class:spectrum-Heading--sizeXXS={xxs}>
<slot />
</h4>
{:else}
SPECIFY HEADING SIZE!
{/if}
<h1
class="spectrum-Heading"
class:spectrum-Heading--sizeXXXL={xxxl}
class:spectrum-Heading--sizeXXL={xxl}
class:spectrum-Heading--sizeXL={xl}
class:spectrum-Heading--sizeL={l}
class:spectrum-Heading--sizeM={m || useDefault}
class:spectrum-Heading--sizeS={s}
class:spectrum-Heading--sizeXS={xs}
class:spectrum-Heading--sizeXXS={xxs}>
<slot />
</h1>

View File

@ -11,7 +11,7 @@
{#if error}
<div class="errors">{error}</div>
{/if}
<Table title={''} schema={query.schema} {data} {loading} />
<Table schema={query.schema} {data} {loading} rowCount={5} />
<style>
.errors {

View File

@ -22,6 +22,7 @@
export let loading = false
export let theme = "alpine"
export let hideAutocolumns
export let rowCount
let selectedRows = []
let editableColumn
@ -91,7 +92,9 @@
<div>
<div class="table-title">
<h1>{title}</h1>
{#if title}
<h1>{title}</h1>
{/if}
{#if loading}
<div transition:fade>
<Spinner size="10" />
@ -111,6 +114,7 @@
{schema}
{loading}
{customRenderers}
{rowCount}
bind:selectedRows
allowSelectRows={allowEditing}
allowEditRows={allowEditing}

View File

@ -1,6 +1,7 @@
<script>
import { Label, Input, TextArea, Spacer } from "@budibase/bbui"
import { Label, Input, Spacer } from "@budibase/bbui"
import KeyValueBuilder from "components/integration/KeyValueBuilder.svelte"
import { capitalise } from "../../../../helpers"
export let integration
export let schema
@ -11,16 +12,15 @@
<form>
{#each Object.keys(schema) as configKey}
{#if schema[configKey].type === 'object'}
<Label small>{configKey}</Label>
<Label>{capitalise(configKey)}</Label>
<Spacer small />
<KeyValueBuilder
defaults={schema[configKey].default}
bind:object={integration[configKey]} />
{:else}
<div class="form-row">
<Label small>{configKey}</Label>
<Label>{capitalise(configKey)}</Label>
<Input
outline
type={schema[configKey].type}
on:change
bind:value={integration[configKey]} />

View File

@ -47,11 +47,10 @@
disabled={error || !name}>
<Input
data-cy="datasource-name-input"
thin
label="Datasource Name"
on:input={checkValid}
bind:value={name}
{error} />
<Label grey extraSmall>Source</Label>
<Label>Source</Label>
<TableIntegrationMenu bind:integration />
</ModalContent>

View File

@ -25,8 +25,8 @@
<!-- Builds Objects with Key Value Pairs. Useful for building things like Request Headers. -->
<div class="container" class:readOnly>
{#each fields as field, idx}
<Input placeholder="Key" thin outline bind:value={field.name} />
<Input placeholder="Value" thin outline bind:value={field.value} />
<Input placeholder="Key" bind:value={field.name} />
<Input placeholder="Value" bind:value={field.value} />
{#if !readOnly}
<i class="ri-close-circle-fill" on:click={() => deleteEntry(idx)} />
{/if}

View File

@ -31,9 +31,9 @@
<section>
<div class="controls">
<Heading small lh>Parameters</Heading>
<Heading>Parameters</Heading>
{#if !bindable}
<Button on:click={newQueryParameter}>Add Param</Button>
<Button secondary on:click={newQueryParameter}>Add Param</Button>
{/if}
</div>
<Body small grey>

View File

@ -10,12 +10,13 @@
Spacer,
Switcher,
} from "@budibase/bbui"
import { notifications } from "@budibase/bbui"
import { notifications, Divider } from "@budibase/bbui"
import api from "builderStore/api"
import IntegrationQueryEditor from "components/integration/index.svelte"
import ExternalDataSourceTable from "components/backend/DataTable/ExternalDataSourceTable.svelte"
import ParameterBuilder from "components/integration/QueryParameterBuilder.svelte"
import { datasources, integrations, queries } from "stores/backend"
import { capitalise } from "../../helpers"
const PREVIEW_HEADINGS = [
{
@ -38,9 +39,14 @@
let tab = "JSON"
let parameters
let data = []
const typeOptions = [
{ label: "Text", value: "STRING" },
{ label: "Number", value: "NUMBER" },
{ label: "Boolean", value: "BOOLEAN" },
{ label: "Datetime", value: "DATETIME" },
]
$: datasource = $datasources.list.find(ds => ds._id === query.datasourceId)
$: query.schema = fields.reduce(
(acc, next) => ({
...acc,
@ -51,12 +57,9 @@
}),
{}
)
$: datasourceType = datasource?.source
$: integrationInfo = $integrations[datasourceType]
$: queryConfig = integrationInfo?.query
$: shouldShowQueryConfig = queryConfig && query.queryVerb
function newField() {
@ -113,7 +116,7 @@
try {
const { _id } = await queries.save(query.datasourceId, query)
notifications.success(`Query saved successfully.`)
$goto(`../../${_id}`)
$goto(`../${_id}`)
} catch (err) {
console.error(err)
notifications.error(`Error creating query. ${err.message}`)
@ -122,57 +125,53 @@
</script>
<section class="config">
<Heading medium lh>Query {integrationInfo?.friendlyName}</Heading>
<hr />
<Spacer extraLarge />
<Heading small lh>Config</Heading>
<Heading>Query {integrationInfo?.friendlyName}</Heading>
<Spacer extraLarge />
<Divider />
<Spacer extraLarge />
<Heading>Config</Heading>
<Body small grey>Provide a name for your query and select its function.</Body>
<Spacer large />
<Spacer medium />
<div class="config-field">
<Label small>Query Name</Label>
<Input thin outline bind:value={query.name} />
<Label>Query Name</Label>
<Input bind:value={query.name} />
</div>
<Spacer extraLarge />
<Spacer medium />
{#if queryConfig}
<div class="config-field">
<Label small>Function</Label>
<Select primary outline thin bind:value={query.queryVerb}>
{#each Object.keys(queryConfig) as queryVerb}
<option value={queryVerb}>
{queryConfig[queryVerb]?.displayName || queryVerb}
</option>
{/each}
</Select>
<Label>Function</Label>
<Select
bind:value={query.queryVerb}
options={Object.keys(queryConfig)}
getOptionLabel={verb => queryConfig[verb]?.displayName || capitalise(verb)} />
</div>
<Spacer extraLarge />
<hr />
<Divider />
<Spacer extraLarge />
<Spacer small />
<ParameterBuilder bind:parameters={query.parameters} bindable={false} />
<hr />
<Divider />
{/if}
</section>
{#if shouldShowQueryConfig}
<section>
<Spacer extraLarge />
<Spacer small />
<div class="config">
<Heading small lh>Fields</Heading>
<Heading>Fields</Heading>
<Body small grey>Fill in the fields specific to this query.</Body>
<Spacer medium />
<Spacer extraLarge />
<IntegrationQueryEditor
{datasource}
{query}
height={300}
schema={queryConfig[query.queryVerb]}
bind:parameters />
<Spacer extraLarge />
<hr />
<Divider />
<Spacer extraLarge />
<Spacer medium />
<div class="viewer-controls">
<Heading small lh>Results</Heading>
<Heading>Results</Heading>
<div class="button-container">
<Button
secondary
@ -182,17 +181,14 @@
Save Query
</Button>
<Spacer medium />
<Button thin primary on:click={previewQuery}>Run Query</Button>
<Button thin secondary on:click={previewQuery}>Run Query</Button>
</div>
</div>
<Body small grey>
Below, you can preview the results from your query and change the
schema.
</Body>
<Spacer extraLarge />
<Spacer medium />
<section class="viewer">
{#if data}
<Switcher headings={PREVIEW_HEADINGS} bind:value={tab}>
@ -201,9 +197,7 @@
class="preview">
<!-- prettier-ignore -->
{#if !data[0]}
Please run your query to fetch some data.
{:else}
{JSON.stringify(data[0], undefined, 2)}
{/if}
@ -214,24 +208,14 @@
{#each fields as field, idx}
<Spacer small />
<div class="field">
<Input
outline
placeholder="Field Name"
type={'text'}
bind:value={field.name} />
<Select thin border bind:value={field.type}>
<option value={''}>Select a field type</option>
<option value={'STRING'}>Text</option>
<option value={'NUMBER'}>Number</option>
<option value={'BOOLEAN'}>Boolean</option>
<option value={'DATETIME'}>Datetime</option>
</Select>
<Input placeholder="Field Name" bind:value={field.name} />
<Select bind:value={field.type} options={typeOptions} />
<i
class="ri-close-circle-line delete"
on:click={() => deleteField(idx)} />
</div>
{/each}
<Spacer small />
<Spacer extraLarge />
<Button thin secondary on:click={newField}>Add Field</Button>
{/if}
</Switcher>
@ -241,7 +225,6 @@
</section>
{/if}
<Spacer extraLarge />
<Spacer extraLarge />
<style>
.config-field {
@ -261,11 +244,6 @@
display: flex;
}
hr {
margin-top: var(--layout-m);
border: 1px solid var(--grey-2);
}
.config {
margin-bottom: var(--spacing-s);
}
@ -285,10 +263,10 @@
overflow-y: auto;
overflow-wrap: break-word;
white-space: pre-wrap;
background-color: var(--grey-1);
background-color: var(--grey-2);
padding: var(--spacing-m);
border-radius: 8px;
color: var(--grey-6);
color: var(--ink);
}
.viewer-controls {

View File

@ -33,14 +33,6 @@
</section>
<style>
section {
overflow: scroll;
}
::-webkit-scrollbar {
width: 0px;
background: transparent; /* make scrollbar transparent */
}
.inner {
width: 640px;
margin: 0 auto;

View File

@ -1,10 +1,11 @@
<script>
import { goto, beforeUrlChange } from "@roxi/routify"
import { Button, Heading, Body, Spacer } from "@budibase/bbui"
import { Button, Heading, Body, Spacer, Divider } from "@budibase/bbui"
import { datasources, integrations, queries } from "stores/backend"
import { notifications } from "@budibase/bbui"
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
import ICONS from "components/backend/DatasourceNavigator/icons"
import { capitalise } from "../../../../../../helpers"
let unsaved = false
@ -19,11 +20,8 @@
}
function onClickQuery(query) {
if ($queries.selected === query._id) {
return
}
queries.select(query)
$goto(`../${query._id}`)
$goto(`./${query._id}`)
}
function setUnsaved() {
@ -45,50 +43,42 @@
<section>
<Spacer extraLarge />
<header>
<div class="datasource-icon">
<svelte:component
this={ICONS[datasource.source]}
height="26"
width="26" />
</div>
<h3 class="section-title">{datasource.name}</h3>
<svelte:component
this={ICONS[datasource.source]}
height="26"
width="26" />
<Heading l>{datasource.name}</Heading>
</header>
<Body small grey lh>{integration.description}</Body>
<Spacer extraLarge />
<hr />
<Spacer large />
<Divider />
<Spacer extraLarge />
<div class="container">
<div class="config-header">
<Heading small>Configuration</Heading>
<Heading>Configuration</Heading>
<Button secondary on:click={saveDatasource}>Save</Button>
</div>
<Body small grey>
Connect your database to Budibase using the config below.
</Body>
<Spacer extraLarge />
<IntegrationConfigForm
schema={integration.datasource}
integration={datasource.config}
on:change={setUnsaved} />
<Spacer extraLarge />
<hr />
<Spacer large />
<Divider />
<Spacer extraLarge />
<div class="query-header">
<Heading small>Queries</Heading>
<Button secondary on:click={() => $goto('../new')}>Add Query</Button>
<Heading>Queries</Heading>
<Button secondary on:click={() => $goto('./new')}>Add Query</Button>
</div>
<Spacer extraLarge />
<div class="query-list">
{#each $queries.list.filter(query => query.datasourceId === datasource._id) as query}
<div class="query-list-item" on:click={() => onClickQuery(query)}>
<p class="query-name">{query.name}</p>
<p>{query.queryVerb}</p>
<p>{capitalise(query.queryVerb)}</p>
<p></p>
</div>
{/each}
@ -108,18 +98,11 @@
width: 640px;
}
hr {
border: 1px solid var(--grey-2);
}
header {
margin: 0 0 var(--spacing-xs) 0;
display: flex;
gap: var(--spacing-m);
}
.section-title {
text-transform: capitalize;
gap: var(--spacing-l);
align-items: center;
}
.config-header {
@ -150,7 +133,7 @@
.query-list-item {
border-radius: var(--border-radius-m);
background: var(--background);
border: var(--border-grey);
border: var(--border-dark);
display: grid;
grid-template-columns: 2fr 0.75fr 20px;
align-items: center;