Updating external table UI a bit, adding the concept of defining an existing relationship, updating the data sources UI to make it a bit less cluttered and make the creation of tables more obvious.

This commit is contained in:
mike12345567 2021-11-01 21:15:46 +00:00
parent 1d48ffc38a
commit 3e82abd88e
6 changed files with 114 additions and 10 deletions

View File

@ -4,6 +4,7 @@
import CreateRowButton from "./buttons/CreateRowButton.svelte" import CreateRowButton from "./buttons/CreateRowButton.svelte"
import CreateColumnButton from "./buttons/CreateColumnButton.svelte" import CreateColumnButton from "./buttons/CreateColumnButton.svelte"
import CreateViewButton from "./buttons/CreateViewButton.svelte" import CreateViewButton from "./buttons/CreateViewButton.svelte"
import ExistingRelationshipButton from "./buttons/ExistingRelationshipButton.svelte"
import ExportButton from "./buttons/ExportButton.svelte" import ExportButton from "./buttons/ExportButton.svelte"
import EditRolesButton from "./buttons/EditRolesButton.svelte" import EditRolesButton from "./buttons/EditRolesButton.svelte"
import ManageAccessButton from "./buttons/ManageAccessButton.svelte" import ManageAccessButton from "./buttons/ManageAccessButton.svelte"
@ -114,6 +115,12 @@
{#if isUsersTable} {#if isUsersTable}
<EditRolesButton /> <EditRolesButton />
{/if} {/if}
{#if !isInternal}
<ExistingRelationshipButton
table={$tables.selected}
on:updatecolumns={onUpdateColumns}
/>
{/if}
<HideAutocolumnButton bind:hideAutocolumns /> <HideAutocolumnButton bind:hideAutocolumns />
<!-- always have the export last --> <!-- always have the export last -->
<ExportButton view={$tables.selected?._id} /> <ExportButton view={$tables.selected?._id} />

View File

@ -0,0 +1,54 @@
<script>
import { ActionButton, Modal, notifications } from "@budibase/bbui"
import CreateEditRelationship from "../../Datasources/CreateEditRelationship.svelte"
import { datasources, tables } from "../../../../stores/backend"
import { createEventDispatcher } from "svelte"
export let table
const dispatch = createEventDispatcher()
$: plusTables = datasource?.plus
? Object.values(datasource?.entities || {})
: []
$: datasource = $datasources.list.find(
source => source._id === table?.sourceId
)
let modal
async function saveRelationship() {
try {
// Create datasource
await datasources.save(datasource)
notifications.success(`Relationship information saved.`)
const tableList = await tables.fetch()
await tables.select(tableList.find(tbl => tbl._id === table._id))
dispatch("updatecolumns")
} catch (err) {
notifications.error(`Error saving relationship info: ${err}`)
}
}
</script>
{#if table.sourceId}
<div>
<ActionButton
icon="DataCorrelated"
primary
size="S"
quiet
on:click={modal.show}
>
Define existing relationship
</ActionButton>
</div>
<Modal bind:this={modal}>
<CreateEditRelationship
{datasource}
save={saveRelationship}
close={modal.hide}
{plusTables}
selectedFromTable={table}
/>
</Modal>
{/if}

View File

@ -18,10 +18,19 @@
export let fromRelationship = {} export let fromRelationship = {}
export let toRelationship = {} export let toRelationship = {}
export let close export let close
export let selectedFromTable
let originalFromName = fromRelationship.name, let originalFromName = fromRelationship.name,
originalToName = toRelationship.name originalToName = toRelationship.name
if (fromRelationship && !fromRelationship.relationshipType) {
fromRelationship.relationshipType = RelationshipTypes.MANY_TO_ONE
}
if (toRelationship && selectedFromTable) {
toRelationship.tableId = selectedFromTable._id
}
function inSchema(table, prop, ogName) { function inSchema(table, prop, ogName) {
if (!table || !prop || prop === ogName) { if (!table || !prop || prop === ogName) {
return false return false
@ -114,6 +123,7 @@
}, },
] ]
$: updateRelationshipType(fromRelationship?.relationshipType) $: updateRelationshipType(fromRelationship?.relationshipType)
$: tableChanged(fromTable, toTable)
function updateRelationshipType(fromType) { function updateRelationshipType(fromType) {
if (fromType === RelationshipTypes.MANY_TO_MANY) { if (fromType === RelationshipTypes.MANY_TO_MANY) {
@ -205,7 +215,6 @@
originalToName = toRelationship.name originalToName = toRelationship.name
originalFromName = fromRelationship.name originalFromName = fromRelationship.name
await save() await save()
await tables.fetch()
} }
async function deleteRelationship() { async function deleteRelationship() {
@ -215,10 +224,26 @@
await tables.fetch() await tables.fetch()
close() close()
} }
function tableChanged(fromTbl, toTbl) {
fromRelationship.name = toTbl?.name || ""
errors.fromCol = ""
toRelationship.name = fromTbl?.name || ""
errors.toCol = ""
if (toTbl || fromTbl) {
checkForErrors(
fromTable,
toTable,
through,
fromRelationship,
toRelationship
)
}
}
</script> </script>
<ModalContent <ModalContent
title="Create Relationship" title="Define Relationship"
confirmText="Save" confirmText="Save"
onConfirm={saveRelationship} onConfirm={saveRelationship}
disabled={!valid} disabled={!valid}
@ -234,6 +259,7 @@
<Select <Select
label="Select from table" label="Select from table"
options={tableOptions} options={tableOptions}
disabled={!!selectedFromTable}
on:change={() => ($touched.from = true)} on:change={() => ($touched.from = true)}
bind:error={errors.from} bind:error={errors.from}
bind:value={toRelationship.tableId} bind:value={toRelationship.tableId}

View File

@ -8,11 +8,12 @@
Layout, Layout,
Modal, Modal,
InlineAlert, InlineAlert,
ActionButton,
} from "@budibase/bbui" } from "@budibase/bbui"
import { datasources, integrations, queries, tables } from "stores/backend" import { datasources, integrations, queries, tables } from "stores/backend"
import { notifications } from "@budibase/bbui" import { notifications } from "@budibase/bbui"
import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte" import IntegrationConfigForm from "components/backend/DatasourceNavigator/TableIntegrationMenu/IntegrationConfigForm.svelte"
import CreateEditRelationship from "./CreateEditRelationship/CreateEditRelationship.svelte" import CreateEditRelationship from "components/backend/Datasources/CreateEditRelationship.svelte"
import CreateExternalTableModal from "./modals/CreateExternalTableModal.svelte" import CreateExternalTableModal from "./modals/CreateExternalTableModal.svelte"
import DisplayColumnModal from "./modals/EditDisplayColumnsModal.svelte" import DisplayColumnModal from "./modals/EditDisplayColumnsModal.svelte"
import ICONS from "components/backend/DatasourceNavigator/icons" import ICONS from "components/backend/DatasourceNavigator/icons"
@ -174,14 +175,24 @@
<Heading size="S">Tables</Heading> <Heading size="S">Tables</Heading>
<div class="table-buttons"> <div class="table-buttons">
{#if plusTables && plusTables.length !== 0} {#if plusTables && plusTables.length !== 0}
<Button primary on:click={openDisplayColumnModal}> <ActionButton
size="S"
quiet
icon="ColumnSettings"
on:click={openDisplayColumnModal}
>
Update display columns Update display columns
</Button> </ActionButton>
{/if} {/if}
<div> <div>
<Button primary on:click={updateDatasourceSchema}> <ActionButton
size="S"
quiet
icon="DataRefresh"
on:click={updateDatasourceSchema}
>
Fetch tables from database Fetch tables from database
</Button> </ActionButton>
</div> </div>
</div> </div>
</div> </div>
@ -214,9 +225,15 @@
<Divider /> <Divider />
<div class="query-header"> <div class="query-header">
<Heading size="S">Relationships</Heading> <Heading size="S">Relationships</Heading>
<Button primary on:click={() => openRelationshipModal()} <ActionButton
>Create relationship</Button icon="DataCorrelated"
primary
size="S"
quiet
on:click={openRelationshipModal}
> >
Define existing relationship
</ActionButton>
</div> </div>
<Body> <Body>
Tell budibase how your tables are related to get even more smart Tell budibase how your tables are related to get even more smart
@ -331,7 +348,6 @@
.table-buttons { .table-buttons {
display: grid; display: grid;
grid-gap: var(--spacing-l);
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
} }

View File

@ -11,6 +11,7 @@ export function createTablesStore() {
const tablesResponse = await api.get(`/api/tables`) const tablesResponse = await api.get(`/api/tables`)
const tables = await tablesResponse.json() const tables = await tablesResponse.json()
update(state => ({ ...state, list: tables })) update(state => ({ ...state, list: tables }))
return tables
} }
async function select(table) { async function select(table) {