Adding validation to the SQL relationship creation modal.
This commit is contained in:
parent
b216c03e44
commit
04fbb8ea29
|
@ -1,8 +1,9 @@
|
|||
<script>
|
||||
import { RelationshipTypes } from "constants/backend"
|
||||
import { Button, Input, ModalContent, Select, Detail } from "@budibase/bbui"
|
||||
import { Button, Input, ModalContent, Select, Detail, Body } from "@budibase/bbui"
|
||||
import { tables } from "stores/backend"
|
||||
import { uuid } from "builderStore/uuid"
|
||||
import { writable } from "svelte/store"
|
||||
|
||||
export let save
|
||||
export let datasource
|
||||
|
@ -14,16 +15,57 @@
|
|||
let originalFromName = fromRelationship.name,
|
||||
originalToName = toRelationship.name
|
||||
|
||||
function isValid(relationship) {
|
||||
if (
|
||||
relationship.relationshipType === RelationshipTypes.MANY_TO_MANY &&
|
||||
!relationship.through
|
||||
) {
|
||||
function inSchema(table, prop, ogName) {
|
||||
if (!table || !prop || prop === ogName) {
|
||||
return false
|
||||
}
|
||||
return (
|
||||
relationship.name && relationship.tableId && relationship.relationshipType
|
||||
)
|
||||
const keys = Object.keys(table.schema).map(key => key.toLowerCase())
|
||||
return keys.indexOf(prop.toLowerCase()) !== -1
|
||||
}
|
||||
|
||||
const touched = writable({})
|
||||
|
||||
function checkForErrors(fromTable, toTable, throughTable, fromRelate, toRelate) {
|
||||
const isMany = fromRelate.relationshipType === RelationshipTypes.MANY_TO_MANY
|
||||
const tableNotSet = "Please specify a table"
|
||||
const errors = {}
|
||||
if ($touched.from && !fromTable) {
|
||||
errors.from = tableNotSet
|
||||
}
|
||||
if ($touched.to && !toTable) {
|
||||
errors.to = tableNotSet
|
||||
}
|
||||
if ($touched.through && isMany && !fromRelate.through) {
|
||||
errors.through = tableNotSet
|
||||
}
|
||||
if ($touched.foreign && !isMany && !fromRelate.fieldName) {
|
||||
errors.foreign = "Please pick the foreign key"
|
||||
}
|
||||
const colNotSet = "Please specify a column name"
|
||||
if ($touched.fromCol && !fromRelate.name) {
|
||||
errors.fromCol = colNotSet
|
||||
}
|
||||
if ($touched.toCol && !toRelate.name) {
|
||||
errors.toCol = colNotSet
|
||||
}
|
||||
const tableError = "From/to/through tables must be different"
|
||||
if (fromTable && (fromTable === toTable || fromTable === throughTable)) {
|
||||
errors.from = tableError
|
||||
}
|
||||
if (toTable && (toTable === fromTable || toTable === throughTable)) {
|
||||
errors.to = tableError
|
||||
}
|
||||
if (throughTable && (throughTable === fromTable || throughTable === toTable)) {
|
||||
errors.through = tableError
|
||||
}
|
||||
const colError = "Column name cannot be an existing column"
|
||||
if (inSchema(fromTable, fromRelate.name, originalFromName)) {
|
||||
errors.fromCol = colError
|
||||
}
|
||||
if (inSchema(toTable, toRelate.name, originalToName)) {
|
||||
errors.toCol = colError
|
||||
}
|
||||
return errors
|
||||
}
|
||||
|
||||
$: tableOptions = plusTables.map(table => ({
|
||||
|
@ -33,7 +75,8 @@
|
|||
$: fromTable = plusTables.find(table => table._id === toRelationship?.tableId)
|
||||
$: toTable = plusTables.find(table => table._id === fromRelationship?.tableId)
|
||||
$: through = plusTables.find(table => table._id === fromRelationship?.through)
|
||||
$: valid = toTable && fromTable && isValid(fromRelationship)
|
||||
$: errors = checkForErrors(fromTable, toTable, through, fromRelationship, toRelationship)
|
||||
$: valid = Object.keys(errors).length === 0 && Object.keys($touched).length !== 0
|
||||
$: linkTable = through || toTable
|
||||
$: relationshipTypes = [
|
||||
{
|
||||
|
@ -155,32 +198,44 @@
|
|||
<Select
|
||||
label="Select from table"
|
||||
options={tableOptions}
|
||||
on:change={() => ($touched.from = true)}
|
||||
bind:error={errors.from}
|
||||
bind:value={toRelationship.tableId}
|
||||
/>
|
||||
<Select
|
||||
label={"Select to table"}
|
||||
options={tableOptions}
|
||||
on:change={() => ($touched.to = true)}
|
||||
bind:error={errors.to}
|
||||
bind:value={fromRelationship.tableId}
|
||||
/>
|
||||
{#if fromRelationship?.relationshipType === RelationshipTypes.MANY_TO_MANY}
|
||||
<Select
|
||||
label={"Through"}
|
||||
options={tableOptions}
|
||||
on:change={() => ($touched.through = true)}
|
||||
bind:error={errors.through}
|
||||
bind:value={fromRelationship.through}
|
||||
/>
|
||||
{:else if toTable}
|
||||
<Select
|
||||
label={`Foreign Key (${toTable?.name})`}
|
||||
options={Object.keys(toTable?.schema)}
|
||||
on:change={() => ($touched.foreign = true)}
|
||||
bind:error={errors.foreign}
|
||||
bind:value={fromRelationship.fieldName}
|
||||
/>
|
||||
{/if}
|
||||
<div class="headings">
|
||||
<Detail>Column names</Detail>
|
||||
</div>
|
||||
<Input label="From table column" bind:value={fromRelationship.name} />
|
||||
<Input label="To table column" bind:value={toRelationship.name} />
|
||||
<Body>
|
||||
Budibase manages SQL relationships as a new column in the table, please provide a name for these columns.
|
||||
</Body>
|
||||
<Input on:blur={() => ($touched.fromCol = true)} bind:error={errors.fromCol} label="From table column" bind:value={fromRelationship.name} />
|
||||
<Input on:blur={() => ($touched.toCol = true)} bind:error={errors.toCol} label="To table column" bind:value={toRelationship.name} />
|
||||
<div slot="footer">
|
||||
|
||||
{#if originalFromName != null}
|
||||
<Button warning text on:click={deleteRelationship}>Delete</Button>
|
||||
{/if}
|
||||
|
|
Loading…
Reference in New Issue