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

View file

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