Update entire builder backend UI to work with new spectrum components and fix multiple issues
This commit is contained in:
parent
a49d54fb1a
commit
9482112d6b
|
@ -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" />
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
placeholder={placeholder || ''}
|
||||
on:blur={onBlur}
|
||||
on:focus={onFocus}
|
||||
on:input
|
||||
{type}
|
||||
class="spectrum-Textfield-input" />
|
||||
</div>
|
||||
|
|
|
@ -28,5 +28,6 @@
|
|||
{placeholder}
|
||||
{type}
|
||||
on:change={onChange}
|
||||
on:click />
|
||||
on:click
|
||||
on:input />
|
||||
</Field>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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]} />
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -33,14 +33,6 @@
|
|||
</section>
|
||||
|
||||
<style>
|
||||
section {
|
||||
overflow: scroll;
|
||||
}
|
||||
::-webkit-scrollbar {
|
||||
width: 0px;
|
||||
background: transparent; /* make scrollbar transparent */
|
||||
}
|
||||
|
||||
.inner {
|
||||
width: 640px;
|
||||
margin: 0 auto;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue