From 5dff2f30173a32cf122b20b96dd40635577c4bd5 Mon Sep 17 00:00:00 2001 From: Dean Date: Wed, 26 Apr 2023 14:16:36 +0100 Subject: [PATCH 01/28] Added pending users to user portal screen --- .../builder/portal/users/users/index.svelte | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/packages/builder/src/pages/builder/portal/users/users/index.svelte b/packages/builder/src/pages/builder/portal/users/users/index.svelte index 984ecd46ff..0c69e2c213 100644 --- a/packages/builder/src/pages/builder/portal/users/users/index.svelte +++ b/packages/builder/src/pages/builder/portal/users/users/index.svelte @@ -110,6 +110,27 @@ } }) } + let invitesLoaded = false + let pendingInvites = [] + let parsedInvites = [] + + const invitesToSchema = invites => { + return invites.map(invite => { + const { admin, builder, userGroups, apps } = invite.info + + return { + email: invite.email, + builder, + admin, + userGroups: userGroups, + apps: apps ? [...new Set(Object.keys(apps))] : undefined, + } + }) + } + $: parsedInvites = invitesToSchema(pendingInvites) + $: console.log("parsed invites ", parsedInvites) + // $: console.log(pendingInvites) + $: console.log(enrichedUsers) const updateFetch = email => { fetch.update({ @@ -232,6 +253,9 @@ try { await groups.actions.init() groupsLoaded = true + + pendingInvites = await users.getInvites() + invitesLoaded = true } catch (error) { notifications.error("Error fetching user group data") } @@ -326,6 +350,23 @@ + + + Pending invitations + A list of all pending user invitations + + + + + + From 785b6f50ae7619bf9fcc82389e7635697ae7c399 Mon Sep 17 00:00:00 2001 From: Dean Date: Wed, 26 Apr 2023 14:53:31 +0100 Subject: [PATCH 02/28] Removed console debugging --- .../builder/src/pages/builder/portal/users/users/index.svelte | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/builder/src/pages/builder/portal/users/users/index.svelte b/packages/builder/src/pages/builder/portal/users/users/index.svelte index 0c69e2c213..19beb67773 100644 --- a/packages/builder/src/pages/builder/portal/users/users/index.svelte +++ b/packages/builder/src/pages/builder/portal/users/users/index.svelte @@ -128,9 +128,6 @@ }) } $: parsedInvites = invitesToSchema(pendingInvites) - $: console.log("parsed invites ", parsedInvites) - // $: console.log(pendingInvites) - $: console.log(enrichedUsers) const updateFetch = email => { fetch.update({ From 4f8e293dc9dec147d66de0fb4e0703f52c472346 Mon Sep 17 00:00:00 2001 From: Dean Date: Wed, 26 Apr 2023 16:42:27 +0100 Subject: [PATCH 03/28] Refresh pending invites after inviting a new user in the portal user menu --- .../builder/src/pages/builder/portal/users/users/index.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/builder/src/pages/builder/portal/users/users/index.svelte b/packages/builder/src/pages/builder/portal/users/users/index.svelte index 19beb67773..ff5ad2356e 100644 --- a/packages/builder/src/pages/builder/portal/users/users/index.svelte +++ b/packages/builder/src/pages/builder/portal/users/users/index.svelte @@ -162,6 +162,7 @@ })) try { inviteUsersResponse = await users.invite(payload) + pendingInvites = await users.getInvites() inviteConfirmationModal.show() } catch (error) { notifications.error("Error inviting user") From 19ed0ec3f59270c6c7418e0ea7870e9055f1bbbe Mon Sep 17 00:00:00 2001 From: Dean Date: Wed, 3 May 2023 11:22:38 +0100 Subject: [PATCH 04/28] Feedback updates and a fix for z-index issue in user side panel --- .../components/backend/DataTable/Table.svelte | 2 ++ .../_components/BuilderSidePanel.svelte | 4 ++-- .../builder/portal/users/users/index.svelte | 22 ++++++++++--------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/packages/builder/src/components/backend/DataTable/Table.svelte b/packages/builder/src/components/backend/DataTable/Table.svelte index 4df6e9a306..460a02a9b1 100644 --- a/packages/builder/src/components/backend/DataTable/Table.svelte +++ b/packages/builder/src/components/backend/DataTable/Table.svelte @@ -22,6 +22,7 @@ export let rowCount export let disableSorting = false export let customPlaceholder = false + export let allowClickRows const dispatch = createEventDispatcher() @@ -110,6 +111,7 @@ {disableSorting} {customPlaceholder} showAutoColumns={!hideAutocolumns} + {allowClickRows} on:clickrelationship={e => selectRelationship(e.detail)} on:sort > diff --git a/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte b/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte index 9a6d9ea1d3..be8237f616 100644 --- a/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/_components/BuilderSidePanel.svelte @@ -555,7 +555,7 @@ {#if filteredUsers?.length}
-
+
Users
Access
@@ -696,7 +696,7 @@ max-width: calc(100vw - 40px); background: var(--background); border-left: var(--border-light); - z-index: 3; + z-index: 999; display: flex; flex-direction: column; overflow-y: auto; diff --git a/packages/builder/src/pages/builder/portal/users/users/index.svelte b/packages/builder/src/pages/builder/portal/users/users/index.svelte index ff5ad2356e..4053ef5ff3 100644 --- a/packages/builder/src/pages/builder/portal/users/users/index.svelte +++ b/packages/builder/src/pages/builder/portal/users/users/index.svelte @@ -88,6 +88,16 @@ }, } + const getPendingSchema = tblSchema => { + if (!tblSchema) { + return {} + } + let pendingSchema = JSON.parse(JSON.stringify(tblSchema)) + pendingSchema.email.displayName = "Pending Invites" + return pendingSchema + } + + $: pendingSchema = getPendingSchema(schema) $: userData = [] $: inviteUsersResponse = { successful: [], unsuccessful: [] } $: { @@ -346,22 +356,14 @@ goToNextPage={fetch.nextPage} />
- - - - - Pending invitations - A list of all pending user invitations - - -
From 80d3b99b90dba2d1e7b4c3bd16a573c63b814f78 Mon Sep 17 00:00:00 2001 From: jvcalderon Date: Mon, 8 May 2023 13:26:00 +0200 Subject: [PATCH 05/28] Provide some functions to check the path in the context --- .../src/utils/tests/utils.spec.ts | 77 +++++++++++++++++++ packages/backend-core/src/utils/utils.ts | 19 ++++- 2 files changed, 93 insertions(+), 3 deletions(-) diff --git a/packages/backend-core/src/utils/tests/utils.spec.ts b/packages/backend-core/src/utils/tests/utils.spec.ts index ededa48628..bea0bfa52b 100644 --- a/packages/backend-core/src/utils/tests/utils.spec.ts +++ b/packages/backend-core/src/utils/tests/utils.spec.ts @@ -5,6 +5,8 @@ import * as db from "../../db" import { Header } from "../../constants" import { newid } from "../../utils" import env from "../../environment" +import { beforeEach } from "@jest/globals" +import { BBContext } from "@budibase/types" describe("utils", () => { const config = new DBTestConfiguration() @@ -106,4 +108,79 @@ describe("utils", () => { expect(actual).toBe(undefined) }) }) + + describe("isServingBuilder", () => { + let ctx: BBContext + + const expectResult = (result: boolean) => + expect(utils.isServingBuilder(ctx)).toBe(result) + + beforeEach(() => { + ctx = structures.koa.newContext() + }) + + it("returns true if current path is in builder", async () => { + ctx.path = "/builder/app/app_" + expectResult(true) + }) + + it("returns false if current path is not in builder", async () => { + ctx.path = "/builder/app" + expectResult(false) + + ctx.path = "/xx" + expectResult(false) + }) + }) + + describe("isServingBuilderPreview", () => { + let ctx: BBContext + + const expectResult = (result: boolean) => + expect(utils.isServingBuilderPreview(ctx)).toBe(result) + + beforeEach(() => { + ctx = structures.koa.newContext() + }) + + it("returns true if current path is in builder preview", async () => { + ctx.path = "/app/preview/xx" + expectResult(true) + }) + + it("returns false if current path is not in builder preview", async () => { + ctx.path = "/builder" + expectResult(false) + + ctx.path = "/xx" + expectResult(false) + }) + }) + + describe("isPublicAPIRequest", () => { + let ctx: BBContext + + const expectResult = (result: boolean) => + expect(utils.isPublicApiRequest(ctx)).toBe(result) + + beforeEach(() => { + ctx = structures.koa.newContext() + }) + + it("returns true if current path remains to public API", async () => { + ctx.path = "/api/public/v1/invoices" + expectResult(true) + + ctx.path = "/api/public/v1" + expectResult(true) + }) + + it("returns false if current path doesn't remain to public API", async () => { + ctx.path = "/api/public" + expectResult(false) + + ctx.path = "/xx" + expectResult(false) + }) + }) }) diff --git a/packages/backend-core/src/utils/utils.ts b/packages/backend-core/src/utils/utils.ts index 75b098093b..6cbd1fc406 100644 --- a/packages/backend-core/src/utils/utils.ts +++ b/packages/backend-core/src/utils/utils.ts @@ -1,10 +1,9 @@ -import { getAllApps, queryGlobalView } from "../db" +import { getAllApps } from "../db" import { Header, MAX_VALID_DATE, DocumentType, SEPARATOR, - ViewName, } from "../constants" import env from "../environment" import * as tenancy from "../tenancy" @@ -23,7 +22,9 @@ const APP_PREFIX = DocumentType.APP + SEPARATOR const PROD_APP_PREFIX = "/app/" const BUILDER_PREVIEW_PATH = "/app/preview" -const BUILDER_REFERER_PREFIX = "/builder/app/" +const BUILDER_PREFIX = "/builder" +const BUILDER_REFERER_PREFIX = `${BUILDER_PREFIX}/app/` +const PUBLIC_API_PREFIX = "/api/public/v1" function confirmAppId(possibleAppId: string | undefined) { return possibleAppId && possibleAppId.startsWith(APP_PREFIX) @@ -69,6 +70,18 @@ export function isServingApp(ctx: Ctx) { return false } +export function isServingBuilder(ctx: Ctx): boolean { + return ctx.path.startsWith(BUILDER_REFERER_PREFIX) +} + +export function isServingBuilderPreview(ctx: Ctx): boolean { + return ctx.path.startsWith(BUILDER_PREVIEW_PATH) +} + +export function isPublicApiRequest(ctx: Ctx): boolean { + return ctx.path.startsWith(PUBLIC_API_PREFIX) +} + /** * Given a request tries to find the appId, which can be located in various places * @param {object} ctx The main request body to look through. From d4d1bc03b31324c530b7f589cbd1ec402fdf739f Mon Sep 17 00:00:00 2001 From: jvcalderon Date: Mon, 8 May 2023 13:42:26 +0200 Subject: [PATCH 06/28] Fix ESLint --- packages/backend-core/src/utils/utils.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/backend-core/src/utils/utils.ts b/packages/backend-core/src/utils/utils.ts index 6cbd1fc406..aee672042b 100644 --- a/packages/backend-core/src/utils/utils.ts +++ b/packages/backend-core/src/utils/utils.ts @@ -1,10 +1,5 @@ import { getAllApps } from "../db" -import { - Header, - MAX_VALID_DATE, - DocumentType, - SEPARATOR, -} from "../constants" +import { Header, MAX_VALID_DATE, DocumentType, SEPARATOR } from "../constants" import env from "../environment" import * as tenancy from "../tenancy" import * as context from "../context" From 88c475e4cb24494a63fe9b21a497728380ec368c Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 10 May 2023 16:00:12 +0100 Subject: [PATCH 07/28] Add grid menu items to copy row ID and rev --- .../grid/overlays/MenuOverlay.svelte | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/frontend-core/src/components/grid/overlays/MenuOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/MenuOverlay.svelte index 89e4d3503b..d0379edee6 100644 --- a/packages/frontend-core/src/components/grid/overlays/MenuOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/MenuOverlay.svelte @@ -1,5 +1,11 @@ {#if $menu.visible} @@ -64,6 +75,22 @@ > Edit row in modal + copyToClipboard($focusedRow?._id)} + on:click={menu.actions.close} + > + Copy row _id + + copyToClipboard($focusedRow?._rev)} + on:click={menu.actions.close} + > + Copy row _rev + Date: Wed, 10 May 2023 16:00:27 +0100 Subject: [PATCH 08/28] Fix not properly updating row state for formula columns --- packages/frontend-core/src/components/grid/stores/rows.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/rows.js b/packages/frontend-core/src/components/grid/stores/rows.js index 694b66629b..b6dc8c05d0 100644 --- a/packages/frontend-core/src/components/grid/stores/rows.js +++ b/packages/frontend-core/src/components/grid/stores/rows.js @@ -338,15 +338,11 @@ export const deriveStores = context => { ...state, [rowId]: true, })) - const newRow = { ...row, ...get(rowChangeCache)[rowId] } - const saved = await API.saveRow(newRow) + const saved = await API.saveRow({ ...row, ...get(rowChangeCache)[rowId] }) // Update state after a successful change rows.update(state => { - state[index] = { - ...newRow, - _rev: saved._rev, - } + state[index] = saved return state.slice() }) rowChangeCache.update(state => { From d146aae08421048081df090d0d9f19fe704fb8eb Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 10 May 2023 16:02:00 +0100 Subject: [PATCH 09/28] Treat formula cell as readonly! --- packages/frontend-core/src/components/grid/cells/DataCell.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/frontend-core/src/components/grid/cells/DataCell.svelte b/packages/frontend-core/src/components/grid/cells/DataCell.svelte index 0aa0cd54f4..f39b820632 100644 --- a/packages/frontend-core/src/components/grid/cells/DataCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/DataCell.svelte @@ -32,6 +32,7 @@ $: readonly = column.schema.autocolumn || column.schema.disabled || + column.schema.type === "formula" || (!$config.allowEditRows && row._id) // Register this cell API if the row is focused From 59ea4460f9ce211694468789e3adf23b661b3dca Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 11 May 2023 10:51:44 +0100 Subject: [PATCH 10/28] Fix multiple issues with keypresses and date cells due to flatpickr --- packages/bbui/src/Form/Core/DatePicker.svelte | 16 ++++++++-- .../src/components/grid/cells/DateCell.svelte | 29 +++++++++++++++++++ 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/packages/bbui/src/Form/Core/DatePicker.svelte b/packages/bbui/src/Form/Core/DatePicker.svelte index 2c89a538a3..ad39136142 100644 --- a/packages/bbui/src/Form/Core/DatePicker.svelte +++ b/packages/bbui/src/Form/Core/DatePicker.svelte @@ -18,10 +18,14 @@ export let ignoreTimezones = false export let time24hr = false export let range = false + export let flatpickr + export let useKeyboardShortcuts = true + const dispatch = createEventDispatcher() const flatpickrId = `${uuid()}-wrapper` + let open = false - let flatpickr, flatpickrOptions + let flatpickrOptions // Another classic flatpickr issue. Errors were randomly being thrown due to // flatpickr internal code. Making sure that "destroy" is a valid function @@ -59,6 +63,8 @@ dispatch("change", timestamp.toISOString()) } }, + onOpen: () => dispatch("open"), + onClose: () => dispatch("close"), } $: redrawOptions = { @@ -113,12 +119,16 @@ const onOpen = () => { open = true - document.addEventListener("keyup", clearDateOnBackspace) + if (useKeyboardShortcuts) { + document.addEventListener("keyup", clearDateOnBackspace) + } } const onClose = () => { open = false - document.removeEventListener("keyup", clearDateOnBackspace) + if (useKeyboardShortcuts) { + document.removeEventListener("keyup", clearDateOnBackspace) + } // Manually blur all input fields since flatpickr creates a second // duplicate input field. diff --git a/packages/frontend-core/src/components/grid/cells/DateCell.svelte b/packages/frontend-core/src/components/grid/cells/DateCell.svelte index 0112bcda15..f5b1acb1c8 100644 --- a/packages/frontend-core/src/components/grid/cells/DateCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/DateCell.svelte @@ -1,12 +1,17 @@
@@ -42,6 +67,10 @@ {timeOnly} time24hr ignoreTimezones={schema.ignoreTimezones} + bind:flatpickr + on:open={() => (isOpen = true)} + on:close={() => (isOpen = false)} + useKeyboardShortcuts={false} />
{/if} From 5a0ae3ff01f1dc72c03d12e31c1ab0379dca884d Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 11 May 2023 11:58:26 +0100 Subject: [PATCH 11/28] Disable most context menu options for cells in the new row --- .../src/components/grid/overlays/MenuOverlay.svelte | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/frontend-core/src/components/grid/overlays/MenuOverlay.svelte b/packages/frontend-core/src/components/grid/overlays/MenuOverlay.svelte index d0379edee6..15ca08dbdf 100644 --- a/packages/frontend-core/src/components/grid/overlays/MenuOverlay.svelte +++ b/packages/frontend-core/src/components/grid/overlays/MenuOverlay.svelte @@ -7,6 +7,7 @@ notifications, } from "@budibase/bbui" import { getContext } from "svelte" + import { NewRowID } from "../lib/constants" const { focusedRow, @@ -20,9 +21,11 @@ clipboard, dispatch, focusedCellAPI, + focusedRowId, } = getContext("grid") $: style = makeStyle($menu) + $: isNewRow = $focusedRowId === NewRowID const makeStyle = menu => { return `left:${menu.left}px; top:${menu.top}px;` @@ -69,7 +72,7 @@
dispatch("edit-row", $focusedRow)} on:click={menu.actions.close} > @@ -77,7 +80,7 @@ copyToClipboard($focusedRow?._id)} on:click={menu.actions.close} > @@ -85,7 +88,7 @@ copyToClipboard($focusedRow?._rev)} on:click={menu.actions.close} > @@ -93,14 +96,14 @@ Duplicate row Delete row From 14906e762cec874d6534bef36b4baafee5a31643 Mon Sep 17 00:00:00 2001 From: Budibase Staging Release Bot <> Date: Thu, 11 May 2023 16:26:40 +0000 Subject: [PATCH 12/28] Bump version to 2.6.8-alpha.8 --- lerna.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lerna.json b/lerna.json index 5988c50af4..c9e10d93a6 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.6.8-alpha.7", + "version": "2.6.8-alpha.8", "npmClient": "yarn", "packages": [ "packages/backend-core", From 395cf4a667aa01319e668c41f151ffbd5781bbe5 Mon Sep 17 00:00:00 2001 From: melohagan <101575380+melohagan@users.noreply.github.com> Date: Thu, 11 May 2023 17:49:33 +0100 Subject: [PATCH 13/28] Add JSON payload support for Make and Zapier (#10529) * Rename Integromat to Make. Update logo. * Add JSON type for automations * Support deprecated values in JSON * Fix json query editor width bug * Push body to schema if missing * Support JSON body * Add JSON payload support for Zapier * Update packages/server/src/automations/steps/make.ts Co-authored-by: Martin McKeaveney * July -> November * Add unit tests --------- Co-authored-by: Martin McKeaveney --- .../SetupPanel/AutomationBlockSetup.svelte | 76 ++++++++++++++++++- .../components/integration/QueryEditor.svelte | 6 +- packages/server/src/automations/steps/make.ts | 19 ++++- .../server/src/automations/steps/zapier.ts | 19 ++++- .../server/src/automations/tests/make.spec.ts | 54 +++++++++++++ .../src/automations/tests/zapier.spec.js | 27 ------- .../src/automations/tests/zapier.spec.ts | 56 ++++++++++++++ .../types/src/documents/app/automation.ts | 1 + 8 files changed, 227 insertions(+), 31 deletions(-) create mode 100644 packages/server/src/automations/tests/make.spec.ts delete mode 100644 packages/server/src/automations/tests/zapier.spec.js create mode 100644 packages/server/src/automations/tests/zapier.spec.ts diff --git a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte index 70cb56c77d..35c9c6ad6d 100644 --- a/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte +++ b/packages/builder/src/components/automation/SetupPanel/AutomationBlockSetup.svelte @@ -61,11 +61,63 @@ $: isTrigger = block?.type === "TRIGGER" $: isUpdateRow = stepId === ActionStepID.UPDATE_ROW + /** + * TODO - Remove after November 2023 + * ******************************* + * Code added to provide backwards compatibility between Values 1,2,3,4,5 + * and the new JSON body. + */ + let deprecatedSchemaProperties + $: { + if (block?.stepId === "integromat" || block?.stepId === "zapier") { + deprecatedSchemaProperties = schemaProperties.filter( + prop => !prop[0].startsWith("value") + ) + if (!deprecatedSchemaProperties.map(entry => entry[0]).includes("body")) { + deprecatedSchemaProperties.push([ + "body", + { + title: "Payload", + type: "json", + }, + ]) + } + } else { + deprecatedSchemaProperties = schemaProperties + } + } + /****************************************************/ + const getInputData = (testData, blockInputs) => { let newInputData = testData || blockInputs if (block.event === "app:trigger" && !newInputData?.fields) { newInputData = cloneDeep(blockInputs) } + + /** + * TODO - Remove after November 2023 + * ******************************* + * Code added to provide backwards compatibility between Values 1,2,3,4,5 + * and the new JSON body. + */ + if ( + (block?.stepId === "integromat" || block?.stepId === "zapier") && + !newInputData?.body?.value + ) { + let deprecatedValues = { + ...newInputData, + } + delete deprecatedValues.url + delete deprecatedValues.body + newInputData = { + url: newInputData.url, + body: { + value: JSON.stringify(deprecatedValues), + }, + } + } + /**********************************/ + inputData = newInputData setDefaultEnumValues() } @@ -239,7 +291,7 @@
- {#each schemaProperties as [key, value]} + {#each deprecatedSchemaProperties as [key, value]}
{#if key !== "fields"}