From 69873152b6afab9b4ed75111762ad33779c58bf9 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Mon, 19 Dec 2022 15:46:38 +0000 Subject: [PATCH 001/149] Add scaffold --- .../TestConfiguration/accounts.ts | 19 +++++++++++++++++++ .../internal-api/TestConfiguration/index.ts | 4 +++- 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 qa-core/src/config/internal-api/TestConfiguration/accounts.ts diff --git a/qa-core/src/config/internal-api/TestConfiguration/accounts.ts b/qa-core/src/config/internal-api/TestConfiguration/accounts.ts new file mode 100644 index 0000000000..3acad4ebb1 --- /dev/null +++ b/qa-core/src/config/internal-api/TestConfiguration/accounts.ts @@ -0,0 +1,19 @@ +import { Response } from "node-fetch" +import { Table } from "@budibase/types" +import InternalAPIClient from "./InternalAPIClient" +import { responseMessage } from "../fixtures/types/responseMessage" + +export default class AccountsApi { + api: InternalAPIClient + + constructor(apiClient: InternalAPIClient) { + this.api = apiClient + } + + async validateEmail(email: string): Promise<[Response, any]> { + const response = await this.api.post(`/accounts/validate/email`, { body: { email } }) + const json = await response.json() + expect(response).toHaveStatusCode(200) + return [response, json] + } +} diff --git a/qa-core/src/config/internal-api/TestConfiguration/index.ts b/qa-core/src/config/internal-api/TestConfiguration/index.ts index a82c1fdf03..85ce0d9166 100644 --- a/qa-core/src/config/internal-api/TestConfiguration/index.ts +++ b/qa-core/src/config/internal-api/TestConfiguration/index.ts @@ -5,7 +5,7 @@ import TablesApi from "./tables" import RowApi from "./rows" import ScreenApi from "./screens" import UserManagementApi from "./userManagement" - +import AccountsApi from "./accounts" export default class TestConfiguration { applications: ApplicationApi auth: AuthApi @@ -14,6 +14,7 @@ export default class TestConfiguration { tables: TablesApi rows: RowApi users: UserManagementApi + accounts: AccountsApi constructor(apiClient: InternalAPIClient) { this.applications = new ApplicationApi(apiClient) @@ -22,6 +23,7 @@ export default class TestConfiguration { this.auth = new AuthApi(apiClient) this.screen = new ScreenApi(apiClient) this.users = new UserManagementApi(apiClient) + this.accounts = new AccountsApi(apiClient) this.context = {} } From aefa3a65c253a59f017551d21a095e3aa662fc3a Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Mon, 19 Dec 2022 18:00:51 +0000 Subject: [PATCH 002/149] Add setup for account and tenant creation --- .../internal-api/TestConfiguration/accounts.ts | 17 +++++++++++++++-- .../internal-api/TestConfiguration/index.ts | 10 ++++++++++ .../config/internal-api/fixtures/accounts.ts | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 qa-core/src/config/internal-api/fixtures/accounts.ts diff --git a/qa-core/src/config/internal-api/TestConfiguration/accounts.ts b/qa-core/src/config/internal-api/TestConfiguration/accounts.ts index 3acad4ebb1..cb544d18a0 100644 --- a/qa-core/src/config/internal-api/TestConfiguration/accounts.ts +++ b/qa-core/src/config/internal-api/TestConfiguration/accounts.ts @@ -1,7 +1,6 @@ import { Response } from "node-fetch" -import { Table } from "@budibase/types" +import { Account } from "@budibase/types" import InternalAPIClient from "./InternalAPIClient" -import { responseMessage } from "../fixtures/types/responseMessage" export default class AccountsApi { api: InternalAPIClient @@ -16,4 +15,18 @@ export default class AccountsApi { expect(response).toHaveStatusCode(200) return [response, json] } + + async validateTenantId(tenantId: string): Promise<[Response, any]> { + const response = await this.api.post(`/accounts/validate/tenantId`, { body: { tenantId } }) + const json = await response.json() + expect(response).toHaveStatusCode(200) + return [response, json] + } + + async create(body: Account): Promise<[Response, Account]> { + const response = await this.api.post(`/accounts`, { body }) + const json = await response.json() + expect(response).toHaveStatusCode(200) + return [response, json] + } } diff --git a/qa-core/src/config/internal-api/TestConfiguration/index.ts b/qa-core/src/config/internal-api/TestConfiguration/index.ts index 85ce0d9166..39a839f58d 100644 --- a/qa-core/src/config/internal-api/TestConfiguration/index.ts +++ b/qa-core/src/config/internal-api/TestConfiguration/index.ts @@ -6,6 +6,8 @@ import RowApi from "./rows" import ScreenApi from "./screens" import UserManagementApi from "./userManagement" import AccountsApi from "./accounts" +import { generateAccount } from "../fixtures/accounts" + export default class TestConfiguration { applications: ApplicationApi auth: AuthApi @@ -31,6 +33,14 @@ export default class TestConfiguration { await this.auth.login(process.env.BB_ADMIN_USER_EMAIL, process.env.BB_ADMIN_USER_PASSWORD) } + async setupAccountAndTenant() { + const account = generateAccount() + const [emailValidationResponse, emailValidationJson] = await this.accounts.validateEmail(account.email) + const [tenantIdValidationResponse, tenantIdValidationJson] = await this.accounts.validateTenantId(account.tenantId) + const [accountCreationResponse, accountCreationJson] = await this.accounts.create(account) + await this.auth.login(account.email, account.password) + } + async login(email: string, password: string) { await this.auth.login(email, password) } diff --git a/qa-core/src/config/internal-api/fixtures/accounts.ts b/qa-core/src/config/internal-api/fixtures/accounts.ts new file mode 100644 index 0000000000..4c1660c0aa --- /dev/null +++ b/qa-core/src/config/internal-api/fixtures/accounts.ts @@ -0,0 +1,17 @@ +import { Account } from "@budibase/types"; +import generator from "../../generator"; + +export const generateAccount = (): Account => { + const randomGuid = generator.guid(); + return { + email: `qa+${randomGuid}@budibase.com`, + hosting: "cloud", + name: `qa+${randomGuid}@budibase.com`, + password: `${randomGuid}`, + profession: "software_engineer", + size: "10+", + tenantId: `${randomGuid}`, + tenantName: `${randomGuid}`, + } +} + From 54ca0d1218742de75d3b33e9b43b3e009f766387 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Mon, 19 Dec 2022 18:01:59 +0000 Subject: [PATCH 003/149] Remove unused const --- qa-core/src/config/internal-api/TestConfiguration/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qa-core/src/config/internal-api/TestConfiguration/index.ts b/qa-core/src/config/internal-api/TestConfiguration/index.ts index 39a839f58d..cb5e8cdf7f 100644 --- a/qa-core/src/config/internal-api/TestConfiguration/index.ts +++ b/qa-core/src/config/internal-api/TestConfiguration/index.ts @@ -35,9 +35,9 @@ export default class TestConfiguration { async setupAccountAndTenant() { const account = generateAccount() - const [emailValidationResponse, emailValidationJson] = await this.accounts.validateEmail(account.email) - const [tenantIdValidationResponse, tenantIdValidationJson] = await this.accounts.validateTenantId(account.tenantId) - const [accountCreationResponse, accountCreationJson] = await this.accounts.create(account) + await this.accounts.validateEmail(account.email) + await this.accounts.validateTenantId(account.tenantId) + await this.accounts.create(account) await this.auth.login(account.email, account.password) } From c2dab0a60bccf6c6abfc1cabbcd0d542df1a0d8a Mon Sep 17 00:00:00 2001 From: Dean Date: Tue, 3 Jan 2023 16:04:11 +0000 Subject: [PATCH 004/149] Refactored the create/edit column UI, fixed auto column validation issues and some other bugs --- .../DataTable/modals/CreateEditColumn.svelte | 312 +++++++++++------- .../data/table/[selectedTable]/index.svelte | 46 +++ 2 files changed, 246 insertions(+), 112 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte index 960283842d..7266318691 100644 --- a/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte +++ b/packages/builder/src/components/backend/DataTable/modals/CreateEditColumn.svelte @@ -12,7 +12,7 @@ Modal, notifications, } from "@budibase/bbui" - import { createEventDispatcher, onMount } from "svelte" + import { createEventDispatcher } from "svelte" import { cloneDeep } from "lodash/fp" import { tables, datasources } from "stores/backend" import { TableNames, UNEDITABLE_USER_FIELDS } from "constants" @@ -48,7 +48,22 @@ const { hide } = getContext(Context.Modal) let fieldDefinitions = cloneDeep(FIELDS) - export let field = { + export let field + + let originalName + let linkEditDisabled + let primaryDisplay + let indexes = [...($tables.selected.indexes || [])] + let isCreating + + let table = $tables.selected + let confirmDeleteDialog + let deletion + let savingColumn + let deleteColName + let jsonSchemaModal + + let editableColumn = { type: "string", constraints: fieldDefinitions.STRING.constraints, @@ -56,48 +71,80 @@ fieldName: $tables.selected.name, } - let originalName = field.name - const linkEditDisabled = originalName != null - let primaryDisplay = - $tables.selected.primaryDisplay == null || - $tables.selected.primaryDisplay === field.name - let isCreating = originalName == null + $: if (primaryDisplay) { + editableColumn.constraints.presence = { allowEmpty: false } + } - let table = $tables.selected - let indexes = [...($tables.selected.indexes || [])] - let confirmDeleteDialog - let deletion - let deleteColName - let jsonSchemaModal + $: if (field && !savingColumn) { + editableColumn = cloneDeep(field) + originalName = editableColumn.name ? editableColumn.name + "" : null + linkEditDisabled = originalName != null + isCreating = originalName == null + primaryDisplay = + $tables.selected.primaryDisplay == null || + $tables.selected.primaryDisplay === editableColumn.name + } - $: checkConstraints(field) - $: required = !!field?.constraints?.presence || primaryDisplay + $: checkConstraints(editableColumn) + $: required = !!editableColumn?.constraints?.presence || primaryDisplay $: uneditable = $tables.selected?._id === TableNames.USERS && - UNEDITABLE_USER_FIELDS.includes(field.name) + UNEDITABLE_USER_FIELDS.includes(editableColumn.name) $: invalid = - !field.name || - (field.type === LINK_TYPE && !field.tableId) || + !editableColumn?.name || + (editableColumn?.type === LINK_TYPE && !editableColumn?.tableId) || Object.keys(errors).length !== 0 - $: errors = checkErrors(field) + $: errors = checkErrors(editableColumn) $: datasource = $datasources.list.find( source => source._id === table?.sourceId ) + const getTableAutoColumnTypes = table => { + return Object.keys(table?.schema).reduce((acc, key) => { + let fieldSchema = table?.schema[key] + if (fieldSchema.autocolumn) { + acc.push(fieldSchema.subtype) + } + return acc + }, []) + } + + let autoColumnInfo = getAutoColumnInformation() + + $: tableAutoColumnsTypes = getTableAutoColumnTypes($tables?.selected) + $: availableAutoColumns = Object.keys(autoColumnInfo).reduce((acc, key) => { + if (!tableAutoColumnsTypes.includes(key)) { + acc[key] = autoColumnInfo[key] + } + return acc + }, {}) + + $: availableAutoColumnKeys = availableAutoColumns + ? Object.keys(availableAutoColumns) + : [] + + $: autoColumnOptions = editableColumn.autocolumn + ? autoColumnInfo + : availableAutoColumns + // used to select what different options can be displayed for column type $: canBeSearched = - field.type !== LINK_TYPE && - field.type !== JSON_TYPE && - field.subtype !== AUTO_COLUMN_SUB_TYPES.CREATED_BY && - field.subtype !== AUTO_COLUMN_SUB_TYPES.UPDATED_BY && - field.type !== FORMULA_TYPE + editableColumn?.type !== LINK_TYPE && + editableColumn?.type !== JSON_TYPE && + editableColumn?.subtype !== AUTO_COLUMN_SUB_TYPES.CREATED_BY && + editableColumn?.subtype !== AUTO_COLUMN_SUB_TYPES.UPDATED_BY && + editableColumn?.type !== FORMULA_TYPE && + !editableColumn.autocolumn $: canBeDisplay = - field.type !== LINK_TYPE && - field.type !== AUTO_TYPE && - field.type !== JSON_TYPE + editableColumn?.type !== LINK_TYPE && + editableColumn?.type !== AUTO_TYPE && + (editableColumn?.type !== JSON_TYPE) & !editableColumn.autocolumn $: canBeRequired = - field.type !== LINK_TYPE && !uneditable && field.type !== AUTO_TYPE - $: relationshipOptions = getRelationshipOptions(field) + editableColumn?.type !== LINK_TYPE && + !uneditable && + editableColumn?.type !== AUTO_TYPE && + !editableColumn.autocolumn + $: relationshipOptions = getRelationshipOptions(editableColumn) $: external = table.type === "external" // in the case of internal tables the sourceId will just be undefined $: tableOptions = $tables.list.filter( @@ -108,76 +155,90 @@ ) $: typeEnabled = !originalName || - (originalName && SWITCHABLE_TYPES.indexOf(field.type) !== -1) + (originalName && + SWITCHABLE_TYPES.indexOf(editableColumn.type) !== -1 && + !editableColumn?.autocolumn) async function saveColumn() { - if (field.type === AUTO_TYPE) { - field = buildAutoColumn($tables.draft.name, field.name, field.subtype) + savingColumn = true + if (errors?.length) { + return } - if (field.type !== LINK_TYPE) { - delete field.fieldName + + let saveColumn = cloneDeep(editableColumn) + + if (saveColumn.type === AUTO_TYPE) { + saveColumn = buildAutoColumn( + $tables.draft.name, + saveColumn.name, + saveColumn.subtype + ) + } + if (saveColumn.type !== LINK_TYPE) { + delete saveColumn.fieldName } try { await tables.saveField({ originalName, - field, + field: saveColumn, primaryDisplay, indexes, }) dispatch("updatecolumns") } catch (err) { - notifications.error("Error saving column") + console.log(err) + notifications.error(`Error saving column: ${err.message}`) } } function cancelEdit() { - field.name = originalName + editableColumn.name = originalName } function deleteColumn() { try { - field.name = deleteColName - if (field.name === $tables.selected.primaryDisplay) { + editableColumn.name = deleteColName + if (editableColumn.name === $tables.selected.primaryDisplay) { notifications.error("You cannot delete the display column") } else { - tables.deleteField(field) - notifications.success(`Column ${field.name} deleted.`) + tables.deleteField(editableColumn) + notifications.success(`Column ${editableColumn.name} deleted.`) confirmDeleteDialog.hide() hide() deletion = false dispatch("updatecolumns") } } catch (error) { - notifications.error("Error deleting column") + notifications.error(`Error deleting column: ${error.message}`) } } function handleTypeChange(event) { // remove any extra fields that may not be related to this type - delete field.autocolumn - delete field.subtype - delete field.tableId - delete field.relationshipType - delete field.formulaType + delete editableColumn.autocolumn + delete editableColumn.subtype + delete editableColumn.tableId + delete editableColumn.relationshipType + delete editableColumn.formulaType // Add in defaults and initial definition const definition = fieldDefinitions[event.detail?.toUpperCase()] if (definition?.constraints) { - field.constraints = definition.constraints + editableColumn.constraints = definition.constraints } // Default relationships many to many - if (field.type === LINK_TYPE) { - field.relationshipType = RelationshipTypes.MANY_TO_MANY + if (editableColumn.type === LINK_TYPE) { + editableColumn.relationshipType = RelationshipTypes.MANY_TO_MANY } - if (field.type === FORMULA_TYPE) { - field.formulaType = "dynamic" + if (editableColumn.type === FORMULA_TYPE) { + editableColumn.formulaType = "dynamic" } } function onChangeRequired(e) { const req = e.detail - field.constraints.presence = req ? { allowEmpty: false } : false + editableColumn.constraints.presence = req ? { allowEmpty: false } : false required = req } @@ -185,17 +246,17 @@ const isPrimary = e.detail // primary display is always required if (isPrimary) { - field.constraints.presence = { allowEmpty: false } + editableColumn.constraints.presence = { allowEmpty: false } } } function onChangePrimaryIndex(e) { - indexes = e.detail ? [field.name] : [] + indexes = e.detail ? [editableColumn.name] : [] } function onChangeSecondaryIndex(e) { if (e.detail) { - indexes[1] = field.name + indexes[1] = editableColumn.name } else { indexes = indexes.slice(0, 1) } @@ -246,11 +307,14 @@ } function getAllowedTypes() { - if (originalName && ALLOWABLE_STRING_TYPES.indexOf(field.type) !== -1) { + if ( + originalName && + ALLOWABLE_STRING_TYPES.indexOf(editableColumn.type) !== -1 + ) { return ALLOWABLE_STRING_OPTIONS } else if ( originalName && - ALLOWABLE_NUMBER_TYPES.indexOf(field.type) !== -1 + ALLOWABLE_NUMBER_TYPES.indexOf(editableColumn.type) !== -1 ) { return ALLOWABLE_NUMBER_OPTIONS } else if (!external) { @@ -275,6 +339,9 @@ } function checkConstraints(fieldToCheck) { + if (!fieldToCheck) { + return + } // most types need this, just make sure its always present if (fieldToCheck && !fieldToCheck.constraints) { fieldToCheck.constraints = {} @@ -296,10 +363,16 @@ } function checkErrors(fieldInfo) { + if (!editableColumn) { + return {} + } function inUse(tbl, column, ogName = null) { - return Object.keys(tbl?.schema || {}).some( - key => key !== ogName && key === column - ) + const parsedColumn = column ? column.toLowerCase().trim() : column + + return Object.keys(tbl?.schema || {}).some(key => { + let lowerKey = key.toLowerCase() + return lowerKey !== ogName?.toLowerCase() && lowerKey === parsedColumn + }) } const newError = {} if (!external && fieldInfo.name?.startsWith("_")) { @@ -313,6 +386,11 @@ } else if (inUse($tables.draft, fieldInfo.name, originalName)) { newError.name = `Column name already in use.` } + + if (fieldInfo.type == "auto" && !fieldInfo.subtype) { + newError.subtype = `Auto Column requires a type` + } + if (fieldInfo.fieldName && fieldInfo.tableId) { const relatedTable = $tables.list.find( tbl => tbl._id === fieldInfo.tableId @@ -323,12 +401,6 @@ } return newError } - - onMount(() => { - if (primaryDisplay) { - field.constraints.presence = { allowEmpty: false } - } - }) - {:else if field.type === "options"} + {:else if editableColumn.type === "options"} - {:else if field.type === "longform"} + {:else if editableColumn.type === "longform"}
- {:else if field.type === "array"} + {:else if editableColumn.type === "array"} - {:else if field.type === "datetime"} + {:else if editableColumn.type === "datetime" && !editableColumn.autocolumn} + - {#if datasource?.source !== "ORACLE" && datasource?.source !== "SQL_SERVER"}
- +
{/if} - {:else if field.type === "number"} + {:else if editableColumn.type === "number" && !editableColumn.autocolumn} - {:else if field.type === "link"} + {:else if editableColumn.type === "link"} - {:else if field.type === FORMULA_TYPE} + {:else if editableColumn.type === FORMULA_TYPE} {#if !table.sql} (field.subtype = e.detail)} - options={Object.entries(getAutoColumnInformation())} - getOptionLabel={option => option[1].name} - getOptionValue={option => option[0]} - /> - {:else if field.type === JSON_TYPE} + {:else if editableColumn.type === JSON_TYPE} {/if} + {#if editableColumn.type === AUTO_TYPE || editableColumn.autocolumn} + { - fromColumn = tableOptions.find(opt => opt.value === e.detail)?.label || "" - if (errors.fromTable === relationshipAlreadyExists) { - errors.toColumn = null - } - errors.fromTable = null - errors.fromColumn = null - errors.toTable = null - errors.throughTable = null - }} - /> + {#if !selectedFromTable} + (errors.fromPrimary = null)} + on:change={changed} /> {/if} { - errors.fromTable = null - errors.toTable = null - errors.throughTable = null - }} + on:change={() => + changed(() => { + throughToKey = null + throughFromKey = null + })} /> {#if fromTable && toTable && throughTable} { - if (throughToKey === e.detail) { - throughToKey = null - } - errors.throughFromKey = null - }} + on:change={e => + changed(() => { + if (throughToKey === e.detail) { + throughToKey = null + } + })} /> {/if} {:else if isManyToOne && toTable} @@ -445,7 +428,7 @@ options={Object.keys(toTable?.schema)} bind:value={fromForeign} bind:error={errors.fromForeign} - on:change={() => (errors.fromForeign = null)} + on:change={changed} /> {/if}
@@ -459,15 +442,13 @@ label="From table column" bind:value={fromColumn} bind:error={errors.fromColumn} - on:change={e => { - errors.fromColumn = e.detail?.length > 0 ? null : colNotSet - }} + on:change={changed} /> (errors.toColumn = e.detail?.length > 0 ? null : colNotSet)} + on:change={changed} />
{#if originalFromColumnName != null} diff --git a/packages/builder/src/components/backend/Datasources/relationshipErrors.js b/packages/builder/src/components/backend/Datasources/relationshipErrors.js new file mode 100644 index 0000000000..71fb634ada --- /dev/null +++ b/packages/builder/src/components/backend/Datasources/relationshipErrors.js @@ -0,0 +1,86 @@ +import { RelationshipTypes } from "constants/backend" + +export const typeMismatch = + "Column type of the foreign key must match the primary key" +export const columnCantExist = "Column name cannot be an existing column" +export const mustBeDifferentTables = "From/to/through tables must be different" +export const primaryKeyNotSet = "Please pick the primary key" +export const throughNotNullable = + "Ensure non-key columns are nullable or auto-generated" +export const noRelationshipType = "Please specify a relationship type" +export const tableNotSet = "Please specify a table" +export const foreignKeyNotSet = "Please pick a foreign key" +export const relationshipAlreadyExists = + "A relationship between these tables already exists" + +function isColumnNameBeingUsed(table, columnName, originalName) { + if (!table || !columnName || columnName === originalName) { + return false + } + const keys = Object.keys(table.schema).map(key => key.toLowerCase()) + return keys.indexOf(columnName.toLowerCase()) !== -1 +} + +export class RelationshipErrorChecker { + constructor(invalidThroughTableFn, relationshipExistsFn) { + this.invalidThroughTable = invalidThroughTableFn + this.relationshipExists = relationshipExistsFn + } + + setType(type) { + this.type = type + } + + isMany() { + return this.type === RelationshipTypes.MANY_TO_MANY + } + + relationshipTypeSet(type) { + return !type ? noRelationshipType : null + } + + tableSet(table) { + return !table ? tableNotSet : null + } + + throughTableSet(table) { + return this.isMany() && !table ? tableNotSet : null + } + + manyForeignKeySet(key) { + return this.isMany() && !key ? foreignKeyNotSet : null + } + + foreignKeySet(key) { + return !this.isMany() && !key ? foreignKeyNotSet : null + } + + throughIsNullable() { + return this.invalidThroughTable() ? throughNotNullable : null + } + + doesRelationshipExists() { + return this.isMany() && this.relationshipExists() + ? relationshipAlreadyExists + : null + } + + differentTables(table1, table2, table3) { + // currently don't support relationships back onto the table itself, needs to relate out + const error = table1 && (table1 === table2 || (table3 && table1 === table3)) + return error ? mustBeDifferentTables : null + } + + columnBeingUsed(table, column, ogName) { + return isColumnNameBeingUsed(table, column, ogName) ? columnCantExist : null + } + + typeMismatch(fromTable, toTable, primary, foreign) { + let fromType, toType + if (primary && foreign) { + fromType = fromTable?.schema[primary]?.type + toType = toTable?.schema[foreign]?.type + } + return fromType && toType && fromType !== toType ? typeMismatch : null + } +} From 049d4a03635befba507a5fceccdbe91f79276467 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 1 Feb 2023 19:10:41 +0000 Subject: [PATCH 070/149] Removing console log. --- .../components/backend/Datasources/CreateEditRelationship.svelte | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 68b51ef3a1..1901053564 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -176,7 +176,6 @@ fromPrimary, fromForeign ) - console.log(errObj) errors = errObj return getErrorCount(errors) === 0 } From ab66378fbf925cb63da9c68e659bb912bdf11213 Mon Sep 17 00:00:00 2001 From: mike12345567 Date: Wed, 1 Feb 2023 19:26:26 +0000 Subject: [PATCH 071/149] Some final updates, clean up some code that could be causing reactive issues. --- .../Datasources/CreateEditRelationship.svelte | 136 ++++++++---------- .../backend/Datasources/relationshipErrors.js | 23 +-- 2 files changed, 72 insertions(+), 87 deletions(-) diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index 1901053564..57ac41a093 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -62,65 +62,18 @@ let isManyToMany, isManyToOne, relationshipType let hasValidated = false - $: { - if (!fromPrimary) { - fromPrimary = fromRelationship.foreignKey - } - if (!fromForeign) { - fromForeign = toRelationship.foreignKey - } - if (!fromColumn && !errors.fromColumn) { - fromColumn = toRelationship.name - } - if (!toColumn && !errors.toColumn) { - toColumn = fromRelationship.name - } - if (!fromId) { - fromId = toRelationship.tableId - } - if (!toId) { - toId = fromRelationship.tableId - } - if (!throughId) { - throughId = fromRelationship.through - throughFromKey = fromRelationship.throughFrom - throughToKey = fromRelationship.throughTo - } - if (!relationshipType) { - relationshipType = - fromRelationship.relationshipType || RelationshipTypes.MANY_TO_ONE - } - } - $: tableOptions = plusTables.map(table => ({ label: table.name, value: table._id, })) $: valid = getErrorCount(errors) === 0 && allRequiredAttributesSet() - $: isManyToMany = relationshipType === RelationshipTypes.MANY_TO_MANY $: isManyToOne = relationshipType === RelationshipTypes.MANY_TO_ONE $: fromTable = plusTables.find(table => table._id === fromId) $: toTable = plusTables.find(table => table._id === toId) $: throughTable = plusTables.find(table => table._id === throughId) - $: toRelationship.relationshipType = fromRelationship?.relationshipType - function getErrorCount(errors) { - return Object.entries(errors) - .filter(entry => !!entry[1]) - .map(entry => entry[0]).length - } - - function allRequiredAttributesSet() { - const base = fromTable && toTable && fromColumn && toColumn - if (isManyToOne) { - return base && fromPrimary && fromForeign - } else { - return base && throughTable && throughFromKey && throughToKey - } - } - function invalidThroughTable() { // need to know the foreign key columns to check error if (!throughId || !throughToKey || !throughFromKey) { @@ -137,6 +90,49 @@ } return false } + function relationshipExists() { + if ( + originalFromTable && + originalToTable && + originalFromTable === fromTable && + originalToTable === toTable + ) { + return false + } + let fromThroughLinks = Object.values( + datasource.entities[fromTable.name].schema + ).filter(value => value.through) + let toThroughLinks = Object.values( + datasource.entities[toTable.name].schema + ).filter(value => value.through) + + const matchAgainstUserInput = (fromTableId, toTableId) => + (fromTableId === fromId && toTableId === toId) || + (fromTableId === toId && toTableId === fromId) + + return !!fromThroughLinks.find(from => + toThroughLinks.find( + to => + from.through === to.through && + matchAgainstUserInput(from.tableId, to.tableId) + ) + ) + } + + function getErrorCount(errors) { + return Object.entries(errors) + .filter(entry => !!entry[1]) + .map(entry => entry[0]).length + } + + function allRequiredAttributesSet() { + const base = fromTable && toTable && fromColumn && toColumn + if (isManyToOne) { + return base && fromPrimary && fromForeign + } else { + return base && throughTable && throughFromKey && throughToKey + } + } function validate() { if (!allRequiredAttributesSet() && !hasValidated) { @@ -153,7 +149,7 @@ errObj.throughToKey = errorChecker.manyForeignKeySet(throughToKey) errObj.throughTable = errorChecker.throughIsNullable() errObj.fromForeign = errorChecker.foreignKeySet(fromForeign) - errObj.fromPrimary = errorChecker.foreignKeySet(fromPrimary) + errObj.fromPrimary = errorChecker.primaryKeySet(fromPrimary) errObj.fromTable = errorChecker.doesRelationshipExists() errObj.toTable = errorChecker.doesRelationshipExists() // currently don't support relationships back onto the table itself, needs to relate out @@ -252,35 +248,6 @@ toRelationship = relateTo } - function relationshipExists() { - if ( - originalFromTable && - originalToTable && - originalFromTable === fromTable && - originalToTable === toTable - ) { - return false - } - let fromThroughLinks = Object.values( - datasource.entities[fromTable.name].schema - ).filter(value => value.through) - let toThroughLinks = Object.values( - datasource.entities[toTable.name].schema - ).filter(value => value.through) - - const matchAgainstUserInput = (fromTableId, toTableId) => - (fromTableId === fromId && toTableId === toId) || - (fromTableId === toId && toTableId === fromId) - - return !!fromThroughLinks.find(from => - toThroughLinks.find( - to => - from.through === to.through && - matchAgainstUserInput(from.tableId, to.tableId) - ) - ) - } - function removeExistingRelationship() { if (originalFromTable && originalFromColumnName) { delete datasource.entities[originalFromTable.name].schema[ @@ -325,6 +292,21 @@ } onMount(() => { + if (fromRelationship) { + fromPrimary = fromRelationship.foreignKey + toId = fromRelationship.tableId + throughId = fromRelationship.through + throughFromKey = fromRelationship.throughFrom + throughToKey = fromRelationship.throughTo + toColumn = fromRelationship.name + } + if (toRelationship) { + fromForeign = toRelationship.foreignKey + fromId = toRelationship.tableId + fromColumn = toRelationship.name + } + relationshipType = + fromRelationship.relationshipType || RelationshipTypes.MANY_TO_ONE if (selectedFromTable) { fromColumn = selectedFromTable.name fromPrimary = selectedFromTable?.primary[0] || null diff --git a/packages/builder/src/components/backend/Datasources/relationshipErrors.js b/packages/builder/src/components/backend/Datasources/relationshipErrors.js index 71fb634ada..cdb7805506 100644 --- a/packages/builder/src/components/backend/Datasources/relationshipErrors.js +++ b/packages/builder/src/components/backend/Datasources/relationshipErrors.js @@ -1,16 +1,15 @@ import { RelationshipTypes } from "constants/backend" -export const typeMismatch = - "Column type of the foreign key must match the primary key" -export const columnCantExist = "Column name cannot be an existing column" -export const mustBeDifferentTables = "From/to/through tables must be different" -export const primaryKeyNotSet = "Please pick the primary key" -export const throughNotNullable = +const typeMismatch = "Column type of the foreign key must match the primary key" +const columnCantExist = "Column name cannot be an existing column" +const mustBeDifferentTables = "From/to/through tables must be different" +const primaryKeyNotSet = "Please pick the primary key" +const throughNotNullable = "Ensure non-key columns are nullable or auto-generated" -export const noRelationshipType = "Please specify a relationship type" -export const tableNotSet = "Please specify a table" -export const foreignKeyNotSet = "Please pick a foreign key" -export const relationshipAlreadyExists = +const noRelationshipType = "Please specify a relationship type" +const tableNotSet = "Please specify a table" +const foreignKeyNotSet = "Please pick a foreign key" +const relationshipAlreadyExists = "A relationship between these tables already exists" function isColumnNameBeingUsed(table, columnName, originalName) { @@ -55,6 +54,10 @@ export class RelationshipErrorChecker { return !this.isMany() && !key ? foreignKeyNotSet : null } + primaryKeySet(key) { + return !this.isMany() && !key ? primaryKeyNotSet : null + } + throughIsNullable() { return this.invalidThroughTable() ? throughNotNullable : null } From 71292d3786286aa4e3391e4e647d119ccda46808 Mon Sep 17 00:00:00 2001 From: Rory Powell Date: Thu, 2 Feb 2023 09:26:39 +0000 Subject: [PATCH 072/149] Fix server build by removing unused dependency on file path in backend-core --- packages/server/src/integrations/couchdb.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/server/src/integrations/couchdb.ts b/packages/server/src/integrations/couchdb.ts index 4da2253c77..257b84ca13 100644 --- a/packages/server/src/integrations/couchdb.ts +++ b/packages/server/src/integrations/couchdb.ts @@ -6,7 +6,6 @@ import { QueryType, } from "@budibase/types" import { db as dbCore } from "@budibase/backend-core" -import { DatabaseWithConnection } from "@budibase/backend-core/src/db" interface CouchDBConfig { url: string From e1d9f5d6bd991c683b08ecd939cbda2eb3535c52 Mon Sep 17 00:00:00 2001 From: Pedro Silva Date: Thu, 2 Feb 2023 09:41:46 +0000 Subject: [PATCH 073/149] Skip tests that need multiple users authenticated --- .../internal-api/userManagement/customRoles.spec.ts | 13 ++++++------- .../userManagement/screenAccess.spec.ts | 9 ++++----- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/qa-core/src/tests/internal-api/userManagement/customRoles.spec.ts b/qa-core/src/tests/internal-api/userManagement/customRoles.spec.ts index a6f7533825..d672bc0eb2 100644 --- a/qa-core/src/tests/internal-api/userManagement/customRoles.spec.ts +++ b/qa-core/src/tests/internal-api/userManagement/customRoles.spec.ts @@ -8,7 +8,7 @@ import { App, User } from "@budibase/types" import generateScreen from "../../../config/internal-api/fixtures/screens" import { db } from "@budibase/backend-core" -describe("Internal API - App Specific Roles & Permissions", () => { +describe.skip("Internal API - App Specific Roles & Permissions", () => { let api: InternalAPIClient let accountsAPI: AccountsAPIClient let config: TestConfiguration @@ -82,14 +82,13 @@ describe("Internal API - App Specific Roles & Permissions", () => { const [selfInfoResponse, selfInfoJson] = await config.users.getSelf() // fetch app package - /* + const [appPackageResponse, appPackageJson] = await config.applications.getAppPackage(app.appId!) expect(appPackageJson.screens).toBeDefined() expect(appPackageJson.screens.length).toEqual(1) - */ }) - it.skip("Custom role access for level 2 permissions", async () => { + it("Custom role access for level 2 permissions", async () => { // Set up user const appUser = generateUser() expect(appUser[0].builder?.global).toEqual(false) @@ -150,7 +149,7 @@ describe("Internal API - App Specific Roles & Permissions", () => { expect(appPackageJson.screens).toBeDefined() expect(appPackageJson.screens.length).toEqual(1) }) - it.skip("Custom role access for level 3 permissions", async () => { + it("Custom role access for level 3 permissions", async () => { const appUser = generateUser() expect(appUser[0].builder?.global).toEqual(false) expect(appUser[0].admin?.global).toEqual(false) @@ -210,7 +209,7 @@ describe("Internal API - App Specific Roles & Permissions", () => { expect(appPackageJson.screens).toBeDefined() expect(appPackageJson.screens.length).toEqual(1) }) - it.skip("Custom role access for level 4 permissions", async () => { + it("Custom role access for level 4 permissions", async () => { const appUser = generateUser() expect(appUser[0].builder?.global).toEqual(false) expect(appUser[0].admin?.global).toEqual(false) @@ -270,7 +269,7 @@ describe("Internal API - App Specific Roles & Permissions", () => { expect(appPackageJson.screens).toBeDefined() expect(appPackageJson.screens.length).toEqual(1) }) - it.skip("Custom role access for level 5 permissions", async () => { + it("Custom role access for level 5 permissions", async () => { const appUser = generateUser() expect(appUser[0].builder?.global).toEqual(false) expect(appUser[0].admin?.global).toEqual(false) diff --git a/qa-core/src/tests/internal-api/userManagement/screenAccess.spec.ts b/qa-core/src/tests/internal-api/userManagement/screenAccess.spec.ts index d7f73bc3f5..26f9d25ff0 100644 --- a/qa-core/src/tests/internal-api/userManagement/screenAccess.spec.ts +++ b/qa-core/src/tests/internal-api/userManagement/screenAccess.spec.ts @@ -8,7 +8,7 @@ import { User } from "@budibase/types" import generateScreen from "../../../config/internal-api/fixtures/screens" import { db } from "@budibase/backend-core" -describe("Internal API - Role screen access", () => { +describe.skip("Internal API - Role screen access", () => { let api: InternalAPIClient let accountsAPI: AccountsAPIClient let config: TestConfiguration @@ -73,16 +73,15 @@ describe("Internal API - Role screen access", () => { const [selfInfoResponse, selfInfoJson] = await config.users.getSelf() // fetch app package - /* + const [appPackageResponse, appPackageJson] = await config.applications.getAppPackage(app.appId!) expect(appPackageJson.screens).toBeDefined() expect(appPackageJson.screens.length).toEqual(1) expect(appPackageJson.screens[0].routing.roleId).toEqual("BASIC") - */ }) - it.skip("Check Screen access for POWER role", async () => { + it("Check Screen access for POWER role", async () => { // Set up user const appUser = generateUser() expect(appUser[0].builder?.global).toEqual(false) @@ -136,7 +135,7 @@ describe("Internal API - Role screen access", () => { expect(appPackageJson.screens.length).toEqual(2) }) - it.skip("Check Screen access for ADMIN role", async () => { + it("Check Screen access for ADMIN role", async () => { // Set up user const appUser = generateUser() expect(appUser[0].builder?.global).toEqual(false) From 3489cb312c0846d4c3c70f60380bc3fceab0a680 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 2 Feb 2023 09:43:29 +0000 Subject: [PATCH 074/149] v2.2.12-alpha.62 --- lerna.json | 2 +- packages/backend-core/package.json | 4 ++-- packages/bbui/package.json | 4 ++-- packages/builder/package.json | 10 +++++----- packages/cli/package.json | 8 ++++---- packages/client/package.json | 8 ++++---- packages/frontend-core/package.json | 4 ++-- packages/sdk/package.json | 2 +- packages/server/package.json | 10 +++++----- packages/string-templates/package.json | 2 +- packages/types/package.json | 2 +- packages/worker/package.json | 8 ++++---- 12 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lerna.json b/lerna.json index 964839467a..2374661f57 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 1257f7567c..38733444d1 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -23,7 +23,7 @@ }, "dependencies": { "@budibase/nano": "10.1.1", - "@budibase/types": "2.2.12-alpha.61", + "@budibase/types": "2.2.12-alpha.62", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-cloudfront-sign": "2.2.0", diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 8b5cb63708..a9938b1348 100644 --- a/packages/bbui/package.json +++ b/packages/bbui/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/bbui", "description": "A UI solution used in the different Budibase projects.", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "license": "MPL-2.0", "svelte": "src/index.js", "module": "dist/bbui.es.js", @@ -38,7 +38,7 @@ ], "dependencies": { "@adobe/spectrum-css-workflow-icons": "1.2.1", - "@budibase/string-templates": "2.2.12-alpha.61", + "@budibase/string-templates": "2.2.12-alpha.62", "@spectrum-css/accordion": "3.0.24", "@spectrum-css/actionbutton": "1.0.1", "@spectrum-css/actiongroup": "1.0.1", diff --git a/packages/builder/package.json b/packages/builder/package.json index 39df0bb4eb..4087d5f1fb 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "license": "GPL-3.0", "private": true, "scripts": { @@ -58,10 +58,10 @@ } }, "dependencies": { - "@budibase/bbui": "2.2.12-alpha.61", - "@budibase/client": "2.2.12-alpha.61", - "@budibase/frontend-core": "2.2.12-alpha.61", - "@budibase/string-templates": "2.2.12-alpha.61", + "@budibase/bbui": "2.2.12-alpha.62", + "@budibase/client": "2.2.12-alpha.62", + "@budibase/frontend-core": "2.2.12-alpha.62", + "@budibase/string-templates": "2.2.12-alpha.62", "@fortawesome/fontawesome-svg-core": "^6.2.1", "@fortawesome/free-brands-svg-icons": "^6.2.1", "@fortawesome/free-solid-svg-icons": "^6.2.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index 3cca426ce3..d87504f40a 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "description": "Budibase CLI, for developers, self hosting and migrations.", "main": "src/index.js", "bin": { @@ -26,9 +26,9 @@ "outputPath": "build" }, "dependencies": { - "@budibase/backend-core": "2.2.12-alpha.61", - "@budibase/string-templates": "2.2.12-alpha.61", - "@budibase/types": "2.2.12-alpha.61", + "@budibase/backend-core": "2.2.12-alpha.62", + "@budibase/string-templates": "2.2.12-alpha.62", + "@budibase/types": "2.2.12-alpha.62", "axios": "0.21.2", "chalk": "4.1.0", "cli-progress": "3.11.2", diff --git a/packages/client/package.json b/packages/client/package.json index 30852e0e33..4af40aadb1 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "license": "MPL-2.0", "module": "dist/budibase-client.js", "main": "dist/budibase-client.js", @@ -19,9 +19,9 @@ "dev:builder": "rollup -cw" }, "dependencies": { - "@budibase/bbui": "2.2.12-alpha.61", - "@budibase/frontend-core": "2.2.12-alpha.61", - "@budibase/string-templates": "2.2.12-alpha.61", + "@budibase/bbui": "2.2.12-alpha.62", + "@budibase/frontend-core": "2.2.12-alpha.62", + "@budibase/string-templates": "2.2.12-alpha.62", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index f33c100b62..2b74865ff6 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "2.2.12-alpha.61", + "@budibase/bbui": "2.2.12-alpha.62", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 0922cd33fe..bfad1b5dd0 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/sdk", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "description": "Budibase Public API SDK", "author": "Budibase", "license": "MPL-2.0", diff --git a/packages/server/package.json b/packages/server/package.json index e8d080dc87..9df3753a97 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -43,11 +43,11 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@budibase/backend-core": "2.2.12-alpha.61", - "@budibase/client": "2.2.12-alpha.61", + "@budibase/backend-core": "2.2.12-alpha.62", + "@budibase/client": "2.2.12-alpha.62", "@budibase/pro": "2.2.12-alpha.61", - "@budibase/string-templates": "2.2.12-alpha.61", - "@budibase/types": "2.2.12-alpha.61", + "@budibase/string-templates": "2.2.12-alpha.62", + "@budibase/types": "2.2.12-alpha.62", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index fe6aee43a0..25523d3aa6 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "description": "Handlebars wrapper for Budibase templating.", "main": "src/index.cjs", "module": "dist/bundle.mjs", diff --git a/packages/types/package.json b/packages/types/package.json index add3be53f8..6ff9a0d8c7 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "description": "Budibase types", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/worker/package.json b/packages/worker/package.json index 8424f50e93..7427028591 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "2.2.12-alpha.61", + "version": "2.2.12-alpha.62", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -36,10 +36,10 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "2.2.12-alpha.61", + "@budibase/backend-core": "2.2.12-alpha.62", "@budibase/pro": "2.2.12-alpha.61", - "@budibase/string-templates": "2.2.12-alpha.61", - "@budibase/types": "2.2.12-alpha.61", + "@budibase/string-templates": "2.2.12-alpha.62", + "@budibase/types": "2.2.12-alpha.62", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", From 9eaa7b787a6f6406c4c34540a69624cc5cf5f8f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Feb 2023 09:45:20 +0000 Subject: [PATCH 075/149] Bump http-cache-semantics from 4.1.0 to 4.1.1 in /packages/backend-core Bumps [http-cache-semantics](https://github.com/kornelski/http-cache-semantics) from 4.1.0 to 4.1.1. - [Release notes](https://github.com/kornelski/http-cache-semantics/releases) - [Commits](https://github.com/kornelski/http-cache-semantics/commits) --- updated-dependencies: - dependency-name: http-cache-semantics dependency-type: indirect ... Signed-off-by: dependabot[bot] --- packages/backend-core/yarn.lock | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/packages/backend-core/yarn.lock b/packages/backend-core/yarn.lock index b288cc521b..c1ec890e92 100644 --- a/packages/backend-core/yarn.lock +++ b/packages/backend-core/yarn.lock @@ -310,6 +310,11 @@ qs "^6.11.0" tough-cookie "^4.1.2" +"@budibase/types@2.2.12-alpha.62": + version "2.2.12-alpha.62" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.62.tgz#385ef000610d5c00b83cb2eafda2bd63c86b7f3f" + integrity sha512-idlhB4fSyBCEDWsVvQvdmN9Dg9VAEwxZ8TLE9pGnXIRZPg48MKXPNn5AUT9zv6cDlbQdlU2tFFF8st9b6lyLuw== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -2773,9 +2778,9 @@ http-assert@^1.3.0: http-errors "~1.8.0" http-cache-semantics@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== http-cookie-agent@^4.0.2: version "4.0.2" From 6ec098efdd85e59f8780388d7bba431e45d841a6 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 2 Feb 2023 09:47:24 +0000 Subject: [PATCH 076/149] Update pro version to 2.2.12-alpha.62 --- packages/server/package.json | 2 +- packages/server/yarn.lock | 30 +++++++++++++++--------------- packages/worker/package.json | 2 +- packages/worker/yarn.lock | 30 +++++++++++++++--------------- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/server/package.json b/packages/server/package.json index 9df3753a97..2cefd8f8ab 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -45,7 +45,7 @@ "@apidevtools/swagger-parser": "10.0.3", "@budibase/backend-core": "2.2.12-alpha.62", "@budibase/client": "2.2.12-alpha.62", - "@budibase/pro": "2.2.12-alpha.61", + "@budibase/pro": "2.2.12-alpha.62", "@budibase/string-templates": "2.2.12-alpha.62", "@budibase/types": "2.2.12-alpha.62", "@bull-board/api": "3.7.0", diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 624f7f94f1..41904ada78 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1273,13 +1273,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.2.12-alpha.61": - version "2.2.12-alpha.61" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.61.tgz#5453d8de94d8262eb39816f673bdb2d729434788" - integrity sha512-NOwZlA6jjQY5HjLujlhnWfJBWjUb7mryFD3d6tLyVuq+exf3ALZO59TE2hSsgSPTpaVTrNOSV4gwbYOev/Drsg== +"@budibase/backend-core@2.2.12-alpha.62": + version "2.2.12-alpha.62" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.62.tgz#f0ac07ab8955e7d94d4ef5cb8373050d08d0e3a1" + integrity sha512-+53SzSVmcXkKdnfhkYj5YTqZrWtSuHmmxyMFwODkJL+P+mxpxPlkF2575bT22xlq0RIgY+lkD4TDv/raS+8vnA== dependencies: "@budibase/nano" "10.1.1" - "@budibase/types" "2.2.12-alpha.61" + "@budibase/types" "2.2.12-alpha.62" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -1374,13 +1374,13 @@ qs "^6.11.0" tough-cookie "^4.1.2" -"@budibase/pro@2.2.12-alpha.61": - version "2.2.12-alpha.61" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.61.tgz#93ca762a0773950d959c9fff24325cfe93718eff" - integrity sha512-ttg6TEGTn+IX2+Uyv853wsNp9pXPZ1n9tNZC9un4jAH/edbxhCElBSNMH8gsHyqw9oOGJOkNNTzsd1IfOTckqw== +"@budibase/pro@2.2.12-alpha.62": + version "2.2.12-alpha.62" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.62.tgz#183de957109a5ea52202d71eb46c82eb8c365691" + integrity sha512-c6BROnN/qW6RVeegmja4JtUZvy030DoZfGWzapsJ+qyC4TPuSTyEG6SWBwWgk1QMrKw4MTccAWBcKrptNEzOcw== dependencies: - "@budibase/backend-core" "2.2.12-alpha.61" - "@budibase/types" "2.2.12-alpha.61" + "@budibase/backend-core" "2.2.12-alpha.62" + "@budibase/types" "2.2.12-alpha.62" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" @@ -1406,10 +1406,10 @@ svelte-apexcharts "^1.0.2" svelte-flatpickr "^3.1.0" -"@budibase/types@2.2.12-alpha.61": - version "2.2.12-alpha.61" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.61.tgz#b1f87134dccfb14a9222a1733bba6f7a5277e3f1" - integrity sha512-gbST+HYYMZ2R+eUnb1lHSoRfLI72XYxzimCaDfWVfBjYTsfQoUkkhMbse+zldUBIveLMGFETZ6MIs3k2puHqEQ== +"@budibase/types@2.2.12-alpha.62": + version "2.2.12-alpha.62" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.62.tgz#385ef000610d5c00b83cb2eafda2bd63c86b7f3f" + integrity sha512-idlhB4fSyBCEDWsVvQvdmN9Dg9VAEwxZ8TLE9pGnXIRZPg48MKXPNn5AUT9zv6cDlbQdlU2tFFF8st9b6lyLuw== "@bull-board/api@3.7.0": version "3.7.0" diff --git a/packages/worker/package.json b/packages/worker/package.json index 7427028591..72b37459a0 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -37,7 +37,7 @@ "license": "GPL-3.0", "dependencies": { "@budibase/backend-core": "2.2.12-alpha.62", - "@budibase/pro": "2.2.12-alpha.61", + "@budibase/pro": "2.2.12-alpha.62", "@budibase/string-templates": "2.2.12-alpha.62", "@budibase/types": "2.2.12-alpha.62", "@koa/router": "8.0.8", diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index d75034dee9..7622bf7df8 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -470,13 +470,13 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@2.2.12-alpha.61": - version "2.2.12-alpha.61" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.61.tgz#5453d8de94d8262eb39816f673bdb2d729434788" - integrity sha512-NOwZlA6jjQY5HjLujlhnWfJBWjUb7mryFD3d6tLyVuq+exf3ALZO59TE2hSsgSPTpaVTrNOSV4gwbYOev/Drsg== +"@budibase/backend-core@2.2.12-alpha.62": + version "2.2.12-alpha.62" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.62.tgz#f0ac07ab8955e7d94d4ef5cb8373050d08d0e3a1" + integrity sha512-+53SzSVmcXkKdnfhkYj5YTqZrWtSuHmmxyMFwODkJL+P+mxpxPlkF2575bT22xlq0RIgY+lkD4TDv/raS+8vnA== dependencies: "@budibase/nano" "10.1.1" - "@budibase/types" "2.2.12-alpha.61" + "@budibase/types" "2.2.12-alpha.62" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -521,13 +521,13 @@ qs "^6.11.0" tough-cookie "^4.1.2" -"@budibase/pro@2.2.12-alpha.61": - version "2.2.12-alpha.61" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.61.tgz#93ca762a0773950d959c9fff24325cfe93718eff" - integrity sha512-ttg6TEGTn+IX2+Uyv853wsNp9pXPZ1n9tNZC9un4jAH/edbxhCElBSNMH8gsHyqw9oOGJOkNNTzsd1IfOTckqw== +"@budibase/pro@2.2.12-alpha.62": + version "2.2.12-alpha.62" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.62.tgz#183de957109a5ea52202d71eb46c82eb8c365691" + integrity sha512-c6BROnN/qW6RVeegmja4JtUZvy030DoZfGWzapsJ+qyC4TPuSTyEG6SWBwWgk1QMrKw4MTccAWBcKrptNEzOcw== dependencies: - "@budibase/backend-core" "2.2.12-alpha.61" - "@budibase/types" "2.2.12-alpha.61" + "@budibase/backend-core" "2.2.12-alpha.62" + "@budibase/types" "2.2.12-alpha.62" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" @@ -535,10 +535,10 @@ lru-cache "^7.14.1" node-fetch "^2.6.1" -"@budibase/types@2.2.12-alpha.61": - version "2.2.12-alpha.61" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.61.tgz#b1f87134dccfb14a9222a1733bba6f7a5277e3f1" - integrity sha512-gbST+HYYMZ2R+eUnb1lHSoRfLI72XYxzimCaDfWVfBjYTsfQoUkkhMbse+zldUBIveLMGFETZ6MIs3k2puHqEQ== +"@budibase/types@2.2.12-alpha.62": + version "2.2.12-alpha.62" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.62.tgz#385ef000610d5c00b83cb2eafda2bd63c86b7f3f" + integrity sha512-idlhB4fSyBCEDWsVvQvdmN9Dg9VAEwxZ8TLE9pGnXIRZPg48MKXPNn5AUT9zv6cDlbQdlU2tFFF8st9b6lyLuw== "@cspotcode/source-map-support@^0.8.0": version "0.8.1" From 659cfd249270f9930ecf5099c53ff714c1ab3289 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 2 Feb 2023 10:06:41 +0000 Subject: [PATCH 077/149] Misc fixes and improvements (#9503) * Rewrite position dropdown helper to properly work as a svelte action, improve performance and fix bugs * Update action button styles * Update spacing on some onboarding pages and update background gradient * Prevent special characters in first app name * Fix type in onboarding tour * Default first app name and url to having a value * Update text in first app onboarding file upload * Fix double mounting of apps page causing issues and templates error * Fix null app ID when creating your first app using data upload * Fix app deletion not causing app list to be refreshed --- .../bbui/src/ActionButton/ActionButton.svelte | 2 +- .../bbui/src/Actions/position_dropdown.js | 65 +++++++++++++----- packages/bbui/src/Popover/Popover.svelte | 46 ++++++------- .../onboarding/steps/OnboardingData.svelte | 2 +- .../components/start/CreateAppModal.svelte | 1 - .../src/pages/builder/auth/forgot.svelte | 12 +++- .../src/pages/builder/auth/login.svelte | 13 ++-- .../src/pages/builder/invite/index.svelte | 3 +- .../src/pages/builder/portal/_layout.svelte | 63 +++++++++-------- .../pages/builder/portal/apps/_layout.svelte | 12 ++-- .../onboarding/_components/NamePanel.svelte | 5 ++ .../portal/apps/onboarding/index.svelte | 16 ++--- .../portal/overview/[appId]/_layout.svelte | 3 +- .../builder/portal/overview/_layout.svelte | 13 ++-- .../portal/users/groups/[groupId].svelte | 2 +- .../builder/portal/users/groups/index.svelte | 4 +- .../portal/users/users/[userId].svelte | 7 +- packages/frontend-core/assets/bg.png | Bin 1765541 -> 2360061 bytes 18 files changed, 152 insertions(+), 117 deletions(-) diff --git a/packages/bbui/src/ActionButton/ActionButton.svelte b/packages/bbui/src/ActionButton/ActionButton.svelte index a8dc989313..663128160f 100644 --- a/packages/bbui/src/ActionButton/ActionButton.svelte +++ b/packages/bbui/src/ActionButton/ActionButton.svelte @@ -86,7 +86,7 @@ } .is-selected:not(.spectrum-ActionButton--emphasized):not(.spectrum-ActionButton--quiet) { background: var(--spectrum-global-color-gray-300); - border-color: var(--spectrum-global-color-gray-700); + border-color: var(--spectrum-global-color-gray-500); } .noPadding { padding: 0; diff --git a/packages/bbui/src/Actions/position_dropdown.js b/packages/bbui/src/Actions/position_dropdown.js index d99601afeb..abc7188985 100644 --- a/packages/bbui/src/Actions/position_dropdown.js +++ b/packages/bbui/src/Actions/position_dropdown.js @@ -1,11 +1,21 @@ -export default function positionDropdown( - element, - { anchor, align, maxWidth, useAnchorWidth, offset = 5 } -) { - const update = () => { +export default function positionDropdown(element, opts) { + let resizeObserver + let latestOpts = opts + + // We need a static reference to this function so that we can properly + // clean up the scroll listener. + const scrollUpdate = () => { + updatePosition(latestOpts) + } + + // Updates the position of the dropdown + const updatePosition = opts => { + const { anchor, align, maxWidth, useAnchorWidth, offset = 5 } = opts if (!anchor) { return } + + // Compute bounds const anchorBounds = anchor.getBoundingClientRect() const elementBounds = element.getBoundingClientRect() let styles = { @@ -51,26 +61,47 @@ export default function positionDropdown( }) } + // The actual svelte action callback which creates observers on the relevant + // DOM elements + const update = newOpts => { + latestOpts = newOpts + + // Cleanup old state + if (resizeObserver) { + resizeObserver.disconnect() + } + + // Do nothing if no anchor + const { anchor } = newOpts + if (!anchor) { + return + } + + // Observe both anchor and element and resize the popover as appropriate + resizeObserver = new ResizeObserver(() => updatePosition(newOpts)) + resizeObserver.observe(anchor) + resizeObserver.observe(element) + resizeObserver.observe(document.body) + } + // Apply initial styles which don't need to change element.style.position = "absolute" element.style.zIndex = "9999" - // Observe both anchor and element and resize the popover as appropriate - const resizeObserver = new ResizeObserver(entries => { - entries.forEach(update) - }) - if (anchor) { - resizeObserver.observe(anchor) - } - resizeObserver.observe(element) - resizeObserver.observe(document.body) + // Set up a scroll listener + document.addEventListener("scroll", scrollUpdate, true) - document.addEventListener("scroll", update, true) + // Perform initial update + update(opts) return { + update, destroy() { - resizeObserver.disconnect() - document.removeEventListener("scroll", update, true) + // Cleanup + if (resizeObserver) { + resizeObserver.disconnect() + } + document.removeEventListener("scroll", scrollUpdate, true) }, } } diff --git a/packages/bbui/src/Popover/Popover.svelte b/packages/bbui/src/Popover/Popover.svelte index b873fabb80..8f6ef06591 100644 --- a/packages/bbui/src/Popover/Popover.svelte +++ b/packages/bbui/src/Popover/Popover.svelte @@ -57,30 +57,28 @@ {#if open} - {#key anchor} - -
{}, - anchor, - }} - on:keydown={handleEscape} - class="spectrum-Popover is-open" - role="presentation" - transition:fly|local={{ y: -20, duration: 200 }} - > - -
-
- {/key} + +
{}, + anchor, + }} + on:keydown={handleEscape} + class="spectrum-Popover is-open" + role="presentation" + transition:fly|local={{ y: -20, duration: 200 }} + > + +
+
{/if} diff --git a/packages/builder/src/pages/builder/auth/login.svelte b/packages/builder/src/pages/builder/auth/login.svelte index 032cf850fa..80122c23a5 100644 --- a/packages/builder/src/pages/builder/auth/login.svelte +++ b/packages/builder/src/pages/builder/auth/login.svelte @@ -66,7 +66,7 @@ - + {#if loaded} logo @@ -124,14 +124,19 @@ - diff --git a/packages/builder/src/pages/builder/invite/index.svelte b/packages/builder/src/pages/builder/invite/index.svelte index 4b786db497..35231117c4 100644 --- a/packages/builder/src/pages/builder/invite/index.svelte +++ b/packages/builder/src/pages/builder/invite/index.svelte @@ -68,7 +68,7 @@ - + logo Join {company} @@ -175,6 +175,7 @@