diff --git a/lerna.json b/lerna.json index 33b8ef3fc1..06a5bb0b51 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 7aab95245c..4a720a3b99 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "description": "Budibase backend core libraries used in server and worker", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", @@ -20,7 +20,7 @@ "test:watch": "jest --watchAll" }, "dependencies": { - "@budibase/types": "^1.1.22-alpha.0", + "@budibase/types": "^1.1.25-alpha.1", "@techpass/passport-openidconnect": "0.3.2", "aws-sdk": "2.1030.0", "bcrypt": "5.0.1", diff --git a/packages/backend-core/src/cache/writethrough.ts b/packages/backend-core/src/cache/writethrough.ts index e11ca0acaa..ec6b1604c8 100644 --- a/packages/backend-core/src/cache/writethrough.ts +++ b/packages/backend-core/src/cache/writethrough.ts @@ -1,5 +1,6 @@ import BaseCache from "./base" import { getWritethroughClient } from "../redis/init" +import { logWarn } from "../logging" const DEFAULT_WRITE_RATE_MS = 10000 let CACHE: BaseCache | null = null @@ -51,10 +52,8 @@ export async function put( if (err.status !== 409) { throw err } else { - // get the rev, update over it - this is risky, may change in future - const readDoc = await db.get(doc._id) - doc._rev = readDoc._rev - await writeDb(doc) + // Swallow 409s but log them + logWarn(`Ignoring conflict in write-through cache`) } } } diff --git a/packages/backend-core/src/logging.ts b/packages/backend-core/src/logging.ts index 68c3307b2f..8eda15ac79 100644 --- a/packages/backend-core/src/logging.ts +++ b/packages/backend-core/src/logging.ts @@ -15,6 +15,11 @@ export function logAlert(message: string, e?: any) { console.error(`bb-alert: ${message} ${errorJson}`) } +export function logWarn(message: string) { + console.warn(`bb-warn: ${message}`) +} + export default { logAlert, + logWarn, } diff --git a/packages/bbui/package.json b/packages/bbui/package.json index 80489d5b9a..17fe308465 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": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "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": "^1.1.22-alpha.0", + "@budibase/string-templates": "^1.1.25-alpha.1", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/bbui/src/Tooltip/Tooltip.svelte b/packages/bbui/src/Tooltip/Tooltip.svelte index 50a3242d1e..ea511b0060 100644 --- a/packages/bbui/src/Tooltip/Tooltip.svelte +++ b/packages/bbui/src/Tooltip/Tooltip.svelte @@ -26,5 +26,9 @@ diff --git a/packages/builder/cypress/integration/adminAndManagement/userManagement.spec.js b/packages/builder/cypress/integration/adminAndManagement/userManagement.spec.js index 562e1e149f..d6a49fe54e 100644 --- a/packages/builder/cypress/integration/adminAndManagement/userManagement.spec.js +++ b/packages/builder/cypress/integration/adminAndManagement/userManagement.spec.js @@ -57,6 +57,7 @@ filterTests(["smoke", "all"], () => { cy.visit(`${Cypress.config().baseUrl}/builder`, { timeout: 5000}) cy.get(interact.SPECTRUM_SIDENAV).contains("Users").click() cy.get(interact.SPECTRUM_TABLE, { timeout: 1000 }).contains("bbuser").click() + cy.get(interact.SPECTRUM_HEADING).contains("bbuser", { timeout: 2000}) for (let i = 0; i < 3; i++) { cy.get(interact.SPECTRUM_TABLE, { timeout: 3000}) .eq(1) diff --git a/packages/builder/cypress/integration/datasources/postgreSql.spec.js b/packages/builder/cypress/integration/datasources/postgreSql.spec.js index 0c3f2b9124..978c763203 100644 --- a/packages/builder/cypress/integration/datasources/postgreSql.spec.js +++ b/packages/builder/cypress/integration/datasources/postgreSql.spec.js @@ -150,7 +150,9 @@ filterTests(["all"], () => { cy.get("@query").its("response.statusCode").should("eq", 200) cy.get("@query").its("response.body").should("not.be.empty") // Save query + cy.intercept("**/queries").as("saveQuery") cy.get(".spectrum-Button").contains("Save Query").click({ force: true }) + cy.wait("@saveQuery") cy.get(".spectrum-Tabs-content", { timeout: 2000 }).should("contain", queryName) }) diff --git a/packages/builder/cypress/integration/revertApp.spec.js b/packages/builder/cypress/integration/revertApp.spec.js index 006b6854ba..9a3d17f7c3 100644 --- a/packages/builder/cypress/integration/revertApp.spec.js +++ b/packages/builder/cypress/integration/revertApp.spec.js @@ -15,7 +15,7 @@ filterTests(['smoke', 'all'], () => { }) cy.get(interact.SPECTRUM_MODAL).within(() => { // Enter app name before revert - cy.get("input").type("Cypress Tests") + cy.get(interact.SPECTRUM_TEXTFIELD_INPUT).type("Cypress Tests") cy.intercept('**/revert').as('revertApp') // Click Revert cy.get(interact.SPECTRUM_BUTTON).contains("Revert").click({ force: true }) diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index cc92ca280a..9688894d24 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -289,7 +289,7 @@ Cypress.Commands.add("updateAppName", (changedName, noName) => { }) Cypress.Commands.add("publishApp", resolvedAppPath => { - //Assumes you have navigated to an application first + // Assumes you have navigated to an application first cy.get(".toprightnav button.spectrum-Button") .contains("Publish") .click({ force: true }) @@ -301,7 +301,7 @@ Cypress.Commands.add("publishApp", resolvedAppPath => { cy.wait(1000) }) - //Verify that the app url is presented correctly to the user + // Verify that the app url is presented correctly to the user cy.get(".spectrum-Modal [data-cy='deploy-app-success-modal']") .should("be.visible") .within(() => { @@ -422,7 +422,12 @@ Cypress.Commands.add("createTable", (tableName, initialTable) => { cy.get("input", { timeout: 2000 }).first().type(tableName).blur() cy.get(".spectrum-ButtonGroup").contains("Create").click() }) - cy.contains(tableName).should("be.visible") + // Ensure modal has closed and table is created + cy.get(".spectrum-Modal").should("not.exist") + cy.get(".spectrum-Tabs-content", { timeout: 1000 }).should( + "contain", + tableName + ) }) Cypress.Commands.add("createTestTableWithData", () => { @@ -514,7 +519,8 @@ Cypress.Commands.add("searchAndAddComponent", component => { cy.get(".spectrum-Button").contains("Component").click({ force: true }) // Search and add component - cy.get(".spectrum-Textfield-input").wait(500).clear().type(component) + cy.wait(500) + cy.get(".spectrum-Textfield-input").clear().type(component) cy.get(".body").within(() => { cy.get(".component") .contains(new RegExp("^" + component + "$"), { timeout: 3000 }) diff --git a/packages/builder/cypress/support/interact.js b/packages/builder/cypress/support/interact.js index b96e2692b4..3f2f348847 100644 --- a/packages/builder/cypress/support/interact.js +++ b/packages/builder/cypress/support/interact.js @@ -108,6 +108,7 @@ export const CONTAINER = ".container" export const REGENERATE = ".regenerate" export const SPECTRUM_DIALOG_CONTENT = ".spectrum-Dialog-content" export const SPECTRUM_ICON = ".spectrum-Icon" +export const SPECTRUM_HEADING = ".spectrum-Heading" //createView export const SPECTRUM_MENU_ITEM_LABEL = ".spectrum-Menu-itemLabel" diff --git a/packages/builder/package.json b/packages/builder/package.json index 093dddbf50..4564d5cc22 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "license": "GPL-3.0", "private": true, "scripts": { @@ -69,10 +69,10 @@ } }, "dependencies": { - "@budibase/bbui": "^1.1.22-alpha.0", - "@budibase/client": "^1.1.22-alpha.0", - "@budibase/frontend-core": "^1.1.22-alpha.0", - "@budibase/string-templates": "^1.1.22-alpha.0", + "@budibase/bbui": "^1.1.25-alpha.1", + "@budibase/client": "^1.1.25-alpha.1", + "@budibase/frontend-core": "^1.1.25-alpha.1", + "@budibase/string-templates": "^1.1.25-alpha.1", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/builder/src/builderStore/store/theme.js b/packages/builder/src/builderStore/store/theme.js index bd3a149d63..54323ba55f 100644 --- a/packages/builder/src/builderStore/store/theme.js +++ b/packages/builder/src/builderStore/store/theme.js @@ -1,11 +1,10 @@ -import { createLocalStorageStore } from "@budibase/frontend-core" +import { Constants, createLocalStorageStore } from "@budibase/frontend-core" export const getThemeStore = () => { const themeElement = document.documentElement const initialValue = { theme: "darkest", - options: ["lightest", "light", "dark", "darkest", "nord"], } const store = createLocalStorageStore("bb-theme", initialValue) @@ -17,11 +16,14 @@ export const getThemeStore = () => { return } - state.options.forEach(option => { + Constants.ThemeOptions.forEach(option => { themeElement.classList.toggle( `spectrum--${option}`, option === state.theme ) + + // Ensure darkest is always added as this is the base class for custom + // themes themeElement.classList.add("spectrum--darkest") }) }) diff --git a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte index 412683721f..c1618a890f 100644 --- a/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte +++ b/packages/builder/src/components/automation/AutomationBuilder/FlowChart/FlowItem.svelte @@ -52,8 +52,9 @@ x => x.blockToLoop === block.id ) - $: setPermissions(role) - $: getPermissions(automationId) + $: isAppAction = block?.stepId === TriggerStepID.APP + $: isAppAction && setPermissions(role) + $: isAppAction && getPermissions(automationId) async function setPermissions(role) { if (!role || !automationId) { @@ -238,7 +239,7 @@ {/if} - {#if block.stepId === TriggerStepID.APP} + {#if isAppAction} Role {/if} diff --git a/packages/builder/src/main.js b/packages/builder/src/main.js index bc5ec4f009..dc1e1cf1bf 100644 --- a/packages/builder/src/main.js +++ b/packages/builder/src/main.js @@ -5,6 +5,8 @@ import "@spectrum-css/vars/dist/spectrum-darkest.css" import "@spectrum-css/vars/dist/spectrum-dark.css" import "@spectrum-css/vars/dist/spectrum-light.css" import "@spectrum-css/vars/dist/spectrum-lightest.css" +import "@budibase/frontend-core/src/themes/nord.css" +import "@budibase/frontend-core/src/themes/midnight.css" import "@spectrum-css/page/dist/index-vars.css" import "./global.css" import { suppressWarnings } from "./helpers/warnings" diff --git a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/ComponentListPanel.svelte b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/ComponentListPanel.svelte index 5b86d4da29..1bb4e3d9cd 100644 --- a/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/ComponentListPanel.svelte +++ b/packages/builder/src/pages/builder/app/[application]/design/[screenId]/components/[componentId]/_components/navigation/ComponentListPanel.svelte @@ -9,6 +9,7 @@ import { setContext } from "svelte" import DNDPositionIndicator from "./DNDPositionIndicator.svelte" import { DropPosition } from "./dndStore" + import { notifications } from "@budibase/bbui" let scrollRef @@ -55,6 +56,15 @@ }) } + const onDrop = async () => { + try { + await dndStore.actions.drop() + } catch (error) { + console.error(error) + notifications.error("Error saving component") + } + } + // Set scroll context so components can invoke scrolling when selected setContext("scroll", { scrollTo, @@ -83,6 +93,7 @@ opened scrollable icon="WebPage" + on:drop={onDrop} > diff --git a/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte b/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte index 293f19ebe4..b2dac7682f 100644 --- a/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte +++ b/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte @@ -139,9 +139,10 @@ notifications.success("App ID copied to clipboard.") } - const exportApp = app => { - const id = isPublished ? app.prodId : app.devId + const exportApp = (app, opts = { published: false }) => { const appName = encodeURIComponent(app.name) + const id = opts?.published ? app.prodId : app.devId + // always export the development version window.location = `/api/backups/export?appId=${id}&appname=${appName}` } @@ -266,12 +267,21 @@ - exportApp(selectedApp)} icon="Download"> - Export + exportApp(selectedApp, { published: false })} + icon="DownloadFromCloud" + > + Export latest {#if isPublished} + exportApp(selectedApp, { published: true })} + icon="DownloadFromCloudOutline" + > + Export published + copyAppId(selectedApp)} icon="Copy"> - Copy App ID + Copy app ID {/if} {#if !isPublished} diff --git a/packages/builder/src/pages/builder/portal/settings/theming.svelte b/packages/builder/src/pages/builder/portal/settings/theming.svelte index 2a2aaa8a3b..2a8e82f0e5 100644 --- a/packages/builder/src/pages/builder/portal/settings/theming.svelte +++ b/packages/builder/src/pages/builder/portal/settings/theming.svelte @@ -2,6 +2,7 @@ import { Layout, Heading, Body, Divider, Label, Select } from "@budibase/bbui" import { themeStore } from "builderStore" import { capitalise } from "helpers" + import { Constants } from "@budibase/frontend-core" @@ -14,7 +15,7 @@ Builder theme diff --git a/packages/client/src/components/app/blocks/CardsBlock.svelte b/packages/client/src/components/app/blocks/CardsBlock.svelte index f6aed54760..a13364833a 100644 --- a/packages/client/src/components/app/blocks/CardsBlock.svelte +++ b/packages/client/src/components/app/blocks/CardsBlock.svelte @@ -4,6 +4,7 @@ import BlockComponent from "components/BlockComponent.svelte" import { Heading } from "@budibase/bbui" import { makePropSafe as safe } from "@budibase/string-templates" + import { enrichSearchColumns, enrichFilter } from "utils/blocks.js" export let title export let dataSource @@ -33,14 +34,6 @@ const { fetchDatasourceSchema, styleable } = getContext("sdk") const context = getContext("context") const component = getContext("component") - const schemaComponentMap = { - string: "stringfield", - options: "optionsfield", - number: "numberfield", - datetime: "datetimefield", - boolean: "booleanfield", - formula: "stringfield", - } let formId let dataProviderId @@ -68,39 +61,6 @@ }, ] - // Enrich the default filter with the specified search fields - const enrichFilter = (filter, columns, formId) => { - let enrichedFilter = [...(filter || [])] - columns?.forEach(column => { - const safePath = column.name.split(".").map(safe).join(".") - enrichedFilter.push({ - field: column.name, - operator: column.type === "string" ? "string" : "equal", - type: column.type, - valueType: "Binding", - value: `{{ ${safe(formId)}.${safePath} }}`, - }) - }) - return enrichedFilter - } - - // Determine data types for search fields and only use those that are valid - const enrichSearchColumns = (searchColumns, schema) => { - let enrichedColumns = [] - searchColumns?.forEach(column => { - const schemaType = schema?.[column]?.type - const componentType = schemaComponentMap[schemaType] - if (componentType) { - enrichedColumns.push({ - name: column, - componentType, - type: schemaType, - }) - } - }) - return enrichedColumns.slice(0, 5) - } - // Builds a full details page URL for the card title const buildFullCardUrl = (link, url, repeaterId, linkColumn) => { if (!link || !url || !repeaterId) { diff --git a/packages/client/src/components/app/blocks/TableBlock.svelte b/packages/client/src/components/app/blocks/TableBlock.svelte index 4ae169ca72..e67124fc4f 100644 --- a/packages/client/src/components/app/blocks/TableBlock.svelte +++ b/packages/client/src/components/app/blocks/TableBlock.svelte @@ -4,6 +4,7 @@ import BlockComponent from "components/BlockComponent.svelte" import { Heading } from "@budibase/bbui" import { makePropSafe as safe } from "@budibase/string-templates" + import { enrichSearchColumns, enrichFilter } from "utils/blocks.js" export let title export let dataSource @@ -31,14 +32,6 @@ const { fetchDatasourceSchema, styleable } = getContext("sdk") const context = getContext("context") const component = getContext("component") - const schemaComponentMap = { - string: "stringfield", - options: "optionsfield", - number: "numberfield", - datetime: "datetimefield", - boolean: "booleanfield", - formula: "stringfield", - } let formId let dataProviderId @@ -58,40 +51,6 @@ }, ] - // Enrich the default filter with the specified search fields - const enrichFilter = (filter, columns, formId) => { - let enrichedFilter = [...(filter || [])] - columns?.forEach(column => { - const safePath = column.name.split(".").map(safe).join(".") - const stringType = column.type === "string" || column.type === "formula" - enrichedFilter.push({ - field: column.name, - type: column.type, - operator: stringType ? "string" : "equal", - valueType: "Binding", - value: `{{ ${safe(formId)}.${safePath} }}`, - }) - }) - return enrichedFilter - } - - // Determine data types for search fields and only use those that are valid - const enrichSearchColumns = (searchColumns, schema) => { - let enrichedColumns = [] - searchColumns?.forEach(column => { - const schemaType = schema?.[column]?.type - const componentType = schemaComponentMap[schemaType] - if (componentType) { - enrichedColumns.push({ - name: column, - componentType, - type: schemaType, - }) - } - }) - return enrichedColumns.slice(0, 5) - } - // Load the datasource schema so we can determine column types const fetchSchema = async dataSource => { if (dataSource) { @@ -109,7 +68,7 @@ {#if title || enrichedSearchColumns?.length || showTitleButton} diff --git a/packages/client/src/components/app/forms/Form.svelte b/packages/client/src/components/app/forms/Form.svelte index a274fb24f0..320fc712aa 100644 --- a/packages/client/src/components/app/forms/Form.svelte +++ b/packages/client/src/components/app/forms/Form.svelte @@ -13,6 +13,10 @@ // for fields rendered in things like search blocks. export let disableValidation = false + // Not exposed as a builder setting. Used internally to allow searching on + // auto columns. + export let editAutoColumns = false + const context = getContext("context") const { API, fetchDatasourceSchema } = getContext("sdk") @@ -107,6 +111,7 @@ {table} {initialValues} {disableValidation} + {editAutoColumns} > diff --git a/packages/client/src/components/app/forms/InnerForm.svelte b/packages/client/src/components/app/forms/InnerForm.svelte index 752bc9a2eb..316b697043 100644 --- a/packages/client/src/components/app/forms/InnerForm.svelte +++ b/packages/client/src/components/app/forms/InnerForm.svelte @@ -11,6 +11,7 @@ export let schema export let table export let disableValidation = false + export let editAutoColumns = false const component = getContext("component") const { styleable, Provider, ActionTypes } = getContext("sdk") @@ -183,7 +184,8 @@ fieldId, value: initialValue, error: initialError, - disabled: disabled || fieldDisabled || isAutoColumn, + disabled: + disabled || fieldDisabled || (isAutoColumn && !editAutoColumns), defaultValue, validator, lastUpdate: Date.now(), diff --git a/packages/client/src/components/app/index.js b/packages/client/src/components/app/index.js index db8cc43ef6..c7b8f18643 100644 --- a/packages/client/src/components/app/index.js +++ b/packages/client/src/components/app/index.js @@ -1,10 +1,10 @@ import "@spectrum-css/vars/dist/spectrum-global.css" import "@spectrum-css/vars/dist/spectrum-medium.css" import "@spectrum-css/vars/dist/spectrum-large.css" -import "@spectrum-css/vars/dist/spectrum-lightest.css" -import "@spectrum-css/vars/dist/spectrum-light.css" -import "@spectrum-css/vars/dist/spectrum-dark.css" import "@spectrum-css/vars/dist/spectrum-darkest.css" +import "@spectrum-css/vars/dist/spectrum-dark.css" +import "@spectrum-css/vars/dist/spectrum-light.css" +import "@spectrum-css/vars/dist/spectrum-lightest.css" import "@spectrum-css/page/dist/index-vars.css" // Non user-facing components @@ -35,6 +35,7 @@ export { default as embeddedmap } from "./embedded-map/EmbeddedMap.svelte" export * from "./charts" export * from "./forms" export * from "./table" + export * from "./blocks" export * from "./dynamic-filter" diff --git a/packages/client/src/utils/blocks.js b/packages/client/src/utils/blocks.js new file mode 100644 index 0000000000..3b97544238 --- /dev/null +++ b/packages/client/src/utils/blocks.js @@ -0,0 +1,81 @@ +import { makePropSafe as safe } from "@budibase/string-templates" + +// Map of data types to component types for search fields inside blocks +const schemaComponentMap = { + string: "stringfield", + options: "optionsfield", + number: "numberfield", + datetime: "datetimefield", + boolean: "booleanfield", + formula: "stringfield", +} + +/** + * Determine data types for search fields and only use those that are valid + * @param searchColumns the search columns to use + * @param schema the data source schema + */ +export const enrichSearchColumns = (searchColumns, schema) => { + let enrichedColumns = [] + searchColumns?.forEach(column => { + const schemaType = schema?.[column]?.type + const componentType = schemaComponentMap[schemaType] + if (componentType) { + enrichedColumns.push({ + name: column, + componentType, + type: schemaType, + }) + } + }) + return enrichedColumns.slice(0, 5) +} + +/** + * Enriches a normal datasource filter with bindings representing the additional + * search fields configured as part of a searchable block. These bindings are + * fields inside a form used as part of the block. + * @param filter the normal data provider filter + * @param columns the enriched search column structure + * @param formId the ID of the form containing the search fields + */ +export const enrichFilter = (filter, columns, formId) => { + let enrichedFilter = [...(filter || [])] + columns?.forEach(column => { + const safePath = column.name.split(".").map(safe).join(".") + const stringType = column.type === "string" || column.type === "formula" + const dateType = column.type === "datetime" + const binding = `${safe(formId)}.${safePath}` + + // For dates, use a range of the entire day selected + if (dateType) { + enrichedFilter.push({ + field: column.name, + type: column.type, + operator: "rangeLow", + valueType: "Binding", + value: `{{ ${binding} }}`, + }) + const format = "YYYY-MM-DDTHH:mm:ss.SSSZ" + enrichedFilter.push({ + field: column.name, + type: column.type, + operator: "rangeHigh", + valueType: "Binding", + value: `{{ date (add (date ${binding} "x") 86399999) "${format}" }}`, + }) + } + + // For other fields, do an exact match + else { + enrichedFilter.push({ + field: column.name, + type: column.type, + operator: stringType ? "string" : "equal", + valueType: "Binding", + value: `{{ ${binding} }}`, + }) + } + }) + return enrichedFilter +} diff --git a/packages/frontend-core/package.json b/packages/frontend-core/package.json index cc46521e82..1c1f8c47aa 100644 --- a/packages/frontend-core/package.json +++ b/packages/frontend-core/package.json @@ -1,12 +1,12 @@ { "name": "@budibase/frontend-core", - "version": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "description": "Budibase frontend core libraries used in builder and client", "author": "Budibase", "license": "MPL-2.0", "svelte": "src/index.js", "dependencies": { - "@budibase/bbui": "^1.1.22-alpha.0", + "@budibase/bbui": "^1.1.25-alpha.1", "lodash": "^4.17.21", "svelte": "^3.46.2" } diff --git a/packages/frontend-core/src/constants.js b/packages/frontend-core/src/constants.js index 1d3c31f54d..71c9019750 100644 --- a/packages/frontend-core/src/constants.js +++ b/packages/frontend-core/src/constants.js @@ -98,3 +98,12 @@ export const SqlNumberTypeRangeMap = { min: -8388608, }, } + +export const ThemeOptions = [ + "lightest", + "light", + "dark", + "darkest", + "nord", + "midnight", +] diff --git a/packages/frontend-core/src/themes/midnight.css b/packages/frontend-core/src/themes/midnight.css new file mode 100644 index 0000000000..528d847702 --- /dev/null +++ b/packages/frontend-core/src/themes/midnight.css @@ -0,0 +1,16 @@ +.spectrum--midnight { + --hue: 220; + --sat: 10%; + --spectrum-global-color-gray-50: hsl(var(--hue), var(--sat), 12%); + --spectrum-global-color-gray-75: hsl(var(--hue), var(--sat), 15%); + --spectrum-global-color-gray-100: hsl(var(--hue), var(--sat), 17%); + --spectrum-global-color-gray-200: hsl(var(--hue), var(--sat), 20%); + --spectrum-global-color-gray-300: hsl(var(--hue), var(--sat), 24%); + --spectrum-global-color-gray-400: hsl(var(--hue), var(--sat), 32%); + --spectrum-global-color-gray-500: hsl(var(--hue), var(--sat), 40%); + --spectrum-global-color-gray-600: hsl(var(--hue), var(--sat), 60%); + --spectrum-global-color-gray-700: hsl(var(--hue), var(--sat), 70%); + --spectrum-global-color-gray-800: hsl(var(--hue), var(--sat), 80%); + --spectrum-global-color-gray-900: hsl(var(--hue), var(--sat), 95%); +} + diff --git a/packages/frontend-core/src/themes/nord.css b/packages/frontend-core/src/themes/nord.css new file mode 100644 index 0000000000..113adfb853 --- /dev/null +++ b/packages/frontend-core/src/themes/nord.css @@ -0,0 +1,46 @@ +.spectrum--nord { + --spectrum-global-color-red-400: #bf616a; + --spectrum-global-color-red-500: #c26971; + --spectrum-global-color-red-600: #c57179; + --spectrum-global-color-red-700: #c97980; + --spectrum-global-color-static-red-400: #bf616a; + --spectrum-global-color-static-red-500: #c26971; + --spectrum-global-color-static-red-600: #c57179; + --spectrum-global-color-static-red-700: #c97980; + + --spectrum-global-color-green-400: #719453; + --spectrum-global-color-green-500: #789d58; + --spectrum-global-color-green-600: #7fa55e; + --spectrum-global-color-green-700: #86aa67; + --spectrum-global-color-static-green-400: #719453; + --spectrum-global-color-static-green-500: #789d58; + --spectrum-global-color-static-green-600: #7fa55e; + --spectrum-global-color-static-green-700: #86aa67; + + --spectrum-global-color-blue-400: #5680b4; + --spectrum-global-color-blue-500: #5e86b8; + --spectrum-global-color-blue-600: #668dbb; + --spectrum-global-color-blue-700: #6f93bf; + --spectrum-global-color-static-blue-200: #7799c4; + --spectrum-global-color-static-blue-300: #6f93bf; + --spectrum-global-color-static-blue-400: #668dbb; + --spectrum-global-color-static-blue-500: #5e86b8; + --spectrum-global-color-static-blue-600: #5680b4; + --spectrum-global-color-static-blue-700: #4e79af; + --spectrum-global-color-static-blue-800: #4a73a6; + + --spectrum-global-color-gray-50: #2e3440; + --spectrum-global-color-gray-75: #353b4a; + --spectrum-global-color-gray-100: #3b4252; + --spectrum-global-color-gray-200: #4a5367; + --spectrum-global-color-gray-300: #4c566a; + --spectrum-global-color-gray-400: #5a657d; + --spectrum-global-color-gray-500: #677590; + --spectrum-global-color-gray-600: #79869f; + --spectrum-global-color-gray-700: #a9b1c1; + --spectrum-global-color-gray-800: #bac1cd; + --spectrum-global-color-gray-900: #eceff4; + + --spectrum-alias-highlight-hover: rgba(169, 177, 193, 0.06); + --spectrum-alias-highlight-active: rgba(169, 177, 193, 0.1); +} diff --git a/packages/frontend-core/src/utils/lucene.js b/packages/frontend-core/src/utils/lucene.js index 1001ec26a8..b27296af37 100644 --- a/packages/frontend-core/src/utils/lucene.js +++ b/packages/frontend-core/src/utils/lucene.js @@ -99,8 +99,16 @@ export const buildLuceneQuery = filter => { filter.forEach(expression => { let { operator, field, type, value, externalType } = expression // Parse all values into correct types - if (type === "datetime" && value) { - value = new Date(value).toISOString() + if (type === "datetime") { + // Ensure date value is a valid date and parse into correct format + if (!value) { + return + } + try { + value = new Date(value).toISOString() + } catch (error) { + return + } } if (type === "number" && !Array.isArray(value)) { if (operator === "oneOf") { diff --git a/packages/server/package.json b/packages/server/package.json index 4d20aca05c..1ba3fc1df9 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/server", "email": "hi@budibase.com", - "version": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "description": "Budibase Web Server", "main": "src/index.ts", "repository": { @@ -77,11 +77,11 @@ "license": "GPL-3.0", "dependencies": { "@apidevtools/swagger-parser": "10.0.3", - "@budibase/backend-core": "^1.1.22-alpha.0", - "@budibase/client": "^1.1.22-alpha.0", - "@budibase/pro": "1.1.22-alpha.0", - "@budibase/string-templates": "^1.1.22-alpha.0", - "@budibase/types": "^1.1.22-alpha.0", + "@budibase/backend-core": "^1.1.25-alpha.1", + "@budibase/client": "^1.1.25-alpha.1", + "@budibase/pro": "1.1.25-alpha.1", + "@budibase/string-templates": "^1.1.25-alpha.1", + "@budibase/types": "^1.1.25-alpha.1", "@bull-board/api": "3.7.0", "@bull-board/koa": "3.9.4", "@elastic/elasticsearch": "7.10.0", diff --git a/packages/server/src/utilities/fileSystem/index.js b/packages/server/src/utilities/fileSystem/index.js index ed1cb1923a..f4aebd11a8 100644 --- a/packages/server/src/utilities/fileSystem/index.js +++ b/packages/server/src/utilities/fileSystem/index.js @@ -111,20 +111,12 @@ exports.apiFileReturn = contents => { } exports.defineFilter = excludeRows => { + const ids = [USER_METDATA_PREFIX, LINK_USER_METADATA_PREFIX] if (excludeRows) { - return doc => - !( - doc._id.includes(USER_METDATA_PREFIX) || - doc._id.includes(LINK_USER_METADATA_PREFIX) || - doc._id.includes(TABLE_ROW_PREFIX) - ) - } else if (!excludeRows) { - return doc => - !( - doc._id.includes(USER_METDATA_PREFIX) || - doc._id.includes(LINK_USER_METADATA_PREFIX) - ) + ids.push(TABLE_ROW_PREFIX) } + return doc => + !ids.map(key => doc._id.includes(key)).reduce((prev, curr) => prev || curr) } /** @@ -132,6 +124,7 @@ exports.defineFilter = excludeRows => { * data or user relationships. * @param {string} appId The app to backup * @param {object} config Config to send to export DB + * @param {boolean} includeRows Flag to state whether the export should include data. * @returns {*} either a string or a stream of the backup */ const backupAppData = async (appId, config, includeRows) => { @@ -154,6 +147,7 @@ exports.performBackup = async (appId, backupName) => { /** * Streams a backup of the database state for an app * @param {string} appId The ID of the app which is to be backed up. + * @param {boolean} includeRows Flag to state whether the export should include data. * @returns {*} a readable stream of the backup which is written in real time */ exports.streamBackup = async (appId, includeRows) => { diff --git a/packages/server/yarn.lock b/packages/server/yarn.lock index fe229cc137..6d285201db 100644 --- a/packages/server/yarn.lock +++ b/packages/server/yarn.lock @@ -1094,12 +1094,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@1.1.22-alpha.0": - version "1.1.22-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.1.22-alpha.0.tgz#2a090a723d35ce4a2e377ac0927fe127213bcbb3" - integrity sha512-77gxcPrjejdqaMaMkbrCS0glYA1jdGo74NpCxdadWx+suU4SMTmOt2jgnEZg20aeKcky2xTpVbjDxIq+Fb2J+g== +"@budibase/backend-core@1.1.24": + version "1.1.24" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.1.24.tgz#35b15c4a2ff3eaed0a612ff04095017250a30e6d" + integrity sha512-Ab5Ju+2Cggfkz14+BasVgHSrxz73l6U6EtcF2Lb8EwkoLHYUT8llhW4hgrO6fXt5QaQ7mhsoiTUZesyn8Xy/Bg== dependencies: - "@budibase/types" "^1.1.22-alpha.0" + "@budibase/types" "^1.1.24" "@techpass/passport-openidconnect" "0.3.2" aws-sdk "2.1030.0" bcrypt "5.0.1" @@ -1177,13 +1177,13 @@ svelte-flatpickr "^3.2.3" svelte-portal "^1.0.0" -"@budibase/pro@1.1.22-alpha.0": - version "1.1.22-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.1.22-alpha.0.tgz#5718188fbc76ce3c3cf3c633c99c6e59f5846310" - integrity sha512-QL5bhT/BJnoKVV5XH5+s3jSCBzV/JGOy8YQObEjZgCrtTWUjdvMrm5pFinflFGriCfoArmvR3Q51FBpNJQfaag== +"@budibase/pro@1.1.24": + version "1.1.24" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.1.24.tgz#4fd5d1b162308cb52d2cebbe9ede05b1f952b727" + integrity sha512-YGloe5IhBVRuGrGgRF1/qvmTICkxmwWAg7cxYPxBszI8IT7Ilisvsm2aBaDFfRYIe9bjzV2PzziiIkwA5qXlXw== dependencies: - "@budibase/backend-core" "1.1.22-alpha.0" - "@budibase/types" "1.1.22-alpha.0" + "@budibase/backend-core" "1.1.24" + "@budibase/types" "1.1.24" node-fetch "^2.6.1" "@budibase/standard-components@^0.9.139": @@ -1204,15 +1204,10 @@ svelte-apexcharts "^1.0.2" svelte-flatpickr "^3.1.0" -"@budibase/types@1.1.22-alpha.0": - version "1.1.22-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.1.22-alpha.0.tgz#85fb7f37773c710e8232c95104095c26a8dd22ca" - integrity sha512-1gRwAtjEl7Ug1jrYwD9Iudbfgs37nndEBEB6yVdNPKA5SpjG+Fwx30zp6R961zlx1vsSu4iMdwM8IbMsCM8p1g== - -"@budibase/types@^1.1.22-alpha.0": - version "1.1.22" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.1.22.tgz#a73a8315ad6a04bf0709f2b51cb35058442ce723" - integrity sha512-24sun/hZ2OJZdavhiJt+S8Aip+RdlKeTyUrkf7OuRCUqbxgEIR2J9QOKBSEumuckwTcpzJHBAm4P4G3dXX5Neg== +"@budibase/types@1.1.24", "@budibase/types@^1.1.24": + version "1.1.24" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.1.24.tgz#87aaab20dc2093b88e036ccb5385ee8a39167cf6" + integrity sha512-ZlzDDBN3uWHCy80lyIZt3IBZB2AQBDgFt9G8b6r5S2rNlPZJQ5u1m58bIcan3NbDNLQOjATZ9opkejIB2qcZnw== "@bull-board/api@3.7.0": version "3.7.0" diff --git a/packages/string-templates/package.json b/packages/string-templates/package.json index f7f497c786..be82ef6d9f 100644 --- a/packages/string-templates/package.json +++ b/packages/string-templates/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/string-templates", - "version": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "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 94a8040fab..ab34aa1c06 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/types", - "version": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "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 863814b3c6..c571e502a1 100644 --- a/packages/worker/package.json +++ b/packages/worker/package.json @@ -1,7 +1,7 @@ { "name": "@budibase/worker", "email": "hi@budibase.com", - "version": "1.1.22-alpha.0", + "version": "1.1.25-alpha.1", "description": "Budibase background service", "main": "src/index.ts", "repository": { @@ -35,10 +35,10 @@ "author": "Budibase", "license": "GPL-3.0", "dependencies": { - "@budibase/backend-core": "^1.1.22-alpha.0", - "@budibase/pro": "1.1.22-alpha.0", - "@budibase/string-templates": "^1.1.22-alpha.0", - "@budibase/types": "^1.1.22-alpha.0", + "@budibase/backend-core": "^1.1.25-alpha.1", + "@budibase/pro": "1.1.25-alpha.1", + "@budibase/string-templates": "^1.1.25-alpha.1", + "@budibase/types": "^1.1.25-alpha.1", "@koa/router": "8.0.8", "@sentry/node": "6.17.7", "@techpass/passport-openidconnect": "0.3.2", diff --git a/packages/worker/yarn.lock b/packages/worker/yarn.lock index 54b1330368..41b6835785 100644 --- a/packages/worker/yarn.lock +++ b/packages/worker/yarn.lock @@ -291,12 +291,12 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@budibase/backend-core@1.1.22-alpha.0": - version "1.1.22-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.1.22-alpha.0.tgz#2a090a723d35ce4a2e377ac0927fe127213bcbb3" - integrity sha512-77gxcPrjejdqaMaMkbrCS0glYA1jdGo74NpCxdadWx+suU4SMTmOt2jgnEZg20aeKcky2xTpVbjDxIq+Fb2J+g== +"@budibase/backend-core@1.1.24": + version "1.1.24" + resolved "https://registry.yarnpkg.com/@budibase/backend-core/-/backend-core-1.1.24.tgz#35b15c4a2ff3eaed0a612ff04095017250a30e6d" + integrity sha512-Ab5Ju+2Cggfkz14+BasVgHSrxz73l6U6EtcF2Lb8EwkoLHYUT8llhW4hgrO6fXt5QaQ7mhsoiTUZesyn8Xy/Bg== dependencies: - "@budibase/types" "^1.1.22-alpha.0" + "@budibase/types" "^1.1.24" "@techpass/passport-openidconnect" "0.3.2" aws-sdk "2.1030.0" bcrypt "5.0.1" @@ -324,24 +324,19 @@ uuid "8.3.2" zlib "1.0.5" -"@budibase/pro@1.1.22-alpha.0": - version "1.1.22-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.1.22-alpha.0.tgz#5718188fbc76ce3c3cf3c633c99c6e59f5846310" - integrity sha512-QL5bhT/BJnoKVV5XH5+s3jSCBzV/JGOy8YQObEjZgCrtTWUjdvMrm5pFinflFGriCfoArmvR3Q51FBpNJQfaag== +"@budibase/pro@1.1.24": + version "1.1.24" + resolved "https://registry.yarnpkg.com/@budibase/pro/-/pro-1.1.24.tgz#4fd5d1b162308cb52d2cebbe9ede05b1f952b727" + integrity sha512-YGloe5IhBVRuGrGgRF1/qvmTICkxmwWAg7cxYPxBszI8IT7Ilisvsm2aBaDFfRYIe9bjzV2PzziiIkwA5qXlXw== dependencies: - "@budibase/backend-core" "1.1.22-alpha.0" - "@budibase/types" "1.1.22-alpha.0" + "@budibase/backend-core" "1.1.24" + "@budibase/types" "1.1.24" node-fetch "^2.6.1" -"@budibase/types@1.1.22-alpha.0": - version "1.1.22-alpha.0" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.1.22-alpha.0.tgz#85fb7f37773c710e8232c95104095c26a8dd22ca" - integrity sha512-1gRwAtjEl7Ug1jrYwD9Iudbfgs37nndEBEB6yVdNPKA5SpjG+Fwx30zp6R961zlx1vsSu4iMdwM8IbMsCM8p1g== - -"@budibase/types@^1.1.22-alpha.0": - version "1.1.23" - resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.1.23.tgz#10894f08704def5d2b62b5b0158e714c43bb76ac" - integrity sha512-McTJZ+R0qGL3PR4Qi5UjYgn82VF1dIi08IIsZjnGbAwY+tt3aATv4uRyERk0fFC7s0IC4neoDs3Wh5zjKxZTSw== +"@budibase/types@1.1.24", "@budibase/types@^1.1.24": + version "1.1.24" + resolved "https://registry.yarnpkg.com/@budibase/types/-/types-1.1.24.tgz#87aaab20dc2093b88e036ccb5385ee8a39167cf6" + integrity sha512-ZlzDDBN3uWHCy80lyIZt3IBZB2AQBDgFt9G8b6r5S2rNlPZJQ5u1m58bIcan3NbDNLQOjATZ9opkejIB2qcZnw== "@cspotcode/source-map-consumer@0.8.0": version "0.8.0"