Improves error handling around grid relationship cell when handling invalid requests

This commit is contained in:
Dean 2024-07-18 09:49:35 +01:00
parent 5e3bec86ed
commit 6b1d16420e
2 changed files with 31 additions and 8 deletions

View File

@ -7,7 +7,7 @@
const { API, cache } = getContext("grid")
export let value
export let value = []
export let api
export let readonly
export let focused
@ -29,10 +29,12 @@
let searching = false
let container
let anchor
let cacheStr
$: fieldValue = parseValue(value)
$: oneRowOnly = schema?.relationshipType === "one-to-many"
$: editable = focused && !readonly
$: lookupMap = buildLookupMap(value, isOpen)
$: lookupMap = buildLookupMap(fieldValue, isOpen)
$: debouncedSearch(searchString)
$: {
if (!focused && isOpen) {
@ -40,6 +42,22 @@
}
}
const parseValue = value => {
// Is it unset or a valid array? 1+
const isValid = val =>
!val ||
(Array.isArray(val) &&
(val.length === 0 ||
val.some(relEntry => Object.hasOwn(relEntry, "_id"))))
const stf = JSON.stringify(value)
if (!cacheStr || cacheStr !== stf) {
cacheStr = stf
return isValid(value) ? [...(value || [])] : []
}
return [...(value || [])]
}
// Builds a lookup map to quickly check which rows are selected
const buildLookupMap = (value, isOpen) => {
let map = {}
@ -177,13 +195,13 @@
// Toggles whether a row is included in the relationship or not
const toggleRow = async row => {
if (value?.some(x => x._id === row._id)) {
if (fieldValue?.some(x => x._id === row._id)) {
// If the row is already included, remove it and update the candidate
// row to be the same position if possible
if (oneRowOnly) {
await onChange([])
} else {
const newValue = value.filter(x => x._id !== row._id)
const newValue = fieldValue.filter(x => x._id !== row._id)
if (!newValue.length) {
candidateIndex = null
} else {
@ -196,7 +214,7 @@
if (oneRowOnly) {
await onChange([row])
} else {
await onChange(sortRows([...(value || []), row]))
await onChange(sortRows([...(fieldValue || []), row]))
}
candidateIndex = null
}
@ -238,7 +256,7 @@
class:wrap={editable || contentLines > 1}
on:wheel={e => (focused ? e.stopPropagation() : null)}
>
{#each value || [] as relationship}
{#each fieldValue || [] as relationship}
{#if relationship[primaryDisplay] || relationship.primaryDisplay}
<div class="badge">
<span>
@ -263,9 +281,9 @@
</div>
{/if}
</div>
{#if !hideCounter && value?.length}
{#if !hideCounter && fieldValue?.length}
<div class="count">
{value?.length || 0}
{fieldValue?.length || 0}
</div>
{/if}
</div>

View File

@ -172,6 +172,11 @@ class LinkController {
const rowField = row[fieldName]
const field = table.schema[fieldName]
if (field.type === FieldType.LINK && rowField != null) {
// Expects an array of docs with at least their _id
if (!Array.isArray(rowField)) {
throw new Error("Relationship Error: Invalid request")
}
// check which links actual pertain to the update in this row
const thisFieldLinkDocs = linkDocs.filter(
linkDoc =>