1
0
Fork 0
mirror of synced 2024-09-10 06:26:02 +12:00

use Relationship selector for external datasource relationships

This commit is contained in:
Peter Clement 2023-09-28 16:02:37 +01:00
parent 7e6faaf587
commit ac2c63f9ed
2 changed files with 76 additions and 53 deletions

View file

@ -13,6 +13,8 @@
import { Helpers } from "@budibase/bbui" import { Helpers } from "@budibase/bbui"
import { RelationshipErrorChecker } from "./relationshipErrors" import { RelationshipErrorChecker } from "./relationshipErrors"
import { onMount } from "svelte" import { onMount } from "svelte"
import RelationshipSelector from "components/common/RelationshipSelector.svelte"
import { PrettyRelationshipDefinitions } from "constants/backend"
export let save export let save
export let datasource export let datasource
@ -22,16 +24,18 @@
export let selectedFromTable export let selectedFromTable
export let close export let close
const relationshipTypes = [ let relationshipMap = {
{ [RelationshipType.MANY_TO_MANY]: {
label: "One to Many", part1: PrettyRelationshipDefinitions.MANY,
value: RelationshipType.MANY_TO_ONE, part2: PrettyRelationshipDefinitions.MANY,
}, },
{ [RelationshipType.MANY_TO_ONE]: {
label: "Many to Many", part1: PrettyRelationshipDefinitions.ONE,
value: RelationshipType.MANY_TO_MANY, part2: PrettyRelationshipDefinitions.MANY,
}, },
] }
let relationshipOpts1 = Object.values(PrettyRelationshipDefinitions)
let relationshipOpts2 = Object.values(PrettyRelationshipDefinitions)
let originalFromColumnName = toRelationship.name, let originalFromColumnName = toRelationship.name,
originalToColumnName = fromRelationship.name originalToColumnName = fromRelationship.name
@ -49,14 +53,32 @@
) )
let errors = {} let errors = {}
let fromPrimary, fromForeign, fromColumn, toColumn let fromPrimary, fromForeign, fromColumn, toColumn
let fromId, toId, throughId, throughToKey, throughFromKey $: fromId = null
$: toId = null
let throughId, throughToKey, throughFromKey
let isManyToMany, isManyToOne, relationshipType let isManyToMany, isManyToOne, relationshipType
let hasValidated = false let hasValidated = false
$: tableOptions = plusTables.map(table => ({ $: tableOptions = plusTables.map(table => ({
label: table.name, label: table.name,
value: table._id, value: table._id,
name: table.name,
_id: table._id,
})) }))
$: {
// Determine the relationship type based on the selected values of both parts
relationshipType = Object.entries(relationshipMap).find(
([_, parts]) =>
parts.part1 === relationshipPart1 && parts.part2 === relationshipPart2
)?.[0]
changed(() => {
hasValidated = false
})
}
$: console.log(relationshipType)
$: valid = getErrorCount(errors) === 0 && allRequiredAttributesSet() $: valid = getErrorCount(errors) === 0 && allRequiredAttributesSet()
$: isManyToMany = relationshipType === RelationshipType.MANY_TO_MANY $: isManyToMany = relationshipType === RelationshipType.MANY_TO_MANY
$: isManyToOne = relationshipType === RelationshipType.MANY_TO_ONE $: isManyToOne = relationshipType === RelationshipType.MANY_TO_ONE
@ -328,6 +350,8 @@
fromPrimary = selectedFromTable?.primary[0] || null fromPrimary = selectedFromTable?.primary[0] || null
} }
}) })
let relationshipPart1 = PrettyRelationshipDefinitions.MANY
let relationshipPart2 = PrettyRelationshipDefinitions.ONE
</script> </script>
<ModalContent <ModalContent
@ -336,33 +360,34 @@
onConfirm={saveRelationship} onConfirm={saveRelationship}
disabled={!valid} disabled={!valid}
> >
<Select
label="Relationship type"
options={relationshipTypes}
bind:value={relationshipType}
bind:error={errors.relationshipType}
on:change={() =>
changed(() => {
hasValidated = false
})}
/>
<div class="headings"> <div class="headings">
<Detail>Tables</Detail> <Detail>Tables</Detail>
</div> </div>
{#if !selectedFromTable}
<Select <RelationshipSelector
label="Select from table" bind:relationshipPart1
options={tableOptions} bind:relationshipPart2
bind:value={fromId} {relationshipOpts1}
bind:error={errors.fromTable} {relationshipOpts2}
on:change={e => bind:relationshipTableIdPrimary={fromId}
changed(() => { bind:relationshipTableIdSecondary={toId}
const table = plusTables.find(tbl => tbl._id === e.detail) {tableOptions}
fromColumn = table?.name || "" {errors}
fromPrimary = table?.primary?.[0] primaryDisabled={selectedFromTable}
})} primaryTableChanged={e =>
/> changed(() => {
{/if} const table = plusTables.find(tbl => tbl._id === e.detail)
fromColumn = table?.name || ""
fromPrimary = table?.primary?.[0]
})}
secondaryTableChanged={e =>
changed(() => {
const table = plusTables.find(tbl => tbl._id === e.detail)
toColumn = table.name || ""
fromForeign = null
})}
/>
{#if isManyToOne && fromId} {#if isManyToOne && fromId}
<Select <Select
label={`Primary Key (${getTable(fromId).name})`} label={`Primary Key (${getTable(fromId).name})`}
@ -372,18 +397,6 @@
on:change={changed} on:change={changed}
/> />
{/if} {/if}
<Select
label={"Select to table"}
options={tableOptions}
bind:value={toId}
bind:error={errors.toTable}
on:change={e =>
changed(() => {
const table = plusTables.find(tbl => tbl._id === e.detail)
toColumn = table.name || ""
fromForeign = null
})}
/>
{#if isManyToMany} {#if isManyToMany}
<Select <Select
label={"Through"} label={"Through"}

View file

@ -6,11 +6,14 @@
export let relationshipTableIdPrimary export let relationshipTableIdPrimary
export let relationshipTableIdSecondary export let relationshipTableIdSecondary
export let editableColumn export let editableColumn
export let linkEditDisabled export let linkEditDisabled = false
export let tableOptions export let tableOptions
export let errors export let errors
export let relationshipOpts1 export let relationshipOpts1
export let relationshipOpts2 export let relationshipOpts2
export let primaryTableChanged
export let secondaryTableChanged
export let primaryDisabled = true
</script> </script>
<div class="relationship-container"> <div class="relationship-container">
@ -19,16 +22,19 @@
disabled={linkEditDisabled} disabled={linkEditDisabled}
bind:value={relationshipPart1} bind:value={relationshipPart1}
options={relationshipOpts1} options={relationshipOpts1}
bind:error={errors.relationshipType}
/> />
</div> </div>
<div class="relationship-label">in</div> <div class="relationship-label">in</div>
<div class="relationship-part"> <div class="relationship-part">
<Select <Select
disabled disabled={primaryDisabled}
options={tableOptions} options={tableOptions}
getOptionLabel={table => table.name} getOptionLabel={table => table.name}
getOptionValue={table => table._id} getOptionValue={table => table._id}
bind:value={relationshipTableIdPrimary} bind:value={relationshipTableIdPrimary}
on:change={primaryTableChanged}
bind:error={errors.fromTable}
/> />
</div> </div>
</div> </div>
@ -46,20 +52,24 @@
<Select <Select
disabled={linkEditDisabled} disabled={linkEditDisabled}
bind:value={relationshipTableIdSecondary} bind:value={relationshipTableIdSecondary}
bind:error={errors.toTable}
options={tableOptions.filter( options={tableOptions.filter(
table => table._id !== relationshipTableIdPrimary table => table._id !== relationshipTableIdPrimary
)} )}
getOptionLabel={table => table.name} getOptionLabel={table => table.name}
getOptionValue={table => table._id} getOptionValue={table => table._id}
on:change={secondaryTableChanged}
/> />
</div> </div>
</div> </div>
<Input {#if editableColumn}
disabled={linkEditDisabled} <Input
label={`Column name in other table`} disabled={linkEditDisabled}
bind:value={editableColumn.fieldName} label={`Column name in other table`}
error={errors.relatedName} bind:value={editableColumn.fieldName}
/> error={errors.relatedName}
/>
{/if}
<style> <style>
.relationship-container { .relationship-container {