Adding validation to the SQL relationship creation modal.
This commit is contained in:
parent
b216c03e44
commit
04fbb8ea29
|
@ -1,8 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import { RelationshipTypes } from "constants/backend"
|
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 { tables } from "stores/backend"
|
||||||
import { uuid } from "builderStore/uuid"
|
import { uuid } from "builderStore/uuid"
|
||||||
|
import { writable } from "svelte/store"
|
||||||
|
|
||||||
export let save
|
export let save
|
||||||
export let datasource
|
export let datasource
|
||||||
|
@ -14,16 +15,57 @@
|
||||||
let originalFromName = fromRelationship.name,
|
let originalFromName = fromRelationship.name,
|
||||||
originalToName = toRelationship.name
|
originalToName = toRelationship.name
|
||||||
|
|
||||||
function isValid(relationship) {
|
function inSchema(table, prop, ogName) {
|
||||||
if (
|
if (!table || !prop || prop === ogName) {
|
||||||
relationship.relationshipType === RelationshipTypes.MANY_TO_MANY &&
|
|
||||||
!relationship.through
|
|
||||||
) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return (
|
const keys = Object.keys(table.schema).map(key => key.toLowerCase())
|
||||||
relationship.name && relationship.tableId && relationship.relationshipType
|
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 => ({
|
$: tableOptions = plusTables.map(table => ({
|
||||||
|
@ -33,7 +75,8 @@
|
||||||
$: fromTable = plusTables.find(table => table._id === toRelationship?.tableId)
|
$: fromTable = plusTables.find(table => table._id === toRelationship?.tableId)
|
||||||
$: toTable = plusTables.find(table => table._id === fromRelationship?.tableId)
|
$: toTable = plusTables.find(table => table._id === fromRelationship?.tableId)
|
||||||
$: through = plusTables.find(table => table._id === fromRelationship?.through)
|
$: 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
|
$: linkTable = through || toTable
|
||||||
$: relationshipTypes = [
|
$: relationshipTypes = [
|
||||||
{
|
{
|
||||||
|
@ -155,32 +198,44 @@
|
||||||
<Select
|
<Select
|
||||||
label="Select from table"
|
label="Select from table"
|
||||||
options={tableOptions}
|
options={tableOptions}
|
||||||
|
on:change={() => ($touched.from = true)}
|
||||||
|
bind:error={errors.from}
|
||||||
bind:value={toRelationship.tableId}
|
bind:value={toRelationship.tableId}
|
||||||
/>
|
/>
|
||||||
<Select
|
<Select
|
||||||
label={"Select to table"}
|
label={"Select to table"}
|
||||||
options={tableOptions}
|
options={tableOptions}
|
||||||
|
on:change={() => ($touched.to = true)}
|
||||||
|
bind:error={errors.to}
|
||||||
bind:value={fromRelationship.tableId}
|
bind:value={fromRelationship.tableId}
|
||||||
/>
|
/>
|
||||||
{#if fromRelationship?.relationshipType === RelationshipTypes.MANY_TO_MANY}
|
{#if fromRelationship?.relationshipType === RelationshipTypes.MANY_TO_MANY}
|
||||||
<Select
|
<Select
|
||||||
label={"Through"}
|
label={"Through"}
|
||||||
options={tableOptions}
|
options={tableOptions}
|
||||||
|
on:change={() => ($touched.through = true)}
|
||||||
|
bind:error={errors.through}
|
||||||
bind:value={fromRelationship.through}
|
bind:value={fromRelationship.through}
|
||||||
/>
|
/>
|
||||||
{:else if toTable}
|
{:else if toTable}
|
||||||
<Select
|
<Select
|
||||||
label={`Foreign Key (${toTable?.name})`}
|
label={`Foreign Key (${toTable?.name})`}
|
||||||
options={Object.keys(toTable?.schema)}
|
options={Object.keys(toTable?.schema)}
|
||||||
|
on:change={() => ($touched.foreign = true)}
|
||||||
|
bind:error={errors.foreign}
|
||||||
bind:value={fromRelationship.fieldName}
|
bind:value={fromRelationship.fieldName}
|
||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="headings">
|
<div class="headings">
|
||||||
<Detail>Column names</Detail>
|
<Detail>Column names</Detail>
|
||||||
</div>
|
</div>
|
||||||
<Input label="From table column" bind:value={fromRelationship.name} />
|
<Body>
|
||||||
<Input label="To table column" bind:value={toRelationship.name} />
|
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">
|
<div slot="footer">
|
||||||
|
|
||||||
{#if originalFromName != null}
|
{#if originalFromName != null}
|
||||||
<Button warning text on:click={deleteRelationship}>Delete</Button>
|
<Button warning text on:click={deleteRelationship}>Delete</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
Loading…
Reference in New Issue