Disabling save button when no changes made.
This commit is contained in:
parent
655c6034c2
commit
9aba344a45
|
@ -11,7 +11,7 @@
|
|||
import { capitalise } from "helpers"
|
||||
import { IntegrationTypes } from "constants"
|
||||
|
||||
export let integration
|
||||
export let datasource
|
||||
export let schema
|
||||
export let creating
|
||||
|
||||
|
@ -20,13 +20,13 @@
|
|||
return false
|
||||
}
|
||||
return !(
|
||||
(integration.source === IntegrationTypes.REST &&
|
||||
(datasource.source === IntegrationTypes.REST &&
|
||||
key === "defaultHeaders") ||
|
||||
value.deprecated
|
||||
)
|
||||
}
|
||||
|
||||
$: config = integration.config
|
||||
$: config = datasource?.config
|
||||
$: configKeys = Object.entries(schema || {})
|
||||
.filter(el => filter(el))
|
||||
.map(([key]) => key)
|
||||
|
@ -39,7 +39,7 @@
|
|||
{#if !creating}
|
||||
<div class="form-row">
|
||||
<Label>{capitalise("Name")}</Label>
|
||||
<Input on:change bind:value={integration.name} />
|
||||
<Input on:change bind:value={datasource.name} />
|
||||
</div>
|
||||
{/if}
|
||||
{#each configKeys as configKey}
|
||||
|
@ -54,6 +54,7 @@
|
|||
bind:this={addButton}
|
||||
defaults={schema[configKey].default}
|
||||
bind:object={config[configKey]}
|
||||
on:change
|
||||
noAddButton={true}
|
||||
/>
|
||||
{:else if schema[configKey].type === "boolean"}
|
||||
|
|
|
@ -121,7 +121,6 @@
|
|||
<div>
|
||||
<ActionButton
|
||||
size="S"
|
||||
quiet
|
||||
icon="DataRefresh"
|
||||
on:click={updateDatasourceSchema}
|
||||
>
|
||||
|
@ -161,9 +160,7 @@
|
|||
<Heading size="S">Relationships</Heading>
|
||||
<ActionButton
|
||||
icon="DataCorrelated"
|
||||
primary
|
||||
size="S"
|
||||
quiet
|
||||
on:click={openRelationshipModal}
|
||||
>
|
||||
Define existing relationship
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import { Divider, Heading, Button } from "@budibase/bbui"
|
||||
import { Divider, Heading, ActionButton, Badge } from "@budibase/bbui"
|
||||
import KeyValueBuilder from "components/integration/KeyValueBuilder.svelte"
|
||||
|
||||
export let datasource
|
||||
|
@ -9,13 +9,19 @@
|
|||
|
||||
<Divider />
|
||||
<div class="query-header">
|
||||
<Heading size="S">Headers</Heading>
|
||||
<Button secondary on:click={() => addHeader.addEntry()}>Add Header</Button>
|
||||
<div class="badge">
|
||||
<Heading size="S">Headers</Heading>
|
||||
<Badge quiet grey>Optional</Badge>
|
||||
</div>
|
||||
<ActionButton size="S" icon="Add" on:click={() => addHeader.addEntry()}
|
||||
>Add Header</ActionButton
|
||||
>
|
||||
</div>
|
||||
<KeyValueBuilder
|
||||
bind:this={addHeader}
|
||||
bind:object={datasource.config.defaultHeaders}
|
||||
noAddButton={true}
|
||||
on:change
|
||||
noAddButton
|
||||
/>
|
||||
|
||||
<style>
|
||||
|
@ -26,4 +32,9 @@
|
|||
align-items: center;
|
||||
margin: 0 0 var(--spacing-s) 0;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: flex;
|
||||
gap: var(--spacing-m);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
export let modal
|
||||
|
||||
// kill the reference so the input isn't saved
|
||||
let config = cloneDeep(integration)
|
||||
let datasource = cloneDeep(integration)
|
||||
|
||||
async function saveDatasource() {
|
||||
try {
|
||||
const resp = await save(config)
|
||||
const resp = await save(datasource)
|
||||
$goto(`./datasource/${resp._id}`)
|
||||
notifications.success(`Datasource updated successfully.`)
|
||||
} catch (err) {
|
||||
|
@ -24,10 +24,10 @@
|
|||
</script>
|
||||
|
||||
<ModalContent
|
||||
title={`Connect to ${IntegrationNames[config.type]}`}
|
||||
title={`Connect to ${IntegrationNames[datasource.type]}`}
|
||||
onConfirm={() => saveDatasource()}
|
||||
onCancel={() => modal.show()}
|
||||
confirmText={config.plus
|
||||
confirmText={datasource.plus
|
||||
? "Fetch tables from database"
|
||||
: "Save and continue to query"}
|
||||
cancelText="Back"
|
||||
|
@ -40,8 +40,8 @@
|
|||
</Layout>
|
||||
|
||||
<IntegrationConfigForm
|
||||
schema={config.schema}
|
||||
integration={config}
|
||||
schema={datasource.schema}
|
||||
bind:datasource
|
||||
creating={true}
|
||||
/>
|
||||
</ModalContent>
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<script>
|
||||
import { Icon, Button, Input } from "@budibase/bbui"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
|
||||
let dispatch = createEventDispatcher()
|
||||
|
||||
export let defaults
|
||||
export let object = defaults || {}
|
||||
|
@ -15,19 +18,25 @@
|
|||
|
||||
export function addEntry() {
|
||||
fields = [...fields, {}]
|
||||
changed()
|
||||
}
|
||||
|
||||
function deleteEntry(idx) {
|
||||
fields.splice(idx, 1)
|
||||
changed()
|
||||
}
|
||||
|
||||
function changed() {
|
||||
fields = fields
|
||||
dispatch("change", fields)
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- 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" bind:value={field.name} />
|
||||
<Input placeholder="Value" bind:value={field.value} />
|
||||
<Input placeholder="Key" bind:value={field.name} on:change={changed} />
|
||||
<Input placeholder="Value" bind:value={field.value} on:change={changed} />
|
||||
{#if !readOnly}
|
||||
<Icon hoverable name="Close" on:click={() => deleteEntry(idx)} />
|
||||
{/if}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
Divider,
|
||||
Layout,
|
||||
notifications,
|
||||
ActionButton,
|
||||
} from "@budibase/bbui"
|
||||
import { datasources, integrations, queries, tables } from "stores/backend"
|
||||
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
|
||||
|
@ -15,9 +16,28 @@
|
|||
import ICONS from "components/backend/DatasourceNavigator/icons"
|
||||
import { IntegrationTypes } from "constants"
|
||||
import { capitalise } from "helpers"
|
||||
import { isEqual } from "lodash"
|
||||
import { cloneDeep } from "lodash/fp"
|
||||
|
||||
let baseDatasource, changed
|
||||
|
||||
$: datasource = $datasources.list.find(ds => ds._id === $datasources.selected)
|
||||
$: integration = datasource && $integrations[datasource.source]
|
||||
$: {
|
||||
if (
|
||||
datasource &&
|
||||
(!baseDatasource || baseDatasource.source !== datasource.source)
|
||||
) {
|
||||
baseDatasource = cloneDeep(datasource)
|
||||
}
|
||||
}
|
||||
$: hasChanged(baseDatasource, datasource)
|
||||
|
||||
function hasChanged(base, ds) {
|
||||
if (base) {
|
||||
changed = !isEqual(base, ds)
|
||||
}
|
||||
}
|
||||
|
||||
async function saveDatasource() {
|
||||
try {
|
||||
|
@ -28,6 +48,7 @@
|
|||
}
|
||||
await datasources.fetch()
|
||||
notifications.success(`Datasource ${name} updated successfully.`)
|
||||
baseDatasource = cloneDeep(datasource)
|
||||
} catch (err) {
|
||||
notifications.error(`Error saving datasource: ${err}`)
|
||||
}
|
||||
|
@ -49,7 +70,7 @@
|
|||
height="26"
|
||||
width="26"
|
||||
/>
|
||||
<Heading size="M">{datasource.name}</Heading>
|
||||
<Heading size="M">{baseDatasource.name}</Heading>
|
||||
</header>
|
||||
<Body size="M">{integration.description}</Body>
|
||||
</Layout>
|
||||
|
@ -57,14 +78,16 @@
|
|||
<div class="container">
|
||||
<div class="config-header">
|
||||
<Heading size="S">Configuration</Heading>
|
||||
<Button secondary on:click={saveDatasource}>Save</Button>
|
||||
<Button disabled={!changed} cta on:click={saveDatasource}>Save</Button
|
||||
>
|
||||
</div>
|
||||
<Body size="S">
|
||||
Connect your data source to Budibase using the config below.
|
||||
</Body>
|
||||
<IntegrationConfigForm
|
||||
on:change={hasChanged}
|
||||
schema={integration.datasource}
|
||||
integration={datasource}
|
||||
bind:datasource
|
||||
/>
|
||||
</div>
|
||||
{#if datasource.plus}
|
||||
|
@ -73,7 +96,9 @@
|
|||
<Divider />
|
||||
<div class="query-header">
|
||||
<Heading size="S">Queries</Heading>
|
||||
<Button secondary on:click={() => $goto("./new")}>Add Query</Button>
|
||||
<ActionButton size="S" icon="Add" on:click={() => $goto("./new")}
|
||||
>Add Query
|
||||
</ActionButton>
|
||||
</div>
|
||||
<div class="query-list">
|
||||
{#each $queries.list.filter(query => query.datasourceId === datasource._id) as query}
|
||||
|
@ -85,7 +110,7 @@
|
|||
{/each}
|
||||
</div>
|
||||
{#if datasource?.source === IntegrationTypes.REST}
|
||||
<RestExtraConfigForm bind:datasource />
|
||||
<RestExtraConfigForm bind:datasource on:change={hasChanged} />
|
||||
{/if}
|
||||
</Layout>
|
||||
</section>
|
||||
|
|
|
@ -153,7 +153,12 @@ module RestModule {
|
|||
}
|
||||
|
||||
getUrl(path: string, queryString: string): string {
|
||||
return `${this.config.url}/${path}?${queryString}`
|
||||
const main = `${path}?${queryString}`
|
||||
if (!this.config.url) {
|
||||
return main
|
||||
} else {
|
||||
return `${this.config.url}/${main}`
|
||||
}
|
||||
}
|
||||
|
||||
async create({ path = "", queryString = "", headers = {}, json = {} }) {
|
||||
|
|
Loading…
Reference in New Issue