diff --git a/packages/bbui/src/Table/ArrayRenderer.svelte b/packages/bbui/src/Table/ArrayRenderer.svelte
new file mode 100644
index 0000000000..8281fce78c
--- /dev/null
+++ b/packages/bbui/src/Table/ArrayRenderer.svelte
@@ -0,0 +1,17 @@
+
+
+{#each badges as badge}
+ {badge}
+{/each}
+{#if leftover}
+
+{leftover} more
+{/if}
diff --git a/packages/bbui/src/Table/CellRenderer.svelte b/packages/bbui/src/Table/CellRenderer.svelte
index 2d073b7782..d6a2f3196d 100644
--- a/packages/bbui/src/Table/CellRenderer.svelte
+++ b/packages/bbui/src/Table/CellRenderer.svelte
@@ -4,7 +4,7 @@
import DateTimeRenderer from "./DateTimeRenderer.svelte"
import RelationshipRenderer from "./RelationshipRenderer.svelte"
import AttachmentRenderer from "./AttachmentRenderer.svelte"
-
+ import ArrayRenderer from "./ArrayRenderer.svelte"
export let row
export let schema
export let value
@@ -19,6 +19,7 @@
options: StringRenderer,
number: StringRenderer,
longform: StringRenderer,
+ array: ArrayRenderer,
}
$: type = schema?.type ?? "string"
$: customRenderer = customRenderers?.find(x => x.column === schema?.name)
diff --git a/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte b/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte
index 078dbf25b2..66879b83cf 100644
--- a/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte
+++ b/packages/builder/src/components/backend/DataTable/RowFieldControl.svelte
@@ -1,5 +1,12 @@
diff --git a/packages/builder/src/constants/backend/index.js b/packages/builder/src/constants/backend/index.js
index 88152deb0f..2ce88c9648 100644
--- a/packages/builder/src/constants/backend/index.js
+++ b/packages/builder/src/constants/backend/index.js
@@ -26,6 +26,15 @@ export const FIELDS = {
inclusion: [],
},
},
+ ARRAY: {
+ name: "List",
+ type: "array",
+ constraints: {
+ type: "array",
+ presence: false,
+ inclusion: [],
+ },
+ },
NUMBER: {
name: "Number",
type: "number",
diff --git a/packages/server/src/api/controllers/row/utils.js b/packages/server/src/api/controllers/row/utils.js
index 16c48181d1..bdb7e03785 100644
--- a/packages/server/src/api/controllers/row/utils.js
+++ b/packages/server/src/api/controllers/row/utils.js
@@ -58,12 +58,24 @@ exports.validate = async ({ appId, tableId, row, table }) => {
const constraints = cloneDeep(table.schema[fieldName].constraints)
// special case for options, need to always allow unselected (null)
if (
- table.schema[fieldName].type === FieldTypes.OPTIONS &&
+ table.schema[fieldName].type ===
+ (FieldTypes.OPTIONS || FieldTypes.ARRAY) &&
constraints.inclusion
) {
constraints.inclusion.push(null)
}
- const res = validateJs.single(row[fieldName], constraints)
+ let res
+
+ // Validate.js doesn't seem to handle array of array very well
+ if (table.schema[fieldName].type === FieldTypes.ARRAY) {
+ row[fieldName].map(val => {
+ if (constraints.inclusion.includes(val)) {
+ errors[fieldName] = "Field not in list"
+ }
+ })
+ } else {
+ res = validateJs.single(row[fieldName], constraints)
+ }
if (res) errors[fieldName] = res
}
return { valid: Object.keys(errors).length === 0, errors }
diff --git a/packages/server/src/constants/index.js b/packages/server/src/constants/index.js
index 703b33deb1..bc7b5b368f 100644
--- a/packages/server/src/constants/index.js
+++ b/packages/server/src/constants/index.js
@@ -12,6 +12,7 @@ exports.FieldTypes = {
OPTIONS: "options",
NUMBER: "number",
BOOLEAN: "boolean",
+ ARRAY: "array",
DATETIME: "datetime",
ATTACHMENT: "attachment",
LINK: "link",
diff --git a/packages/server/src/utilities/rowProcessor.js b/packages/server/src/utilities/rowProcessor.js
index c067d4de87..3c43a20409 100644
--- a/packages/server/src/utilities/rowProcessor.js
+++ b/packages/server/src/utilities/rowProcessor.js
@@ -29,6 +29,11 @@ const TYPE_TRANSFORM_MAP = {
[null]: null,
[undefined]: undefined,
},
+ [FieldTypes.ARRAY]: {
+ "": [],
+ [null]: [],
+ [undefined]: undefined,
+ },
[FieldTypes.STRING]: {
"": "",
[null]: "",