more design updates

This commit is contained in:
Martin McKeaveney 2021-02-18 18:55:08 +00:00
parent d99e1a5a53
commit 68f28bb912
8 changed files with 85 additions and 46 deletions

View File

@ -7,18 +7,19 @@
<form> <form>
{#each Object.keys(integration) as configKey} {#each Object.keys(integration) as configKey}
<div class="form-row"> {#if typeof integration[configKey] === 'object'}
{#if typeof integration[configKey] === 'object'} <Label small>{configKey}</Label>
<Label small>{configKey}</Label> <Spacer small />
<KeyValueBuilder bind:object={integration[configKey]} /> <KeyValueBuilder bind:object={integration[configKey]} />
{:else} {:else}
<div class="form-row">
<Label small>{configKey}</Label> <Label small>{configKey}</Label>
<Input <Input
outline outline
type={integration[configKey].type} type={integration[configKey].type}
bind:value={integration[configKey]} /> bind:value={integration[configKey]} />
{/if} </div>
</div> {/if}
{/each} {/each}
</form> </form>

View File

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

View File

@ -29,7 +29,7 @@
{#each schemaKeys as field} {#each schemaKeys as field}
{#if schema.fields[field]?.type === 'object'} {#if schema.fields[field]?.type === 'object'}
<div> <div>
<Label extraSmall grey>{field}</Label> <Label small>{field}</Label>
<KeyValueBuilder bind:object={fields[field]} /> <KeyValueBuilder bind:object={fields[field]} />
</div> </div>
{:else if schema.fields[field]?.type === 'json'} {:else if schema.fields[field]?.type === 'json'}
@ -45,7 +45,7 @@
<div class="horizontal"> <div class="horizontal">
<Label small>{field}</Label> <Label small>{field}</Label>
<Input <Input
placeholder="Enter {field} name" placeholder="Enter {field}"
outline outline
disabled={!editable} disabled={!editable}
type={schema.fields[field]?.type} type={schema.fields[field]?.type}

View File

@ -77,6 +77,7 @@
.controls { .controls {
display: flex; display: flex;
align-items: center;
justify-content: space-between; justify-content: space-between;
} }

View File

@ -64,7 +64,7 @@
$: integrationInfo = $backendUiStore.integrations[datasourceType] $: integrationInfo = $backendUiStore.integrations[datasourceType]
$: queryConfig = integrationInfo?.query $: queryConfig = integrationInfo?.query
$: shouldShowQueryConfig = config && query.queryVerb $: shouldShowQueryConfig = queryConfig && query.queryVerb
function newField() { function newField() {
fields = [...fields, {}] fields = [...fields, {}]
@ -134,14 +134,13 @@
<section class="config"> <section class="config">
<Heading medium>Query {integrationInfo.friendlyName}</Heading> <Heading medium>Query {integrationInfo.friendlyName}</Heading>
<hr /> <hr />
<Spacer medium />
<Heading small>Config</Heading> <Heading small>Config</Heading>
<Spacer medium /> <Spacer medium />
<Body small grey>Provide a name for your query and select its function.</Body> <Body small grey>Provide a name for your query and select its function.</Body>
<Spacer medium /> <Spacer medium />
<div class="config-field"> <div class="config-field">
<Label small>Query Name</Label> <Label small>Query Name</Label>
<Input thin bind:value={query.name} /> <Input thin outline bind:value={query.name} />
</div> </div>
<Spacer medium /> <Spacer medium />
{#if queryConfig} {#if queryConfig}
@ -153,7 +152,6 @@
{/each} {/each}
</Select> </Select>
</div> </div>
<Spacer medium />
<hr /> <hr />
<ParameterBuilder bind:parameters={query.parameters} bindable={false} /> <ParameterBuilder bind:parameters={query.parameters} bindable={false} />
<hr /> <hr />
@ -189,29 +187,33 @@
<Heading small>Fields</Heading> <Heading small>Fields</Heading>
<Spacer medium /> <Spacer medium />
<IntegrationQueryEditor <IntegrationQueryEditor
{datasource}
{query} {query}
schema={config[query.queryVerb]} schema={queryConfig[query.queryVerb]}
bind:parameters /> bind:parameters />
<Spacer medium />
<hr /> <hr />
<Spacer medium />
<div class="viewer-controls"> <div class="viewer-controls">
<Heading small>Query Results</Heading> <Heading small>Query Results</Heading>
<Button <div>
secondary <Button
thin secondary
disabled={data.length === 0 || !query.name} thin
on:click={saveQuery}> disabled={data.length === 0 || !query.name}
Save Query on:click={saveQuery}>
</Button> Save Query
</Button>
<Button thin primary on:click={previewQuery}>Run Query</Button> <Button thin primary on:click={previewQuery}>Run Query</Button>
</div>
</div> </div>
<Body small grey> <Body small grey>
Below, you can preview the results from your query and change the Below, you can preview the results from your query and change the
schema. schema.
</Body> </Body>
<Spacer medium />
<section class="viewer"> <section class="viewer">
{#if data} {#if data}
<Switcher headings={PREVIEW_HEADINGS} bind:value={tab}> <Switcher headings={PREVIEW_HEADINGS} bind:value={tab}>
@ -276,6 +278,11 @@
font-size: var(--font-size-s); font-size: var(--font-size-s);
} }
hr {
margin-top: var(--layout-m);
margin-bottom: var(--layout-m);
}
.config { .config {
margin-bottom: var(--spacing-s); margin-bottom: var(--spacing-s);
} }
@ -285,10 +292,6 @@
cursor: pointer; cursor: pointer;
} }
.query-type-span {
text-transform: uppercase;
}
.preview { .preview {
width: 800px; width: 800px;
height: 100%; height: 100%;
@ -300,15 +303,8 @@
.viewer-controls { .viewer-controls {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
/* margin-left: auto; */ justify-content: space-between;
/* direction: rtl; */
/* z-index: 5; */
gap: var(--spacing-m); gap: var(--spacing-m);
min-width: 150px; min-width: 150px;
} }
.viewer {
/* margin-top: -28px; */
/* z-index: -2; */
}
</style> </style>

View File

@ -8,13 +8,16 @@
const QueryTypes = { const QueryTypes = {
SQL: "sql", SQL: "sql",
JSON: "json", JSON: "json",
FIELDS: "fields", FIELDS: "fields"
} }
export let query export let query
export let datasource
export let schema export let schema
export let editable = true export let editable = true
$: urlDisplay = schema.urlDisplay && `${datasource.config.url}${query.fields.path}${query.fields.queryString}`
function updateQuery({ detail }) { function updateQuery({ detail }) {
query.fields[schema.type] = detail.value query.fields[schema.type] = detail.value
} }
@ -40,6 +43,27 @@
parameters={query.parameters} /> parameters={query.parameters} />
{:else if schema.type === QueryTypes.FIELDS} {:else if schema.type === QueryTypes.FIELDS}
<FieldsBuilder bind:fields={query.fields} {schema} {editable} /> <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}
{/if} {/if}
{/key} {/key}
{/if} {/if}
<style>
.url-row {
display: grid;
grid-template-columns: 20% 1fr;
grid-gap: var(--spacing-l);
align-items: center;
}
pre {
background: var(--background);
border-radius: var(--border-radius-s);
margin: 0;
}
</style>

View File

@ -50,6 +50,7 @@
<Spacer medium /> <Spacer medium />
<IntegrationConfigForm integration={datasource.config} /> <IntegrationConfigForm integration={datasource.config} />
<Spacer medium />
<hr /> <hr />

View File

@ -20,10 +20,14 @@ const SCHEMA = {
create: { create: {
displayName: "POST", displayName: "POST",
type: QUERY_TYPES.FIELDS, type: QUERY_TYPES.FIELDS,
urlDisplay: true,
fields: { fields: {
path: { path: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
}, },
queryString: {
type: FIELD_TYPES.STRING,
},
headers: { headers: {
type: FIELD_TYPES.OBJECT, type: FIELD_TYPES.OBJECT,
}, },
@ -35,10 +39,14 @@ const SCHEMA = {
read: { read: {
displayName: "GET", displayName: "GET",
type: QUERY_TYPES.FIELDS, type: QUERY_TYPES.FIELDS,
urlDisplay: true,
fields: { fields: {
path: { path: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
}, },
queryString: {
type: FIELD_TYPES.STRING,
},
headers: { headers: {
type: FIELD_TYPES.OBJECT, type: FIELD_TYPES.OBJECT,
}, },
@ -47,10 +55,14 @@ const SCHEMA = {
update: { update: {
displayName: "PUT", displayName: "PUT",
type: QUERY_TYPES.FIELDS, type: QUERY_TYPES.FIELDS,
urlDisplay: true,
fields: { fields: {
path: { path: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
}, },
queryString: {
type: FIELD_TYPES.STRING,
},
headers: { headers: {
type: FIELD_TYPES.OBJECT, type: FIELD_TYPES.OBJECT,
}, },
@ -62,10 +74,14 @@ const SCHEMA = {
delete: { delete: {
displayName: "DELETE", displayName: "DELETE",
type: QUERY_TYPES.FIELDS, type: QUERY_TYPES.FIELDS,
urlDisplay: true,
fields: { fields: {
path: { path: {
type: FIELD_TYPES.STRING, type: FIELD_TYPES.STRING,
}, },
queryString: {
type: FIELD_TYPES.STRING,
},
headers: { headers: {
type: FIELD_TYPES.OBJECT, type: FIELD_TYPES.OBJECT,
}, },
@ -82,8 +98,8 @@ class RestIntegration {
this.config = config this.config = config
} }
async create({ path, headers = {}, json }) { async create({ path, queryString, headers = {}, json }) {
const response = await fetch(this.config.url + path, { const response = await fetch(this.config.url + path + queryString, {
method: "POST", method: "POST",
headers: { headers: {
...this.config.defaultHeaders, ...this.config.defaultHeaders,
@ -95,8 +111,8 @@ class RestIntegration {
return await response.json() return await response.json()
} }
async read({ path, headers = {} }) { async read({ path, queryString, headers = {} }) {
const response = await fetch(this.config.url + path, { const response = await fetch(this.config.url + path + queryString, {
headers: { headers: {
...this.config.defaultHeaders, ...this.config.defaultHeaders,
...headers, ...headers,
@ -106,8 +122,8 @@ class RestIntegration {
return await response.json() return await response.json()
} }
async update({ path, headers = {}, json }) { async update({ path, queryString, headers = {}, json }) {
const response = await fetch(this.config.url + path, { const response = await fetch(this.config.url + path + queryString, {
method: "POST", method: "POST",
headers: { headers: {
...this.config.defaultHeaders, ...this.config.defaultHeaders,
@ -119,8 +135,8 @@ class RestIntegration {
return await response.json() return await response.json()
} }
async delete({ path, headers = {} }) { async delete({ path, queryString, headers = {} }) {
const response = await fetch(this.config.url + path, { const response = await fetch(this.config.url + path + queryString, {
method: "DELETE", method: "DELETE",
headers: { headers: {
...this.config.defaultHeaders, ...this.config.defaultHeaders,