Adding validation to the SQL relationship creation modal.

This commit is contained in:
mike12345567 2021-07-06 12:58:36 +01:00
parent b216c03e44
commit 04fbb8ea29
1 changed files with 67 additions and 12 deletions

View File

@ -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}