diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte index 8233278e58..ba61ede746 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte @@ -33,7 +33,7 @@ import { getBindings } from "components/backend/DataTable/formula" import JSONSchemaModal from "./JSONSchemaModal.svelte" import { ValidColumnNameRegex } from "@budibase/shared-core" - import { FieldType } from "@budibase/types" + import { FieldType, FieldSubtype, SourceName } from "@budibase/types" import RelationshipSelector from "components/common/RelationshipSelector.svelte" const AUTO_TYPE = "auto" @@ -43,7 +43,6 @@ const NUMBER_TYPE = FIELDS.NUMBER.type const JSON_TYPE = FIELDS.JSON.type const DATE_TYPE = FIELDS.DATETIME.type - const USER_REFRENCE_TYPE = FIELDS.BB_REFERENCE_USER.compositeType const dispatch = createEventDispatcher() const PROHIBITED_COLUMN_NAMES = ["type", "_id", "_rev", "tableId"] @@ -52,7 +51,19 @@ export let field let mounted = false - let fieldDefinitions = cloneDeep(FIELDS) + const fieldDefinitions = Object.values(FIELDS).reduce( + // Storing the fields by complex field id + (acc, field) => ({ + ...acc, + [makeFieldId(field.type, field.subtype)]: field, + }), + {} + ) + + function makeFieldId(type, subtype) { + return `${type}${subtype || ""}`.toUpperCase() + } + let originalName let linkEditDisabled let primaryDisplay @@ -72,8 +83,8 @@ let jsonSchemaModal let allowedTypes = [] let editableColumn = { - type: fieldDefinitions.STRING.type, - constraints: fieldDefinitions.STRING.constraints, + type: FIELDS.STRING.type, + constraints: FIELDS.STRING.constraints, // Initial value for column name in other table for linked records fieldName: $tables.selected.name, } @@ -139,9 +150,6 @@ $tables.selected.primaryDisplay == null || $tables.selected.primaryDisplay === editableColumn.name - if (editableColumn.type === FieldType.BB_REFERENCE) { - editableColumn.type = `${editableColumn.type}_${editableColumn.subtype}` - } // Here we are setting the relationship values based on the editableColumn // This part of the code is used when viewing an existing field hence the check // for the tableId @@ -172,7 +180,17 @@ } } - allowedTypes = getAllowedTypes() + if (!savingColumn) { + editableColumn.fieldId = makeFieldId( + editableColumn.type, + editableColumn.subtype + ) + + allowedTypes = getAllowedTypes().map(t => ({ + fieldId: makeFieldId(t.type, t.subtype), + ...t, + })) + } } $: initialiseField(field, savingColumn) @@ -249,13 +267,7 @@ let saveColumn = cloneDeep(editableColumn) - // Handle types on composite types - const definition = fieldDefinitions[saveColumn.type.toUpperCase()] - if (definition && saveColumn.type === definition.compositeType) { - saveColumn.type = definition.type - saveColumn.subtype = definition.subtype - delete saveColumn.compositeType - } + delete saveColumn.fieldId if (saveColumn.type === AUTO_TYPE) { saveColumn = buildAutoColumn( @@ -320,27 +332,33 @@ } } - function handleTypeChange(event) { + function onHandleTypeChange(event) { + handleTypeChange(event.detail) + } + + function handleTypeChange(type) { // remove any extra fields that may not be related to this type delete editableColumn.autocolumn delete editableColumn.subtype delete editableColumn.tableId delete editableColumn.relationshipType delete editableColumn.formulaType + delete editableColumn.constraints // Add in defaults and initial definition - const definition = fieldDefinitions[event.detail?.toUpperCase()] + const definition = fieldDefinitions[type?.toUpperCase()] if (definition?.constraints) { editableColumn.constraints = definition.constraints } + editableColumn.type = definition.type + editableColumn.subtype = definition.subtype + // Default relationships many to many if (editableColumn.type === LINK_TYPE) { editableColumn.relationshipType = RelationshipType.MANY_TO_MANY } else if (editableColumn.type === FORMULA_TYPE) { editableColumn.formulaType = "dynamic" - } else if (editableColumn.type === USER_REFRENCE_TYPE) { - editableColumn.relationshipType = RelationshipType.ONE_TO_MANY } } @@ -381,9 +399,26 @@ return ALLOWABLE_NUMBER_OPTIONS } + const isUsers = + editableColumn.type === FieldType.BB_REFERENCE && + editableColumn.subtype === FieldSubtype.USERS + if (!external) { return [ - ...Object.values(fieldDefinitions), + FIELDS.STRING, + FIELDS.BARCODEQR, + FIELDS.LONGFORM, + FIELDS.OPTIONS, + FIELDS.ARRAY, + FIELDS.NUMBER, + FIELDS.BIGINT, + FIELDS.BOOLEAN, + FIELDS.DATETIME, + FIELDS.ATTACHMENT, + FIELDS.LINK, + FIELDS.FORMULA, + FIELDS.JSON, + isUsers ? FIELDS.USERS : FIELDS.USER, { name: "Auto Column", type: AUTO_TYPE }, ] } else { @@ -397,7 +432,7 @@ FIELDS.BOOLEAN, FIELDS.FORMULA, FIELDS.BIGINT, - FIELDS.BB_REFERENCE_USER, + isUsers ? FIELDS.USERS : FIELDS.USER, ] // no-sql or a spreadsheet if (!external || table.sql) { @@ -472,6 +507,13 @@ return newError } + function isUsersColumn(column) { + return ( + column.type === FieldType.BB_REFERENCE && + [FieldSubtype.USER, FieldSubtype.USERS].includes(column.subtype) + ) + } + onMount(() => { mounted = true }) @@ -489,11 +531,11 @@ {/if} x.name === filter.field) filter.type = fieldSchema?.type + filter.subtype = fieldSchema?.subtype // Update external type based on field filter.externalType = getSchema(filter)?.externalType @@ -196,7 +196,7 @@ } return LuceneUtils.getValidOperatorsForType( - filter.type, + { type: filter.type, subtype: filter.subtype }, filter.field, datasource ) @@ -301,9 +301,10 @@ {:else if filter.type === FieldType.BB_REFERENCE} {:else} diff --git a/packages/builder/src/constants/backend/index.js b/packages/builder/src/constants/backend/index.js index 8b76207822..a81b33c2d3 100644 --- a/packages/builder/src/constants/backend/index.js +++ b/packages/builder/src/constants/backend/index.js @@ -1,7 +1,9 @@ +import { FieldType, FieldSubtype } from "@budibase/types" + export const FIELDS = { STRING: { name: "Text", - type: "string", + type: FieldType.STRING, icon: "Text", constraints: { type: "string", @@ -11,7 +13,7 @@ export const FIELDS = { }, BARCODEQR: { name: "Barcode/QR", - type: "barcodeqr", + type: FieldType.BARCODEQR, icon: "Camera", constraints: { type: "string", @@ -21,7 +23,7 @@ export const FIELDS = { }, LONGFORM: { name: "Long Form Text", - type: "longform", + type: FieldType.LONGFORM, icon: "TextAlignLeft", constraints: { type: "string", @@ -31,7 +33,7 @@ export const FIELDS = { }, OPTIONS: { name: "Options", - type: "options", + type: FieldType.OPTIONS, icon: "Dropdown", constraints: { type: "string", @@ -41,7 +43,7 @@ export const FIELDS = { }, ARRAY: { name: "Multi-select", - type: "array", + type: FieldType.ARRAY, icon: "Duplicate", constraints: { type: "array", @@ -51,7 +53,7 @@ export const FIELDS = { }, NUMBER: { name: "Number", - type: "number", + type: FieldType.NUMBER, icon: "123", constraints: { type: "number", @@ -61,12 +63,12 @@ export const FIELDS = { }, BIGINT: { name: "BigInt", - type: "bigint", + type: FieldType.BIGINT, icon: "TagBold", }, BOOLEAN: { name: "Boolean", - type: "boolean", + type: FieldType.BOOLEAN, icon: "Boolean", constraints: { type: "boolean", @@ -75,7 +77,7 @@ export const FIELDS = { }, DATETIME: { name: "Date/Time", - type: "datetime", + type: FieldType.DATETIME, icon: "Calendar", constraints: { type: "string", @@ -89,7 +91,7 @@ export const FIELDS = { }, ATTACHMENT: { name: "Attachment", - type: "attachment", + type: FieldType.ATTACHMENT, icon: "Folder", constraints: { type: "array", @@ -98,7 +100,7 @@ export const FIELDS = { }, LINK: { name: "Relationship", - type: "link", + type: FieldType.LINK, icon: "Link", constraints: { type: "array", @@ -107,26 +109,34 @@ export const FIELDS = { }, FORMULA: { name: "Formula", - type: "formula", + type: FieldType.FORMULA, icon: "Calculator", constraints: {}, }, JSON: { name: "JSON", - type: "json", + type: FieldType.JSON, icon: "Brackets", constraints: { type: "object", presence: false, }, }, - BB_REFERENCE_USER: { + USER: { name: "User", - type: "bb_reference", - subtype: "user", - compositeType: "bb_reference_user", // Used for working with the subtype on CreateEditColumn as is it was a primary type + type: FieldType.BB_REFERENCE, + subtype: FieldSubtype.USER, icon: "User", }, + USERS: { + name: "Users", + type: FieldType.BB_REFERENCE, + subtype: FieldSubtype.USERS, + icon: "User", + constraints: { + type: "array", + }, + }, } export const AUTO_COLUMN_SUB_TYPES = { diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ConditionalUIDrawer.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ConditionalUIDrawer.svelte index d21b4799a1..ddbc8b004e 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ConditionalUIDrawer.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/ConditionalUIDrawer.svelte @@ -118,7 +118,7 @@ } const getOperatorOptions = condition => { - return LuceneUtils.getValidOperatorsForType(condition.valueType) + return LuceneUtils.getValidOperatorsForType({ type: condition.valueType }) } const onOperatorChange = (condition, newOperator) => { @@ -137,9 +137,9 @@ condition.referenceValue = null // Ensure a valid operator is set - const validOperators = LuceneUtils.getValidOperatorsForType(newType).map( - x => x.value - ) + const validOperators = LuceneUtils.getValidOperatorsForType({ + type: newType, + }).map(x => x.value) if (!validOperators.includes(condition.operator)) { condition.operator = validOperators[0] ?? Constants.OperatorOptions.Equals.value diff --git a/packages/client/src/components/app/dynamic-filter/FilterModal.svelte b/packages/client/src/components/app/dynamic-filter/FilterModal.svelte index 513c19126d..0adf508dfa 100644 --- a/packages/client/src/components/app/dynamic-filter/FilterModal.svelte +++ b/packages/client/src/components/app/dynamic-filter/FilterModal.svelte @@ -63,7 +63,7 @@ // Ensure a valid operator is set const validOperators = LuceneUtils.getValidOperatorsForType( - expression.type, + { type: expression.type }, expression.field, datasource ).map(x => x.value) @@ -125,7 +125,7 @@