From 6b1d16420e26bebf15a8f41943abcb29ea8247cb Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 18 Jul 2024 09:49:35 +0100 Subject: [PATCH 1/3] Improves error handling around grid relationship cell when handling invalid requests --- .../grid/cells/RelationshipCell.svelte | 34 ++++++++++++++----- .../src/db/linkedRows/LinkController.ts | 5 +++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte index 462d53445d..d91655a715 100644 --- a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte @@ -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}
@@ -263,9 +281,9 @@
{/if} - {#if !hideCounter && value?.length} + {#if !hideCounter && fieldValue?.length}
- {value?.length || 0} + {fieldValue?.length || 0}
{/if} diff --git a/packages/server/src/db/linkedRows/LinkController.ts b/packages/server/src/db/linkedRows/LinkController.ts index ffc9e32fde..4de5506e05 100644 --- a/packages/server/src/db/linkedRows/LinkController.ts +++ b/packages/server/src/db/linkedRows/LinkController.ts @@ -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 => From 7c03a39b9f2b4a32331fea677b1cc04bb444ca59 Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 18 Jul 2024 14:17:51 +0100 Subject: [PATCH 2/3] PR feedback. Remove unnecessary caching --- .../grid/cells/RelationshipCell.svelte | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte index d91655a715..1b3b24ff2e 100644 --- a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte @@ -29,7 +29,6 @@ let searching = false let container let anchor - let cacheStr $: fieldValue = parseValue(value) $: oneRowOnly = schema?.relationshipType === "one-to-many" @@ -43,19 +42,10 @@ } 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 || [])] : [] + if (Array.isArray(value) && value.every(x => x?._id)) { + return value } - return [...(value || [])] + return [] } // Builds a lookup map to quickly check which rows are selected From 4da3155374a8afb035773ea4841cb8b4356f960f Mon Sep 17 00:00:00 2001 From: Dean Date: Thu, 18 Jul 2024 15:23:10 +0100 Subject: [PATCH 3/3] Minor change to the error messaging --- packages/server/src/db/linkedRows/LinkController.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/db/linkedRows/LinkController.ts b/packages/server/src/db/linkedRows/LinkController.ts index 4de5506e05..7427c9a44d 100644 --- a/packages/server/src/db/linkedRows/LinkController.ts +++ b/packages/server/src/db/linkedRows/LinkController.ts @@ -174,7 +174,7 @@ class LinkController { 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") + throw new Error("Relationship Error: Invalid value") } // check which links actual pertain to the update in this row