1
0
Fork 0
mirror of synced 2024-09-20 19:33:10 +12:00

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

View file

@ -172,6 +172,11 @@ class LinkController {
const rowField = row[fieldName] const rowField = row[fieldName]
const field = table.schema[fieldName] const field = table.schema[fieldName]
if (field.type === FieldType.LINK && rowField != null) { 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 // check which links actual pertain to the update in this row
const thisFieldLinkDocs = linkDocs.filter( const thisFieldLinkDocs = linkDocs.filter(
linkDoc => linkDoc =>