diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index f004e0acc5..6ace2303d9 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -6,7 +6,7 @@ labels: bug assignees: '' --- -## Checklist +**Checklist** - [ ] I have searched budibase discussions and github issues to check if my issue already exists **Hosting** diff --git a/lerna.json b/lerna.json index 61c7197554..0606169dd3 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.2.12-alpha.22", + "version": "2.2.12-alpha.32", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index bb55bedc80..ca87d6daa4 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.22", + "version": "2.2.12-alpha.32", "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.22", + "@budibase/types": "2.2.12-alpha.32", "@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 ff6d9c01e4..6b67ca77d0 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.22", + "version": "2.2.12-alpha.32", "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.22", + "@budibase/string-templates": "2.2.12-alpha.32", "@spectrum-css/actionbutton": "1.0.1", "@spectrum-css/actiongroup": "1.0.1", "@spectrum-css/avatar": "3.0.2", diff --git a/packages/bbui/src/Form/Core/Picker.svelte b/packages/bbui/src/Form/Core/Picker.svelte index 81348452c7..32cfcf3310 100644 --- a/packages/bbui/src/Form/Core/Picker.svelte +++ b/packages/bbui/src/Form/Core/Picker.svelte @@ -45,7 +45,9 @@ getOptionLabel ) - const onClick = () => { + const onClick = e => { + e.preventDefault() + e.stopPropagation() dispatch("click") if (readonly) { return @@ -88,7 +90,6 @@ class:is-open={open} aria-haspopup="listbox" on:click={onClick} - use:clickOutside={() => (open = false)} bind:this={button} > {#if fieldIcon} @@ -130,14 +131,17 @@ (open = false)} useAnchorWidth={!autoWidth} maxWidth={autoWidth ? 400 : null} > -
+
(open = false)} + > {#if autocomplete} { dispatch("open") @@ -61,7 +64,7 @@ {#if open} - +
{ - context("Auth Configuration", () => { + xcontext("Auth Configuration", () => { before(() => { cy.login() }) @@ -21,7 +21,7 @@ filterTests(["smoke", "all"], () => { cy.get("[data-cy=oidc-active]").should('not.be.checked') cy.intercept("POST", "/api/global/configs").as("updateAuth") - cy.get("button[data-cy=oidc-save]").contains("Save").click({force: true}) + cy.get("button[data-cy=oidc-save]").contains("Save").click({ force: true }) cy.wait("@updateAuth") cy.get("@updateAuth").its("response.statusCode").should("eq", 200) @@ -45,7 +45,7 @@ filterTests(["smoke", "all"], () => { cy.get("button[data-cy=oidc-save]").should("not.be.disabled"); cy.intercept("POST", "/api/global/configs").as("updateAuth") - cy.get("button[data-cy=oidc-save]").contains("Save").click({force: true}) + cy.get("button[data-cy=oidc-save]").contains("Save").click({ force: true }) cy.wait("@updateAuth") cy.get("@updateAuth").its("response.statusCode").should("eq", 200) @@ -85,11 +85,11 @@ filterTests(["smoke", "all"], () => { cy.get(".auth-form input.spectrum-Textfield-input").type("Another ") cy.get(".spectrum-Tags").find(".spectrum-Tags-item").its("length").should("eq", 6) cy.get(".spectrum-Tags-item").contains("Another") - + cy.get("button[data-cy=oidc-save]").should("not.be.disabled"); cy.intercept("POST", "/api/global/configs").as("updateAuth") - cy.get("button[data-cy=oidc-save]").contains("Save").click({force: true}) + cy.get("button[data-cy=oidc-save]").contains("Save").click({ force: true }) cy.wait("@updateAuth") cy.get("@updateAuth").its("response.statusCode").should("eq", 200) @@ -123,7 +123,7 @@ filterTests(["smoke", "all"], () => { cy.get("button[data-cy=oidc-save]").should("not.be.disabled"); cy.intercept("POST", "/api/global/configs").as("updateAuth") - cy.get("button[data-cy=oidc-save]").contains("Save").click({force: true}) + cy.get("button[data-cy=oidc-save]").contains("Save").click({ force: true }) cy.wait("@updateAuth") cy.get("@updateAuth").its("response.statusCode").should("eq", 200) @@ -144,7 +144,7 @@ filterTests(["smoke", "all"], () => { cy.get("div.content").scrollTo("bottom") - cy.get("[data-cy=restore-oidc-default-scopes]").click({force: true}) + cy.get("[data-cy=restore-oidc-default-scopes]").click({ force: true }) cy.get(".spectrum-Tags").find(".spectrum-Tags-item").its("length").should("eq", 4) diff --git a/packages/builder/cypress/integration/adminAndManagement/userSettings.spec.js b/packages/builder/cypress/integration/adminAndManagement/userSettings.spec.js index a2b0d32d02..18362031c9 100644 --- a/packages/builder/cypress/integration/adminAndManagement/userSettings.spec.js +++ b/packages/builder/cypress/integration/adminAndManagement/userSettings.spec.js @@ -3,107 +3,112 @@ const interact = require('../../support/interact') filterTests(["smoke", "all"], () => { context("User Settings Menu", () => { - + before(() => { cy.login() }) - + it("should update user information via user settings menu", () => { - const fname = "test" - const lname = "user" + const fname = "test" + const lname = "user" - cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.updateUserInformation(fname, lname) + cy.visit(`${Cypress.config().baseUrl}/builder`) + cy.updateUserInformation(fname, lname) - // Go to user info and confirm name update - cy.contains("Users").click() - cy.contains("test@test.com").click() + // Go to user info and confirm name update + cy.contains("Users").click() + cy.contains("test@test.com").click() - cy.get(interact.FIELD, { timeout: 1000 }).eq(1).within(() => { - cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).should('have.value', fname) - }) - cy.get(interact.FIELD).eq(2).within(() => { - cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).should('have.value', lname) - }) + cy.get(interact.FIELD, { timeout: 1000 }).eq(1).within(() => { + cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).should('have.value', fname) + }) + cy.get(interact.FIELD).eq(2).within(() => { + cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).should('have.value', lname) + }) }) - it("should allow copying of the users API key", () => { - cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true }) - cy.get(interact.SPECTRUM_MENU_ITEM).contains("View API key").click({ force: true }) - cy.get(interact.SPECTRUM_DIALOG_CONTENT).within(() => { - cy.get(interact.SPECTRUM_ICON).click({force: true}) - }) - // There may be timing issues with this on the smoke build - cy.wait(500) - cy.get(".spectrum-Toast-content") + xit("should allow copying of the users API key", () => { + cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true }) + cy.get(interact.SPECTRUM_MENU_ITEM).contains("View API key").click({ force: true }) + cy.get(interact.SPECTRUM_DIALOG_CONTENT).within(() => { + cy.get(interact.SPECTRUM_ICON).click({ force: true }) + }) + // There may be timing issues with this on the smoke build + cy.wait(500) + cy.get(".spectrum-Toast-content") .contains("URL copied to clipboard") .should("be.visible") }) it("should allow API key regeneration", () => { - // Get initial API key value - cy.get(interact.SPECTRUM_DIALOG_CONTENT) + cy.get(".user-dropdown .icon", { timeout: 2000 }).click({ force: true }) + cy.get(interact.SPECTRUM_MENU_ITEM).contains("View API key").click({ force: true }) + cy.get(interact.SPECTRUM_DIALOG_CONTENT).within(() => { + cy.get(interact.SPECTRUM_ICON).click({ force: true }) + }) + // Get initial API key value + cy.get(interact.SPECTRUM_DIALOG_CONTENT) .find(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').as('keyOne') - // Click re-generate key button - cy.get("button").contains("Re-generate key").click({ force: true }) + // Click re-generate key button + cy.get("button").contains("Regenerate key").click({ force: true }) - // Verify API key was changed - cy.get(interact.SPECTRUM_DIALOG_CONTENT).within(() => { - cy.get('@keyOne').then((keyOne) => { - cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').should('not.eq', keyOne) - }) + // Verify API key was changed + cy.get(interact.SPECTRUM_DIALOG_CONTENT).within(() => { + cy.get('@keyOne').then((keyOne) => { + cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).invoke('val').should('not.eq', keyOne) }) - cy.closeModal() + }) + cy.closeModal() }) it("should update password", () => { - // Access Update password modal - cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true }) - cy.get(interact.SPECTRUM_MENU_ITEM).contains("Update password").click({ force: true }) + // Access Update password modal + cy.get(".user-dropdown .icon", { timeout: 2000 }).click({ force: true }) + cy.get(interact.SPECTRUM_MENU_ITEM).contains("Update password").click({ force: true }) - // Enter new password and update - cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => { - for (let i = 0; i < 2; i++) { - // password set to 'newpwd' - cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("newpwd") - } - cy.get("button").contains("Update password").click({ force: true }) - }) + // Enter new password and update + cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => { + for (let i = 0; i < 2; i++) { + // password set to 'newpwd' + cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("newpwd") + } + cy.get("button").contains("Update password").click({ force: true }) + }) - // Logout & in with new password - //cy.logOut() - cy.login("test@test.com", "newpwd") + // Logout & in with new password + //cy.logOut() + cy.login("test@test.com", "newpwd") }) - it("should open and close developer mode", () => { - cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true }) - - // Close developer mode & verify - cy.get(interact.SPECTRUM_MENU_ITEM).contains("Close developer mode").click({ force: true }) - cy.get(interact.SPECTRUM_SIDENAV).should('not.exist') // No config sections - cy.get(interact.CREATE_APP_BUTTON).should('not.exist') // No create app button - cy.get(".app").should('not.exist') // At least one app should be available + xit("should open and close developer mode", () => { + cy.get(".user-dropdown .icon", { timeout: 2000 }).click({ force: true }) - // Open developer mode & verify - cy.get(".avatar > .icon").click({ force: true }) - cy.get(interact.SPECTRUM_MENU_ITEM).contains("Open developer mode").click({ force: true }) - cy.get(interact.SPECTRUM_SIDENAV).should('exist') // config sections available - cy.get(interact.CREATE_APP_BUTTON).should('exist') // create app button available + // Close developer mode & verify + cy.get(interact.SPECTRUM_MENU_ITEM).contains("Close developer mode").click({ force: true }) + cy.get(interact.SPECTRUM_SIDENAV).should('not.exist') // No config sections + cy.get(interact.CREATE_APP_BUTTON).should('not.exist') // No create app button + cy.get(".app").should('not.exist') // At least one app should be available + + // Open developer mode & verify + cy.get(".avatar > .icon").click({ force: true }) + cy.get(interact.SPECTRUM_MENU_ITEM).contains("Open developer mode").click({ force: true }) + cy.get(".app-table").should('exist') // config sections available + cy.get(interact.CREATE_APP_BUTTON).should('exist') // create app button available }) after(() => { - // Change password back to original value - cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ force: true }) - cy.get(interact.SPECTRUM_MENU_ITEM).contains("Update password").click({ force: true }) - cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => { - for (let i = 0; i < 2; i++) { - cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("test") - } - cy.get("button").contains("Update password").click({ force: true }) - }) - // Remove users name - cy.updateUserInformation() + // Change password back to original value + cy.get(".user-dropdown .icon", { timeout: 2000 }).click({ force: true }) + cy.get(interact.SPECTRUM_MENU_ITEM).contains("Update password").click({ force: true }) + cy.get(interact.SPECTRUM_DIALOG_GRID).within(() => { + for (let i = 0; i < 2; i++) { + cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).eq(i).type("test") + } + cy.get("button").contains("Update password").click({ force: true }) }) + // Remove users name + cy.updateUserInformation() + }) }) }) diff --git a/packages/builder/cypress/integration/appOverview.spec.js b/packages/builder/cypress/integration/appOverview.spec.js index 2afc0af277..60d0f2a06d 100644 --- a/packages/builder/cypress/integration/appOverview.spec.js +++ b/packages/builder/cypress/integration/appOverview.spec.js @@ -2,7 +2,7 @@ import filterTests from "../support/filterTests" import clientPackage from "@budibase/client/package.json" filterTests(["all"], () => { - context("Application Overview screen", () => { + xcontext("Application Overview screen", () => { before(() => { cy.login() cy.deleteAllApps() diff --git a/packages/builder/cypress/integration/createApp.spec.js b/packages/builder/cypress/integration/createApp.spec.js index d37b0806c4..897c7f8b91 100644 --- a/packages/builder/cypress/integration/createApp.spec.js +++ b/packages/builder/cypress/integration/createApp.spec.js @@ -14,15 +14,15 @@ filterTests(['smoke', 'all'], () => { cy.visit(`${Cypress.config().baseUrl}/builder/portal/apps/create`, { timeout: 5000 }) //added /portal/apps/create cy.wait(1000) cy.get(interact.CREATE_APP_BUTTON, { timeout: 10000 }).contains('Start from scratch').should("exist") - + cy.get(interact.TEMPLATE_CATEGORY_FILTER).should("exist") cy.get(interact.TEMPLATE_CATEGORY).should("exist") - + cy.get(interact.APP_TABLE).should("not.exist") }) } - it("should provide filterable templates", () => { + xit("should provide filterable templates", () => { cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 }) cy.wait(500) @@ -30,16 +30,16 @@ filterTests(['smoke', 'all'], () => { .its("body") .then(val => { if (val.length > 0) { - cy.get(interact.SPECTRUM_BUTTON).contains("Templates").click({force: true}) + cy.get(interact.SPECTRUM_BUTTON).contains("View Templates").click({ force: true }) } }) cy.get(interact.TEMPLATE_CATEGORY_FILTER).should("exist") cy.get(interact.TEMPLATE_CATEGORY).should("exist") - + cy.get(interact.TEMPLATE_CATEGORY_ACTIONGROUP).its('length').should('be.gt', 1) cy.get(interact.TEMPLATE_CATEGORY_FILTER_ACTIONBUTTON).its('length').should('be.gt', 2) - + cy.get(interact.TEMPLATE_CATEGORY_FILTER_ACTIONBUTTON).eq(1).click() cy.get(interact.TEMPLATE_CATEGORY_ACTIONGROUP).should('have.length', 1) @@ -104,14 +104,14 @@ filterTests(['smoke', 'all'], () => { cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000 }) cy.updateUserInformation("Ted", "Userman") - + cy.createApp("", false) cy.applicationInAppTable("Teds app") cy.deleteApp("Teds app") // Accomodate names that end in 'S' cy.updateUserInformation("Chris", "Userman") - + cy.createApp("", false) cy.applicationInAppTable("Chris app") cy.deleteApp("Chris app") @@ -123,35 +123,49 @@ filterTests(['smoke', 'all'], () => { const exportedApp = 'cypress/fixtures/exported-app.txt' cy.importApp(exportedApp, "") - cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 2000 }) - cy.applicationInAppTable("My app") - - cy.get(".appTable .name").eq(0).click() - - cy.deleteApp("My app") + cy.get(".app-table .name").eq(0).click() + cy.closeModal() + cy.get(`[aria-label="ShowMenu"]`).click() + cy.get(".spectrum-Menu").within(() => { + cy.contains("Overview").click() + }) + cy.get(".app-overview-actions-icon").within(() => { + cy.get(".spectrum-Icon").click({ force: true }) + }) + cy.get(".spectrum-Menu").contains("Delete").click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get("input").type("My app") + }) + cy.get(".spectrum-Button--warning").click() }) it("should create an application from an export, using the users first name as the default app name", () => { const exportedApp = 'cypress/fixtures/exported-app.txt' cy.updateUserInformation("Ted", "Userman") - cy.importApp(exportedApp, "") - cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.applicationInAppTable("Teds app") - - cy.get(".appTable .name").eq(0).click() - - cy.deleteApp("Teds app") - + cy.get(".app-table .name").eq(0).click() + cy.closeModal() + cy.get(`[aria-label="ShowMenu"]`).click() + cy.get(".spectrum-Menu").within(() => { + cy.contains("Overview").click() + }) + cy.get(".app-overview-actions-icon").within(() => { + cy.get(".spectrum-Icon").click({ force: true }) + }) + cy.get(".spectrum-Menu").contains("Delete").click({ force: true }) + cy.get(".spectrum-Dialog-grid").within(() => { + cy.get("input").type("Teds app") + }) + cy.get(".spectrum-Button--warning").click() cy.updateUserInformation("", "") }) - it("should generate the first application from a template", () => { + xit("should generate the first application from a template", () => { cy.visit(`${Cypress.config().baseUrl}/builder`) cy.wait(500) @@ -172,28 +186,28 @@ filterTests(['smoke', 'all'], () => { const card = cy.get('.template-card').eq(0).should("exist"); const cardOverlay = card.get('.template-thumbnail-action-overlay').should("exist") cardOverlay.invoke("show") - cardOverlay.get("button").contains("Use template").should("exist").click({force: true}) + cardOverlay.get("button").contains("Use template").should("exist").click({ force: true }) }) // CMD Create app from theme card cy.get(".spectrum-Modal").should('be.visible') - + const templateName = cy.get(".spectrum-Modal .template-thumbnail-text") templateName.invoke('text') - .then(templateNameText => { - const templateNameParsed = "/"+templateNameText.toLowerCase().replace(/\s+/g, "-") - cy.get(interact.SPECTRUM_MODAL_INPUT).eq(0).should("have.value", templateNameText) - cy.get(interact.SPECTRUM_MODAL_INPUT).eq(1).should("have.value", templateNameParsed) + .then(templateNameText => { + const templateNameParsed = "/" + templateNameText.toLowerCase().replace(/\s+/g, "-") + cy.get(interact.SPECTRUM_MODAL_INPUT).eq(0).should("have.value", templateNameText) + cy.get(interact.SPECTRUM_MODAL_INPUT).eq(1).should("have.value", templateNameParsed) - cy.get(".spectrum-Modal .spectrum-ButtonGroup").contains("Create app").click() - cy.wait(5000) - - cy.visit(`${Cypress.config().baseUrl}/builder`) - cy.wait(2000) + cy.get(".spectrum-Modal .spectrum-ButtonGroup").contains("Create app").click() + cy.wait(5000) - cy.applicationInAppTable(templateNameText) - cy.deleteApp(templateNameText) - }); + cy.visit(`${Cypress.config().baseUrl}/builder`) + cy.wait(2000) + + cy.applicationInAppTable(templateNameText) + cy.deleteApp(templateNameText) + }); }) @@ -217,5 +231,5 @@ filterTests(['smoke', 'all'], () => { cy.deleteApp(secondAppName) }) - }) + }) }) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index 4c44fd6672..e63fd41591 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -101,7 +101,7 @@ Cypress.Commands.add("deleteUser", email => { }) Cypress.Commands.add("updateUserInformation", (firstName, lastName) => { - cy.get(".user-dropdown .avatar > .icon", { timeout: 2000 }).click({ + cy.get(".user-dropdown .icon", { timeout: 2000 }).click({ force: true, }) @@ -132,7 +132,7 @@ Cypress.Commands.add("updateUserInformation", (firstName, lastName) => { .blur() } cy.get(".confirm-wrap").within(() => { - cy.get("button").contains("Update information").click({ force: true }) + cy.get("button").contains("Save").click({ force: true }) }) cy.get(".spectrum-Dialog-grid").should("not.exist") }) @@ -222,9 +222,12 @@ Cypress.Commands.add("deleteApp", name => { // Go to app overview const appIdParsed = appId.split("_").pop() const actionEleId = `[data-cy=row_actions_${appIdParsed}]` - cy.get(actionEleId).within(() => { - cy.contains("Manage").click({ force: true }) + cy.get(actionEleId).click() + cy.get(`[aria-label="ShowMenu"]`).click() + cy.get(".spectrum-Menu").within(() => { + cy.contains("Overview").click() }) + cy.wait(500) // Unpublish first if needed @@ -400,7 +403,7 @@ Cypress.Commands.add("searchForApplication", appName => { return } else { // Searches for the app - cy.get(".filter").then(() => { + cy.get(".spectrum-Search").then(() => { cy.get(".spectrum-Textfield").within(() => { cy.get("input").eq(0).clear({ force: true }) cy.get("input").eq(0).type(appName, { force: true }) @@ -413,7 +416,7 @@ Cypress.Commands.add("searchForApplication", appName => { // Assumes there are no others Cypress.Commands.add("applicationInAppTable", appName => { cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 30000 }) - cy.get(".appTable", { timeout: 30000 }).within(() => { + cy.get(".app-table", { timeout: 30000 }).within(() => { cy.get(".title").contains(appName).should("exist") }) }) diff --git a/packages/builder/package.json b/packages/builder/package.json index eefdd9d0f1..82c939d1f4 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "2.2.12-alpha.22", + "version": "2.2.12-alpha.32", "license": "GPL-3.0", "private": true, "scripts": { @@ -71,10 +71,10 @@ } }, "dependencies": { - "@budibase/bbui": "2.2.12-alpha.22", - "@budibase/client": "2.2.12-alpha.22", - "@budibase/frontend-core": "2.2.12-alpha.22", - "@budibase/string-templates": "2.2.12-alpha.22", + "@budibase/bbui": "2.2.12-alpha.32", + "@budibase/client": "2.2.12-alpha.32", + "@budibase/frontend-core": "2.2.12-alpha.32", + "@budibase/string-templates": "2.2.12-alpha.32", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/builderStore/dataBinding.js b/packages/builder/src/builderStore/dataBinding.js index d188073b95..6de73d487c 100644 --- a/packages/builder/src/builderStore/dataBinding.js +++ b/packages/builder/src/builderStore/dataBinding.js @@ -378,6 +378,7 @@ const getProviderContextBindings = (asset, dataProviders) => { providerId, // Table ID is used by JSON fields to know what table the field is in tableId: table?._id, + component: component._component, category: component._instanceName, icon: def.icon, display: { diff --git a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte index ec39cc6d71..e4cbbfc7aa 100644 --- a/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte +++ b/packages/builder/src/components/backend/Datasources/CreateEditRelationship.svelte @@ -10,7 +10,6 @@ } from "@budibase/bbui" import { tables } from "stores/backend" import { Helpers } from "@budibase/bbui" - import { writable } from "svelte/store" export let save export let datasource @@ -18,41 +17,95 @@ export let fromRelationship = {} export let toRelationship = {} export let close - export let selectedFromTable - let originalFromName = fromRelationship.name, - originalToName = toRelationship.name - let fromTable, toTable, through, linkTable, tableOptions - let isManyToMany, isManyToOne, relationshipTypes - let errors, valid - let currentTables = {} + const colNotSet = "Please specify a column name" + const relationshipTypes = [ + { + label: "One to Many", + value: RelationshipTypes.MANY_TO_ONE, + }, + { + label: "Many to Many", + value: RelationshipTypes.MANY_TO_MANY, + }, + ] - if (fromRelationship && !fromRelationship.relationshipType) { - fromRelationship.relationshipType = RelationshipTypes.MANY_TO_ONE - } + let originalFromColumnName = toRelationship.name, + originalToColumnName = fromRelationship.name + let originalFromTable = plusTables.find( + table => table._id === toRelationship?.tableId + ) + let originalToTable = plusTables.find( + table => table._id === fromRelationship?.tableId + ) - if (toRelationship && selectedFromTable) { - toRelationship.tableId = selectedFromTable._id - } + let tableOptions + let errors = {} + let hasClickedSave = !!fromRelationship.relationshipType + let fromPrimary, + fromForeign, + fromTable, + toTable, + throughTable, + fromColumn, + toColumn + let fromId, toId, throughId, throughToKey, throughFromKey + let isManyToMany, isManyToOne, relationshipType - function inSchema(table, prop, ogName) { - if (!table || !prop || prop === ogName) { - return false + $: { + if (!fromPrimary) { + fromPrimary = fromRelationship.foreignKey + 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 } - const keys = Object.keys(table.schema).map(key => key.toLowerCase()) - return keys.indexOf(prop.toLowerCase()) !== -1 } - const touched = writable({}) + $: tableOptions = plusTables.map(table => ({ + label: table.name, + value: table._id, + })) + $: valid = getErrorCount(errors) === 0 || !hasClickedSave - function invalidThroughTable({ through, throughTo, throughFrom }) { + $: 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 + + const getErrorCount = errors => + Object.entries(errors) + .filter(entry => !!entry[1]) + .map(entry => entry[0]).length + + function invalidThroughTable() { // need to know the foreign key columns to check error - if (!through || !throughTo || !throughFrom) { + if (!throughId || !throughToKey || !throughFromKey) { return false } - const throughTable = plusTables.find(tbl => tbl._id === through) - const otherColumns = Object.values(throughTable.schema).filter( - col => col.name !== throughFrom && col.name !== throughTo + const throughTbl = plusTables.find(tbl => tbl._id === throughId) + const otherColumns = Object.values(throughTbl.schema).filter( + col => col.name !== throughFromKey && col.name !== throughToKey ) for (let col of otherColumns) { if (col.constraints?.presence && !col.autocolumn) { @@ -62,142 +115,134 @@ return false } - function checkForErrors(fromRelate, toRelate) { - const isMany = - fromRelate.relationshipType === RelationshipTypes.MANY_TO_MANY + function validate() { + const isMany = relationshipType === RelationshipTypes.MANY_TO_MANY const tableNotSet = "Please specify a table" + const foreignKeyNotSet = "Please pick a foreign key" const errObj = {} - if ($touched.from && !fromTable) { - errObj.from = tableNotSet + if (!relationshipType) { + errObj.relationshipType = "Please specify a relationship type" } - if ($touched.to && !toTable) { - errObj.to = tableNotSet + if (!fromTable) { + errObj.fromTable = tableNotSet } - if ($touched.through && isMany && !fromRelate.through) { - errObj.through = tableNotSet + if (!toTable) { + errObj.toTable = tableNotSet } - if ($touched.through && invalidThroughTable(fromRelate)) { - errObj.through = - "Ensure all columns in table are nullable or auto generated" + if (isMany && !throughTable) { + errObj.throughTable = tableNotSet } - if ($touched.foreign && !isMany && !fromRelate.fieldName) { - errObj.foreign = "Please pick the foreign key" + if (isMany && !throughFromKey) { + errObj.throughFromKey = foreignKeyNotSet } - const colNotSet = "Please specify a column name" - if ($touched.fromCol && !fromRelate.name) { - errObj.fromCol = colNotSet + if (isMany && !throughToKey) { + errObj.throughToKey = foreignKeyNotSet } - if ($touched.toCol && !toRelate.name) { - errObj.toCol = colNotSet + if (invalidThroughTable()) { + errObj.throughTable = + "Ensure non-key columns are nullable or auto-generated" } - if ($touched.primary && !fromPrimary) { - errObj.primary = "Please pick the primary key" + if (!isMany && !fromForeign) { + errObj.fromForeign = foreignKeyNotSet } + if (!fromColumn) { + errObj.fromColumn = colNotSet + } + if (!toColumn) { + errObj.toColumn = colNotSet + } + if (!isMany && !fromPrimary) { + errObj.fromPrimary = "Please pick the primary key" + } + // currently don't support relationships back onto the table itself, needs to relate out const tableError = "From/to/through tables must be different" - if (fromTable && (fromTable === toTable || fromTable === through)) { - errObj.from = tableError + if (fromTable && (fromTable === toTable || fromTable === throughTable)) { + errObj.fromTable = tableError } - if (toTable && (toTable === fromTable || toTable === through)) { - errObj.to = tableError + if (toTable && (toTable === fromTable || toTable === throughTable)) { + errObj.toTable = tableError } - if (through && (through === fromTable || through === toTable)) { - errObj.through = tableError + if ( + throughTable && + (throughTable === fromTable || throughTable === toTable) + ) { + errObj.throughTable = tableError } const colError = "Column name cannot be an existing column" - if (inSchema(fromTable, fromRelate.name, originalFromName)) { - errObj.fromCol = colError + if (isColumnNameBeingUsed(toTable, fromColumn, originalFromColumnName)) { + errObj.fromColumn = colError } - if (inSchema(toTable, toRelate.name, originalToName)) { - errObj.toCol = colError + if (isColumnNameBeingUsed(fromTable, toColumn, originalToColumnName)) { + errObj.toColumn = colError } let fromType, toType - if (fromPrimary && fromRelate.fieldName) { + if (fromPrimary && fromForeign) { fromType = fromTable?.schema[fromPrimary]?.type - toType = toTable?.schema[fromRelate.fieldName]?.type + toType = toTable?.schema[fromForeign]?.type } if (fromType && toType && fromType !== toType) { - errObj.foreign = + errObj.fromForeign = "Column type of the foreign key must match the primary key" } + errors = errObj + return getErrorCount(errors) === 0 } - let fromPrimary - $: { - if (!fromPrimary && fromTable) { - fromPrimary = fromTable.primary[0] - } - } - $: isManyToMany = - fromRelationship?.relationshipType === RelationshipTypes.MANY_TO_MANY - $: isManyToOne = - fromRelationship?.relationshipType === RelationshipTypes.MANY_TO_ONE - $: tableOptions = plusTables.map(table => ({ - label: table.name, - value: table._id, - })) - $: fromTable = plusTables.find(table => table._id === toRelationship?.tableId) - $: toTable = plusTables.find(table => table._id === fromRelationship?.tableId) - $: through = plusTables.find(table => table._id === fromRelationship?.through) - $: checkForErrors(fromRelationship, toRelationship) - $: valid = - Object.keys(errors).length === 0 && Object.keys($touched).length !== 0 - $: linkTable = through || toTable - $: relationshipTypes = [ - { - label: "Many", - value: RelationshipTypes.MANY_TO_MANY, - }, - { - label: "One", - value: RelationshipTypes.MANY_TO_ONE, - }, - ] - $: updateRelationshipType(fromRelationship?.relationshipType) - $: tableChanged(fromTable, toTable) - - function updateRelationshipType(fromType) { - if (fromType === RelationshipTypes.MANY_TO_MANY) { - toRelationship.relationshipType = RelationshipTypes.MANY_TO_MANY - } else { - toRelationship.relationshipType = RelationshipTypes.MANY_TO_ONE + 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 } function buildRelationships() { - // if any to many only need to check from - const manyToMany = - fromRelationship.relationshipType === RelationshipTypes.MANY_TO_MANY - // main is simply used to know this is the side the user configured it from const id = Helpers.uuid() - if (!manyToMany) { - delete fromRelationship.through - delete toRelationship.through - } + //Map temporary variables let relateFrom = { ...fromRelationship, + tableId: toId, + name: toColumn, + relationshipType, + fieldName: fromForeign, + through: throughId, + throughFrom: throughFromKey, + throughTo: throughToKey, type: "link", main: true, _id: id, } - let relateTo = { + let relateTo = (toRelationship = { ...toRelationship, + tableId: fromId, + name: fromColumn, + through: throughId, type: "link", _id: id, + }) + + // if any to many only need to check from + const manyToMany = + relateFrom.relationshipType === RelationshipTypes.MANY_TO_MANY + + if (!manyToMany) { + delete relateFrom.through + delete relateTo.through } // [0] is because we don't support composite keys for relationships right now if (manyToMany) { relateFrom = { ...relateFrom, - through: through._id, + through: throughTable._id, fieldName: toTable.primary[0], } relateTo = { ...relateTo, - through: through._id, + through: throughTable._id, fieldName: fromTable.primary[0], throughFrom: relateFrom.throughTo, throughTo: relateFrom.throughFrom, @@ -226,9 +271,27 @@ toRelationship = relateTo } - // save the relationship on to the datasource + function removeExistingRelationship() { + if (originalFromTable && originalFromColumnName) { + delete datasource.entities[originalFromTable.name].schema[ + originalToColumnName + ] + } + if (originalToTable && originalToColumnName) { + delete datasource.entities[originalToTable.name].schema[ + originalFromColumnName + ] + } + } + async function saveRelationship() { + hasClickedSave = true + if (!validate()) { + return false + } buildRelationships() + removeExistingRelationship() + // source of relationship datasource.entities[fromTable.name].schema[fromRelationship.name] = fromRelationship @@ -236,43 +299,14 @@ datasource.entities[toTable.name].schema[toRelationship.name] = toRelationship - // If relationship has been renamed - if (originalFromName !== fromRelationship.name) { - delete datasource.entities[fromTable.name].schema[originalFromName] - } - if (originalToName !== toRelationship.name) { - delete datasource.entities[toTable.name].schema[originalToName] - } - - // store the original names so it won't cause an error - originalToName = toRelationship.name - originalFromName = fromRelationship.name await save() } - async function deleteRelationship() { - delete datasource.entities[fromTable.name].schema[fromRelationship.name] - delete datasource.entities[toTable.name].schema[toRelationship.name] + removeExistingRelationship() await save() await tables.fetch() close() } - - function tableChanged(fromTbl, toTbl) { - if ( - (currentTables?.from?._id === fromTbl?._id && - currentTables?.to?._id === toTbl?._id) || - originalFromName || - originalToName - ) { - return - } - fromRelationship.name = toTbl?.name || "" - errors.fromCol = "" - toRelationship.name = fromTbl?.name || "" - errors.toCol = "" - currentTables = { from: fromTbl, to: toTbl } - } (errors.relationshipType = null)} />
Tables @@ -292,58 +328,74 @@ ($touched.primary = true)} - bind:error={errors.primary} + label={`Primary Key (${fromTable.name})`} + options={Object.keys(fromTable.schema)} bind:value={fromPrimary} + bind:error={errors.fromPrimary} + on:change={() => (errors.fromPrimary = null)} /> {/if} ($touched.through = true)} - bind:error={errors.through} - bind:value={fromRelationship.through} + bind:value={throughId} + bind:error={errors.throughTable} /> - {#if fromTable && toTable && through} + {#if fromTable && toTable && throughTable} ($touched.toForeign = true)} - bind:error={errors.toForeign} - bind:value={fromRelationship.throughFrom} + options={Object.keys(throughTable?.schema)} + bind:value={throughFromKey} + bind:error={errors.throughFromKey} + on:change={e => { + if (throughToKey === e.detail) { + throughToKey = null + } + errors.throughFromKey = null + }} /> {/if} {:else if isManyToOne && toTable} ($touched.fromCol = true)} - bind:error={errors.fromCol} label="From table column" - bind:value={fromRelationship.name} + bind:value={fromColumn} + bind:error={errors.fromColumn} + on:change={e => { + errors.fromColumn = e.detail?.length > 0 ? null : colNotSet + }} /> ($touched.toCol = true)} - bind:error={errors.toCol} label="To table column" - bind:value={toRelationship.name} + bind:value={toColumn} + bind:error={errors.toColumn} + on:change={e => (errors.toColumn = e.detail?.length > 0 ? null : colNotSet)} />
- {#if originalFromName != null} + {#if originalFromColumnName != null} {/if}
diff --git a/packages/builder/src/components/design/settings/controls/DataSourceSelect.svelte b/packages/builder/src/components/design/settings/controls/DataSourceSelect.svelte index 6269599f40..49151a09b0 100644 --- a/packages/builder/src/components/design/settings/controls/DataSourceSelect.svelte +++ b/packages/builder/src/components/design/settings/controls/DataSourceSelect.svelte @@ -70,7 +70,10 @@ type: "provider", })) $: links = bindings + // Get only link bindings .filter(x => x.fieldSchema?.type === "link") + // Filter out bindings provided by forms + .filter(x => !x.component?.endsWith("/form")) .map(binding => { const { providerId, readableBinding, fieldSchema } = binding || {} const { name, tableId } = fieldSchema || {} diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/new/_components/NewComponentPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/new/_components/NewComponentPanel.svelte index 98e04a262a..6b3f302264 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/new/_components/NewComponentPanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/new/_components/NewComponentPanel.svelte @@ -176,7 +176,6 @@ const addComponent = async component => { try { await store.actions.components.create(component) - $goto("../") } catch (error) { notifications.error(error || "Error creating component") } diff --git a/packages/builder/src/pages/builder/portal/_components/UpgradeButton.svelte b/packages/builder/src/pages/builder/portal/_components/UpgradeButton.svelte index 3e095dce21..7de6205a31 100644 --- a/packages/builder/src/pages/builder/portal/_components/UpgradeButton.svelte +++ b/packages/builder/src/pages/builder/portal/_components/UpgradeButton.svelte @@ -7,6 +7,7 @@ {#if $admin.cloud && $auth?.user?.accountPortalAccess}
- themeModal.show()} dataCy="theme"> - Theme - profileModal.show()} @@ -36,6 +33,9 @@ > My profile + themeModal.show()} dataCy="theme"> + Theme + updatePasswordModal.show()}> Update password diff --git a/packages/builder/src/pages/builder/portal/settings/auth/index.svelte b/packages/builder/src/pages/builder/portal/settings/auth/index.svelte index 412a75ec0a..f0ca5c9797 100644 --- a/packages/builder/src/pages/builder/portal/settings/auth/index.svelte +++ b/packages/builder/src/pages/builder/portal/settings/auth/index.svelte @@ -172,6 +172,8 @@ delete element.createdAt delete element.updatedAt + const { activated } = element.config + if (element.type === ConfigTypes.OIDC) { // Add a UUID here so each config is distinguishable when it arrives at the login page for (let config of element.config.configs) { @@ -181,30 +183,26 @@ // Callback urls shouldn't be included delete config.callbackURL } - if (partialOidc) { - if (!oidcComplete) { - notifications.error( - `Please fill in all required ${ConfigTypes.OIDC} fields` - ) - } else { - calls.push(API.saveConfig(element)) - // Turn the save button grey when clicked - oidcSaveButtonDisabled = true - originalOidcDoc = cloneDeep(providers.oidc) - } + if ((partialOidc || activated) && !oidcComplete) { + notifications.error( + `Please fill in all required ${ConfigTypes.OIDC} fields` + ) + } else if (oidcComplete || !activated) { + calls.push(API.saveConfig(element)) + // Turn the save button grey when clicked + oidcSaveButtonDisabled = true + originalOidcDoc = cloneDeep(providers.oidc) } } if (element.type === ConfigTypes.Google) { - if (partialGoogle) { - if (!googleComplete) { - notifications.error( - `Please fill in all required ${ConfigTypes.Google} fields` - ) - } else { - calls.push(API.saveConfig(element)) - googleSaveButtonDisabled = true - originalGoogleDoc = cloneDeep(providers.google) - } + if ((partialGoogle || activated) && !googleComplete) { + notifications.error( + `Please fill in all required ${ConfigTypes.Google} fields` + ) + } else if (googleComplete || !activated) { + calls.push(API.saveConfig(element)) + googleSaveButtonDisabled = true + originalGoogleDoc = cloneDeep(providers.google) } } }) diff --git a/packages/cli/package.json b/packages/cli/package.json index 46d404dde0..fd514d6917 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "2.2.12-alpha.22", + "version": "2.2.12-alpha.32", "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.22", - "@budibase/string-templates": "2.2.12-alpha.22", - "@budibase/types": "2.2.12-alpha.22", + "@budibase/backend-core": "2.2.12-alpha.32", + "@budibase/string-templates": "2.2.12-alpha.32", + "@budibase/types": "2.2.12-alpha.32", "axios": "0.21.2", "chalk": "4.1.0", "cli-progress": "3.11.2", diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 9d50c13bb6..d1898a82c1 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -4019,7 +4019,8 @@ { "type": "filter", "label": "Filtering", - "key": "filter" + "key": "filter", + "nested": true }, { "type": "field", @@ -4535,7 +4536,8 @@ { "type": "filter", "label": "Filtering", - "key": "filter" + "key": "filter", + "nested": true }, { "type": "searchfield", @@ -4665,7 +4667,8 @@ { "type": "filter", "label": "Filtering", - "key": "filter" + "key": "filter", + "nested": true }, { "type": "field/sortable", @@ -4831,7 +4834,8 @@ { "type": "filter", "label": "Filtering", - "key": "filter" + "key": "filter", + "nested": true }, { "type": "field/sortable", diff --git a/packages/client/package.json b/packages/client/package.json index aaca8dcfc9..6f6422c236 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "2.2.12-alpha.22", + "version": "2.2.12-alpha.32", "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.22", - "@budibase/frontend-core": "2.2.12-alpha.22", - "@budibase/string-templates": "2.2.12-alpha.22", + "@budibase/bbui": "2.2.12-alpha.32", + "@budibase/frontend-core": "2.2.12-alpha.32", + "@budibase/string-templates": "2.2.12-alpha.32", "@spectrum-css/button": "^3.0.3", "@spectrum-css/card": "^3.0.3", "@spectrum-css/divider": "^1.0.3", diff --git a/packages/client/src/components/Block.svelte b/packages/client/src/components/Block.svelte index 8258912e52..b72ff81b49 100644 --- a/packages/client/src/components/Block.svelte +++ b/packages/client/src/components/Block.svelte @@ -38,7 +38,7 @@ ...$component.styles?.normal, }, custom: - definition._styles?.custom || "" + $component.styles?.custom || "", + (definition._styles?.custom || "") + ($component.styles?.custom || ""), } // Create component tree diff --git a/packages/client/src/components/CustomThemeWrapper.svelte b/packages/client/src/components/CustomThemeWrapper.svelte index 20dae01ce0..c9ab9c9dc1 100644 --- a/packages/client/src/components/CustomThemeWrapper.svelte +++ b/packages/client/src/components/CustomThemeWrapper.svelte @@ -1,5 +1,9 @@
diff --git a/packages/client/src/components/app/blocks/CardsBlock.svelte b/packages/client/src/components/app/blocks/CardsBlock.svelte index 5098a3acf4..795e62eb31 100644 --- a/packages/client/src/components/app/blocks/CardsBlock.svelte +++ b/packages/client/src/components/app/blocks/CardsBlock.svelte @@ -36,9 +36,12 @@ let dataProviderId let repeaterId let schema + let enrichedSearchColumns $: fetchSchema(dataSource) - $: enrichedSearchColumns = enrichSearchColumns(searchColumns, schema) + $: enrichSearchColumns(searchColumns, schema).then( + val => (enrichedSearchColumns = val) + ) $: enrichedFilter = enrichFilter(filter, enrichedSearchColumns, formId) $: cardWidth = cardHorizontal ? 420 : 300 $: fullCardURL = buildFullCardUrl( diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte index 0984c901a3..91c266b434 100644 --- a/packages/client/src/components/app/blocks/TableBlock.svelte +++ b/packages/client/src/components/app/blocks/TableBlock.svelte @@ -36,9 +36,12 @@ let newRowSidePanelId let schema let primaryDisplay + let enrichedSearchColumns $: fetchSchema(dataSource) - $: enrichedSearchColumns = enrichSearchColumns(searchColumns, schema) + $: enrichSearchColumns(searchColumns, schema).then( + val => (enrichedSearchColumns = val) + ) $: enrichedFilter = enrichFilter(filter, enrichedSearchColumns, formId) $: editTitle = getEditTitle(detailsFormBlockId, primaryDisplay) $: normalFields = getNormalFields(schema) diff --git a/packages/client/src/components/app/forms/Form.svelte b/packages/client/src/components/app/forms/Form.svelte index 977b940d1f..0b4502b962 100644 --- a/packages/client/src/components/app/forms/Form.svelte +++ b/packages/client/src/components/app/forms/Form.svelte @@ -24,6 +24,11 @@ let table $: fetchSchema(dataSource) + $: schemaKey = generateSchemaKey(schema) + $: initialValues = getInitialValues(actionType, dataSource, $context) + $: resetKey = Helpers.hashString( + schemaKey + JSON.stringify(initialValues) + disabled + ) // Returns the closes data context which isn't a built in context const getInitialValues = (type, dataSource, context) => { @@ -57,13 +62,17 @@ schema = res || {} } - $: initialValues = getInitialValues(actionType, dataSource, $context) - $: resetKey = Helpers.hashString( - !!schema + - JSON.stringify(initialValues) + - JSON.stringify(dataSource) + - disabled - ) + // Generates a predictable string that uniquely identifies a schema. We can't + // simply stringify the whole schema as there are array fields which have + // random order. + const generateSchemaKey = schema => { + if (!schema) { + return null + } + const fields = Object.keys(schema) + fields.sort() + return fields.map(field => `${field}:${schema[field].type}`).join("-") + } {#key resetKey} diff --git a/packages/client/src/utils/blocks.js b/packages/client/src/utils/blocks.js index 61cd640bbc..214b48a4d2 100644 --- a/packages/client/src/utils/blocks.js +++ b/packages/client/src/utils/blocks.js @@ -1,4 +1,5 @@ import { makePropSafe as safe } from "@budibase/string-templates" +import { API } from "../api/index.js" // Map of data types to component types for search fields inside blocks const schemaComponentMap = { @@ -15,10 +16,28 @@ const schemaComponentMap = { * @param searchColumns the search columns to use * @param schema the datasource schema */ -export const enrichSearchColumns = (searchColumns, schema) => { +export const enrichSearchColumns = async (searchColumns, schema) => { + if (!searchColumns?.length || !schema) { + return [] + } let enrichedColumns = [] - searchColumns?.forEach(column => { - const schemaType = schema?.[column]?.type + for (let column of searchColumns) { + let schemaType = schema[column]?.type + + // Check if this is a field in another related table. The only way we can + // check this is checking for a "." inside the column, then checking if we + // have a link field named the same as that field prefix. + if (column.includes(".")) { + const split = column.split(".") + const sourceField = split[0] + const linkField = split.slice(1).join(".") + const linkSchema = schema[sourceField] + if (linkSchema?.type === "link") { + const linkedDef = await API.fetchTableDefinition(linkSchema.tableId) + schemaType = linkedDef?.schema?.[linkField]?.type + } + } + const componentType = schemaComponentMap[schemaType] if (componentType) { enrichedColumns.push({ @@ -27,7 +46,7 @@ export const enrichSearchColumns = (searchColumns, schema) => { type: schemaType, }) } - }) + } return enrichedColumns.slice(0, 5) } @@ -57,12 +76,14 @@ export const enrichFilter = (filter, columns, formId) => { value: `{{ ${binding} }}`, }) const format = "YYYY-MM-DDTHH:mm:ss.SSSZ" + let hbs = `{{ date (add (date ${binding} "x") 86399999) "${format}" }}` + hbs = `{{#if ${binding} }}${hbs}{{/if}}` enrichedFilter.push({ field: column.name, type: column.type, operator: "rangeHigh", valueType: "Binding", - value: `{{ date (add (date ${binding} "x") 86399999) "${format}" }}`, + value: hbs, }) } diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index 12abf5a662..321d95a284 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.22", + "version": "2.2.12-alpha.32", "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.22", + "@budibase/bbui": "2.2.12-alpha.32", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 184067100e..ad4f5615f1 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/sdk", - "version": "2.2.12-alpha.22", + "version": "2.2.12-alpha.32", "description": "Budibase Public API SDK", "author": "Budibase", "license": "MPL-2.0", diff --git a/packages/server/package.json b/packages/server/package.json index defc16e36a..0ba9468623 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.22", + "version": "2.2.12-alpha.32", "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.22", - "@budibase/client": "2.2.12-alpha.22", - "@budibase/pro": "2.2.12-alpha.22", - "@budibase/string-templates": "2.2.12-alpha.22", - "@budibase/types": "2.2.12-alpha.22", + "@budibase/backend-core": "2.2.12-alpha.32", + "@budibase/client": "2.2.12-alpha.32", + "@budibase/pro": "2.2.12-alpha.32", + "@budibase/string-templates": "2.2.12-alpha.32", + "@budibase/types": "2.2.12-alpha.32", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", @@ -77,7 +77,7 @@ "joi": "17.6.0", "js-yaml": "4.1.0", "jsonschema": "1.4.0", - "knex": "0.95.15", + "knex": "2.4.0", "koa": "2.13.4", "koa-body": "4.2.0", "koa-compress": "4.0.1", diff --git a/packages/server/src/api/controllers/row/ExternalRequest.ts b/packages/server/src/api/controllers/row/ExternalRequest.ts index 80ba4fd808..6085921423 100644 --- a/packages/server/src/api/controllers/row/ExternalRequest.ts +++ b/packages/server/src/api/controllers/row/ExternalRequest.ts @@ -681,6 +681,12 @@ export class ExternalRequest { config, table ) + //if the sort column is a formula, remove it + for (let sortColumn of Object.keys(sort || {})) { + if (table.schema[sortColumn]?.type === "formula") { + delete sort?.[sortColumn] + } + } filters = buildFilters(id, filters || {}, table) const relationships = this.buildRelationships(table) // clean up row on ingress using schema diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index 21dbcf1da8..0514fed5d6 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.22": - version "2.2.12-alpha.22" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.22.tgz#120ee25139f88e3b7f96355b4fe5b7ca2ccff5f4" - integrity sha512-rhQ7fHneJKo5qKWrSwSX0Ud4xcCbv5qg7fNr2AqxClEpkNbY9DH8YZn9C9yDyvpQj/UM39jvUiwnN2lrKi8b4A== +"@budibase/backend-core@2.2.12-alpha.32": + version "2.2.12-alpha.32" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.32.tgz#5d53fdde38e80fdade73c59cb81623041984a5fc" + integrity sha512-XoaqGrttx01wlblI0+O23R9uS5FTMgK07juY6mUkdReCK46IvmG7FFnuYu0euKVRbhChSf5X8S+fvKIAEi1ZFw== dependencies: "@budibase/nano" "10.1.1" - "@budibase/types" "2.2.12-alpha.22" + "@budibase/types" "2.2.12-alpha.32" "@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.22": - version "2.2.12-alpha.22" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.22.tgz#5ffe51546b7ec1b685c954ae111792b66f1d9653" - integrity sha512-zFZC37mOMgY9c1nnFlWyDpkP2RT4nKbC6z/oobed7P5yjykc8LZGTOpVz7RZE0eRa1+S4pGrjw1wFRM/TUFvFw== +"@budibase/pro@2.2.12-alpha.32": + version "2.2.12-alpha.32" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.32.tgz#4f35b0ada97458cc69ee41ebb40d56b361518065" + integrity sha512-Kn/IahgIb9Ydzmasv4Bhlh3rvyAC2tBVSoI33OZ/6PKF0vPYJNJkFds3iGELNV7SyWoLbVWb2z5SQ4SSaOYsJw== dependencies: - "@budibase/backend-core" "2.2.12-alpha.22" - "@budibase/types" "2.2.12-alpha.22" + "@budibase/backend-core" "2.2.12-alpha.32" + "@budibase/types" "2.2.12-alpha.32" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" @@ -1405,10 +1405,10 @@ svelte-apexcharts "^1.0.2" svelte-flatpickr "^3.1.0" -"@budibase/types@2.2.12-alpha.22": - version "2.2.12-alpha.22" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.22.tgz#b34026ec0176482c9e93431f4db25442f48e933f" - integrity sha512-wCFfD0Awa+RNUJmHYS4Iuhpj6zRPvNIlFMvgOnZes+tIbvLjmOF+9cuDY11qea6pLoG2i+T5Z4NaDv7xn5ATMQ== +"@budibase/types@2.2.12-alpha.32": + version "2.2.12-alpha.32" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.32.tgz#71af8e8cff66acbfd65aa87e66183dd95d76ce6f" + integrity sha512-ZZwmO+0ORGEFbU/EQvtnjo1VonUbBdsciFkTOiopVupU5iNY2oCKgbYTQiTZZisQrRuiKdPV6P17uV+YTkjQSQ== "@bull-board/api@3.7.0": version "3.7.0" @@ -5301,15 +5301,10 @@ color@^3.1.3: color-convert "^1.9.3" color-string "^1.6.0" -colorette@2.0.16: - version "2.0.16" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== - -colorette@^2.0.14: - version "2.0.17" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.17.tgz#5dd4c0d15e2984b7433cb4a9f2ead45063b80c47" - integrity sha512-hJo+3Bkn0NCHybn9Tu35fIeoOKGOk5OCC32y4Hz2It+qlCO2Q3DeQ1hRn/tDDMQKRYUEzqsl7jbF6dYKjlE60g== +colorette@2.0.19, colorette@^2.0.14: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== colorspace@1.1.x: version "1.1.4" @@ -5346,7 +5341,7 @@ commander@^5.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^7.0.0, commander@^7.1.0: +commander@^7.0.0: version "7.2.0" resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== @@ -5356,6 +5351,11 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@^9.1.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + commoner@^0.10.1: version "0.10.8" resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5" @@ -5659,20 +5659,13 @@ dayjs@^1.10.4, dayjs@^1.10.5: resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.3.tgz#4754eb694a624057b9ad2224b67b15d552589258" integrity sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A== -debug@4, debug@^4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: +debug@4, debug@4.3.4, debug@^4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -7441,10 +7434,10 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== -getopts@2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b" - integrity sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA== +getopts@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4" + integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA== getpass@^0.1.1: version "0.1.7" @@ -9825,23 +9818,24 @@ kleur@^3.0.3: resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== -knex@0.95.15: - version "0.95.15" - resolved "https://registry.yarnpkg.com/knex/-/knex-0.95.15.tgz#39d7e7110a6e2ad7de5d673d2dea94143015e0e7" - integrity sha512-Loq6WgHaWlmL2bfZGWPsy4l8xw4pOE+tmLGkPG0auBppxpI0UcK+GYCycJcqz9W54f2LiGewkCVLBm3Wq4ur/w== +knex@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/knex/-/knex-2.4.0.tgz#7d33cc36f320cdac98741010544b4c6a98b8b19e" + integrity sha512-i0GWwqYp1Hs2yvc2rlDO6nzzkLhwdyOZKRdsMTB8ZxOs2IXQyL5rBjSbS1krowCh6V65T4X9CJaKtuIfkaPGSA== dependencies: - colorette "2.0.16" - commander "^7.1.0" - debug "4.3.2" + colorette "2.0.19" + commander "^9.1.0" + debug "4.3.4" escalade "^3.1.1" esm "^3.2.25" - getopts "2.2.5" + get-package-type "^0.1.0" + getopts "2.3.0" interpret "^2.2.0" lodash "^4.17.21" pg-connection-string "2.5.0" - rechoir "0.7.0" + rechoir "^0.8.0" resolve-from "^5.0.0" - tarn "^3.0.1" + tarn "^3.0.2" tildify "2.0.0" koa-body@4.2.0: @@ -12561,13 +12555,6 @@ recast@^0.11.17: private "~0.1.5" source-map "~0.5.0" -rechoir@0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca" - integrity sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q== - dependencies: - resolve "^1.9.0" - rechoir@^0.7.0: version "0.7.1" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" @@ -12575,6 +12562,13 @@ rechoir@^0.7.0: dependencies: resolve "^1.9.0" +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + redis-commands@1.7.0, redis-commands@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89" @@ -14051,7 +14045,7 @@ tarn@^1.1.5: resolved "https://registry.yarnpkg.com/tarn/-/tarn-1.1.5.tgz#7be88622e951738b9fa3fb77477309242cdddc2d" integrity sha512-PMtJ3HCLAZeedWjJPgGnCvcphbCOMbtZpjKgLq3qM5Qq9aQud+XHrL0WlrlgnTyS8U+jrjGbEXprFcQrxPy52g== -tarn@^3.0.1: +tarn@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index 1c0235c83d..b523f2cd0e 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.22", + "version": "2.2.12-alpha.32", "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 6f7c0d9966..8a27829c47 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "2.2.12-alpha.22", + "version": "2.2.12-alpha.32", "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 ecea3786e0..3cef4d12f6 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.22", + "version": "2.2.12-alpha.32", "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.22", - "@budibase/pro": "2.2.12-alpha.22", - "@budibase/string-templates": "2.2.12-alpha.22", - "@budibase/types": "2.2.12-alpha.22", + "@budibase/backend-core": "2.2.12-alpha.32", + "@budibase/pro": "2.2.12-alpha.32", + "@budibase/string-templates": "2.2.12-alpha.32", + "@budibase/types": "2.2.12-alpha.32", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", diff --git a/packages/worker/src/api/routes/global/configs.ts b/packages/worker/src/api/routes/global/configs.ts index 7420d749c2..38a31a28e6 100644 --- a/packages/worker/src/api/routes/global/configs.ts +++ b/packages/worker/src/api/routes/global/configs.ts @@ -34,8 +34,8 @@ function settingValidation() { function googleValidation() { // prettier-ignore return Joi.object({ - clientID: Joi.string().required(), - clientSecret: Joi.string().required(), + clientID: Joi.when('activated', { is: true, then: Joi.string().required() }), + clientSecret: Joi.when('activated', { is: true, then: Joi.string().required() }), activated: Joi.boolean().required(), }).unknown(true) } @@ -45,12 +45,12 @@ function oidcValidation() { return Joi.object({ configs: Joi.array().items( Joi.object({ - clientID: Joi.string().required(), - clientSecret: Joi.string().required(), - configUrl: Joi.string().required(), + clientID: Joi.when('activated', { is: true, then: Joi.string().required() }), + clientSecret: Joi.when('activated', { is: true, then: Joi.string().required() }), + configUrl: Joi.when('activated', { is: true, then: Joi.string().required() }), logo: Joi.string().allow("", null), name: Joi.string().allow("", null), - uuid: Joi.string().required(), + uuid: Joi.when('activated', { is: true, then: Joi.string().required() }), activated: Joi.boolean().required(), scopes: Joi.array().optional() }) diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index 55cd72952c..052edf0197 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.22": - version "2.2.12-alpha.22" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.22.tgz#120ee25139f88e3b7f96355b4fe5b7ca2ccff5f4" - integrity sha512-rhQ7fHneJKo5qKWrSwSX0Ud4xcCbv5qg7fNr2AqxClEpkNbY9DH8YZn9C9yDyvpQj/UM39jvUiwnN2lrKi8b4A== +"@budibase/backend-core@2.2.12-alpha.32": + version "2.2.12-alpha.32" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-2.2.12-alpha.32.tgz#5d53fdde38e80fdade73c59cb81623041984a5fc" + integrity sha512-XoaqGrttx01wlblI0+O23R9uS5FTMgK07juY6mUkdReCK46IvmG7FFnuYu0euKVRbhChSf5X8S+fvKIAEi1ZFw== dependencies: "@budibase/nano" "10.1.1" - "@budibase/types" "2.2.12-alpha.22" + "@budibase/types" "2.2.12-alpha.32" "@shopify/jest-koa-mocks" "5.0.1" "@techpass/passport-openidconnect" "0.3.2" aws-cloudfront-sign "2.2.0" @@ -521,23 +521,23 @@ qs "^6.11.0" tough-cookie "^4.1.2" -"@budibase/pro@2.2.12-alpha.22": - version "2.2.12-alpha.22" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.22.tgz#5ffe51546b7ec1b685c954ae111792b66f1d9653" - integrity sha512-zFZC37mOMgY9c1nnFlWyDpkP2RT4nKbC6z/oobed7P5yjykc8LZGTOpVz7RZE0eRa1+S4pGrjw1wFRM/TUFvFw== +"@budibase/pro@2.2.12-alpha.32": + version "2.2.12-alpha.32" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-2.2.12-alpha.32.tgz#4f35b0ada97458cc69ee41ebb40d56b361518065" + integrity sha512-Kn/IahgIb9Ydzmasv4Bhlh3rvyAC2tBVSoI33OZ/6PKF0vPYJNJkFds3iGELNV7SyWoLbVWb2z5SQ4SSaOYsJw== dependencies: - "@budibase/backend-core" "2.2.12-alpha.22" - "@budibase/types" "2.2.12-alpha.22" + "@budibase/backend-core" "2.2.12-alpha.32" + "@budibase/types" "2.2.12-alpha.32" "@koa/router" "8.0.8" bull "4.10.1" joi "17.6.0" jsonwebtoken "8.5.1" node-fetch "^2.6.1" -"@budibase/types@2.2.12-alpha.22": - version "2.2.12-alpha.22" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.22.tgz#b34026ec0176482c9e93431f4db25442f48e933f" - integrity sha512-wCFfD0Awa+RNUJmHYS4Iuhpj6zRPvNIlFMvgOnZes+tIbvLjmOF+9cuDY11qea6pLoG2i+T5Z4NaDv7xn5ATMQ== +"@budibase/types@2.2.12-alpha.32": + version "2.2.12-alpha.32" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-2.2.12-alpha.32.tgz#71af8e8cff66acbfd65aa87e66183dd95d76ce6f" + integrity sha512-ZZwmO+0ORGEFbU/EQvtnjo1VonUbBdsciFkTOiopVupU5iNY2oCKgbYTQiTZZisQrRuiKdPV6P17uV+YTkjQSQ== "@cspotcode/source-map-support@^0.8.0": version "0.8.1"