diff --git a/lerna.json b/lerna.json index 24172a05b0..1eeecc5051 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "2.1.32-alpha.3", + "version": "2.1.32-alpha.9", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/packages/backend-core/package.json b/packages/backend-core/package.json index 6a54c16c89..9f2a1a3888 100644 --- a/packages/backend-core/package.json +++ b/packages/backend-core/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/backend-core", - "version": "2.1.32-alpha.3", + "version": "2.1.32-alpha.9", "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": "2.1.32-alpha.3", + "@budibase/types": "2.1.32-alpha.9", "@shopify/jest-koa-mocks": "5.0.1", "@techpass/passport-openidconnect": "0.3.2", "aws-sdk": "2.1030.0", diff --git a/packages/backend-core/src/db/utils.ts b/packages/backend-core/src/db/utils.ts index 9920be7e55..04feafa008 100644 --- a/packages/backend-core/src/db/utils.ts +++ b/packages/backend-core/src/db/utils.ts @@ -171,7 +171,7 @@ export function getGlobalUserParams(globalId: any, otherProps: any = {}) { /** * Gets parameters for retrieving users, this is a utility function for the getDocParams function. */ -export function getUserMetadataParams(userId?: string, otherProps = {}) { +export function getUserMetadataParams(userId?: string | null, otherProps = {}) { return getRowParams(InternalTable.USER_METADATA, userId, otherProps) } @@ -244,7 +244,7 @@ export function getTemplateParams( * Generates a new role ID. * @returns {string} The new role ID which the role doc can be stored under. */ -export function generateRoleID(id: any) { +export function generateRoleID(id?: any) { return `${DocumentType.ROLE}${SEPARATOR}${id || newid()}` } diff --git a/packages/backend-core/src/migrations/migrations.ts b/packages/backend-core/src/migrations/migrations.ts index 60c17f4020..7bc2dec290 100644 --- a/packages/backend-core/src/migrations/migrations.ts +++ b/packages/backend-core/src/migrations/migrations.ts @@ -1,10 +1,13 @@ import { DEFAULT_TENANT_ID } from "../constants" -import { doWithDB } from "../db" -import { DocumentType, StaticDatabases } from "../db/constants" -import { getAllApps } from "../db/utils" +import { + DocumentType, + StaticDatabases, + getAllApps, + getGlobalDBName, + doWithDB, +} from "../db" import environment from "../environment" import { doInTenant, getTenantIds, getTenantId } from "../tenancy" -import { getGlobalDBName } from "../db/tenancy" import * as context from "../context" import { DEFINITIONS } from "." import { diff --git a/packages/backend-core/src/objectStore/index.ts b/packages/backend-core/src/objectStore/index.ts index 84eebeff81..a1193c0303 100644 --- a/packages/backend-core/src/objectStore/index.ts +++ b/packages/backend-core/src/objectStore/index.ts @@ -390,7 +390,7 @@ export const uploadDirectory = async ( return files } -exports.downloadTarballDirect = async ( +export const downloadTarballDirect = async ( url: string, path: string, headers = {} diff --git a/packages/backend-core/src/security/roles.ts b/packages/backend-core/src/security/roles.ts index da475322a7..bdf7a38726 100644 --- a/packages/backend-core/src/security/roles.ts +++ b/packages/backend-core/src/security/roles.ts @@ -1,10 +1,5 @@ import { BuiltinPermissionID, PermissionLevel } from "./permissions" -import { - generateRoleID, - getRoleParams, - DocumentType, - SEPARATOR, -} from "../db/utils" +import { generateRoleID, getRoleParams, DocumentType, SEPARATOR } from "../db" import { getAppDB } from "../context" import { doWithDB } from "../db" import { Screen, Role as RoleDoc } from "@budibase/types" @@ -30,20 +25,18 @@ const EXTERNAL_BUILTIN_ROLE_IDS = [ BUILTIN_IDS.PUBLIC, ] -export class Role { +export class Role implements RoleDoc { _id: string + _rev?: string name: string - permissionId?: string + permissionId: string inherits?: string + permissions = {} - constructor(id: string, name: string) { + constructor(id: string, name: string, permissionId: string) { this._id = id this.name = name - } - - addPermission(permissionId: string) { this.permissionId = permissionId - return this } addInheritance(inherits: string) { @@ -53,24 +46,26 @@ export class Role { } const BUILTIN_ROLES = { - ADMIN: new Role(BUILTIN_IDS.ADMIN, "Admin") - .addPermission(BuiltinPermissionID.ADMIN) - .addInheritance(BUILTIN_IDS.POWER), - POWER: new Role(BUILTIN_IDS.POWER, "Power") - .addPermission(BuiltinPermissionID.POWER) - .addInheritance(BUILTIN_IDS.BASIC), - BASIC: new Role(BUILTIN_IDS.BASIC, "Basic") - .addPermission(BuiltinPermissionID.WRITE) - .addInheritance(BUILTIN_IDS.PUBLIC), - PUBLIC: new Role(BUILTIN_IDS.PUBLIC, "Public").addPermission( - BuiltinPermissionID.PUBLIC - ), - BUILDER: new Role(BUILTIN_IDS.BUILDER, "Builder").addPermission( + ADMIN: new Role( + BUILTIN_IDS.ADMIN, + "Admin", BuiltinPermissionID.ADMIN - ), + ).addInheritance(BUILTIN_IDS.POWER), + POWER: new Role( + BUILTIN_IDS.POWER, + "Power", + BuiltinPermissionID.POWER + ).addInheritance(BUILTIN_IDS.BASIC), + BASIC: new Role( + BUILTIN_IDS.BASIC, + "Basic", + BuiltinPermissionID.WRITE + ).addInheritance(BUILTIN_IDS.PUBLIC), + PUBLIC: new Role(BUILTIN_IDS.PUBLIC, "Public", BuiltinPermissionID.PUBLIC), + BUILDER: new Role(BUILTIN_IDS.BUILDER, "Builder", BuiltinPermissionID.ADMIN), } -export function getBuiltinRoles() { +export function getBuiltinRoles(): { [key: string]: RoleDoc } { return cloneDeep(BUILTIN_ROLES) } @@ -104,7 +99,7 @@ export function builtinRoleToNumber(id?: string) { if (!role) { break } - role = builtins[role.inherits] + role = builtins[role.inherits!] count++ } while (role !== null) return count @@ -129,12 +124,12 @@ export async function roleToNumber(id?: string) { /** * Returns whichever builtin roleID is lower. */ -export function lowerBuiltinRoleID(roleId1?: string, roleId2?: string) { +export function lowerBuiltinRoleID(roleId1?: string, roleId2?: string): string { if (!roleId1) { - return roleId2 + return roleId2 as string } if (!roleId2) { - return roleId1 + return roleId1 as string } return builtinRoleToNumber(roleId1) > builtinRoleToNumber(roleId2) ? roleId2 diff --git a/packages/backend-core/src/security/sessions.ts b/packages/backend-core/src/security/sessions.ts index 33230afc60..48e75b0d60 100644 --- a/packages/backend-core/src/security/sessions.ts +++ b/packages/backend-core/src/security/sessions.ts @@ -89,6 +89,7 @@ export async function createASession( userId, } await client.store(key, session, EXPIRY_SECONDS) + return session } export async function updateSessionTTL(session: Session) { diff --git a/packages/bbui/package.json b/packages/bbui/package.json index b619e85651..5e077007b6 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.1.32-alpha.3", + "version": "2.1.32-alpha.9", "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.1.32-alpha.3", + "@budibase/string-templates": "2.1.32-alpha.9", "@spectrum-css/actionbutton": "^1.0.1", "@spectrum-css/actiongroup": "^1.0.1", "@spectrum-css/avatar": "^3.0.2", diff --git a/packages/bbui/src/Skeleton/Skeleton.svelte b/packages/bbui/src/Skeleton/Skeleton.svelte new file mode 100644 index 0000000000..e12d37b057 --- /dev/null +++ b/packages/bbui/src/Skeleton/Skeleton.svelte @@ -0,0 +1,56 @@ +
+
+ +
+
+ + diff --git a/packages/bbui/src/Table/Table.svelte b/packages/bbui/src/Table/Table.svelte index 958869b066..cec270486a 100644 --- a/packages/bbui/src/Table/Table.svelte +++ b/packages/bbui/src/Table/Table.svelte @@ -71,7 +71,8 @@ visibleRowCount, rowCount, totalRowCount, - rowHeight + rowHeight, + loading ) $: sortedRows = sortRows(rows, sortColumn, sortOrder) $: gridStyle = getGridStyle(fields, schema, showEditColumn) @@ -120,8 +121,12 @@ visibleRowCount, rowCount, totalRowCount, - rowHeight + rowHeight, + loading ) => { + if (loading) { + return `height: ${headerHeight + visibleRowCount * rowHeight}px;` + } if (!rowCount || !visibleRowCount || totalRowCount <= rowCount) { return "" } @@ -278,9 +283,11 @@ bind:offsetHeight={height} style={`--row-height: ${rowHeight}px; --header-height: ${headerHeight}px;`} > - {#if !loaded} + {#if loading}
- + + +
{:else}
@@ -440,9 +447,10 @@ /* Loading */ .loading { - display: grid; - place-items: center; + display: flex; + align-items: center; min-height: 100px; + justify-content: center; } /* Table */ diff --git a/packages/bbui/src/index.js b/packages/bbui/src/index.js index 538a62188f..601c4dcbca 100644 --- a/packages/bbui/src/index.js +++ b/packages/bbui/src/index.js @@ -4,6 +4,7 @@ import "./bbui.css" import "@spectrum-css/icon/dist/index-vars.css" // Components +export { default as Skeleton } from "./Skeleton/Skeleton.svelte" export { default as Input } from "./Form/Input.svelte" export { default as Stepper } from "./Form/Stepper.svelte" export { default as TextArea } from "./Form/TextArea.svelte" diff --git a/packages/bbui/yarn.lock b/packages/bbui/yarn.lock index f148ca201e..3b748a7daf 100644 --- a/packages/bbui/yarn.lock +++ b/packages/bbui/yarn.lock @@ -53,10 +53,10 @@ to-gfm-code-block "^0.1.1" year "^0.2.1" -"@budibase/string-templates@2.1.22-alpha.5": - version "2.1.22-alpha.5" - resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-2.1.22-alpha.5.tgz#3493be2ec8a3799ad1f7e470c308d9cdcd36abf6" - integrity sha512-iFN4nccB8eIjsaU0ki7DyC+zznJaGC+cUQiAiwgO+aDm3SD6vkF443IjwL/fcmpK81/4WpEWmJPDjVuQ+vjlKQ== +"@budibase/string-templates@2.1.32-alpha.0": + version "2.1.32-alpha.0" + resolved "https://registry.yarnpkg.com/@budibase/string-templates/-/string-templates-2.1.32-alpha.0.tgz#97452a80b3c3238e0d11b48ec36d2d7b8cb8e1d5" + integrity sha512-F+AkIWb8CitLt+YCJV/GQB8ECfj7GfO4I/vptIyNay9EWo0MRIU+4Xn715nBfEW5e23BQPKF3QR8S6y0IgxFbg== dependencies: "@budibase/handlebars-helpers" "^0.11.8" dayjs "^1.10.4" @@ -824,7 +824,7 @@ component-emitter@^1.2.1: concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== concat-with-sourcemaps@*, concat-with-sourcemaps@^1.1.0: version "1.1.0" @@ -2080,10 +2080,10 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -loader-utils@^1.1.0: - version "1.4.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" - integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== +loader-utils@1.4.1, loader-utils@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.1.tgz#278ad7006660bccc4d2c0c1578e17c5c78d5c0e0" + integrity sha512-1Qo97Y2oKaU+Ro2xnDMR26g1BwMT29jNbem1EvcujW2jqt+j5COXyscjM7bLQkM9HaxI7pkWeW7gnI072yMI9Q== dependencies: big.js "^5.2.2" emojis-list "^3.0.0" @@ -2220,9 +2220,9 @@ mime@1.6.0: integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== dependencies: brace-expansion "^1.1.7" diff --git a/packages/builder/cypress/integration/appPublishWorkflow.spec.js b/packages/builder/cypress/integration/appPublishWorkflow.spec.js index 0e3fbb191b..ab799f40fe 100644 --- a/packages/builder/cypress/integration/appPublishWorkflow.spec.js +++ b/packages/builder/cypress/integration/appPublishWorkflow.spec.js @@ -30,7 +30,6 @@ filterTests(['all'], () => { it("Should publish an application and correctly reflect that", () => { //Assuming the previous test was run and the unpublished app is open in edit mode. - cy.closeModal() cy.get(interact.TOPRIGHTNAV_BUTTON_SPECTRUM).contains("Publish").click({ force : true }) cy.get(interact.DEPLOY_APP_MODAL).should("be.visible") @@ -86,8 +85,7 @@ filterTests(['all'], () => { .within(() => { cy.get(interact.APP_TABLE_APP_NAME).click({ force: true }) }) - - cy.closeModal() + cy.get(interact.DEPLOYMENT_TOP_GLOBE).should("exist").click({ force: true }) cy.get("[data-cy='publish-popover-menu']") diff --git a/packages/builder/cypress/integration/createBinding.spec.js b/packages/builder/cypress/integration/createBinding.spec.js index 0c1ddf1e7d..0722d29f1d 100644 --- a/packages/builder/cypress/integration/createBinding.spec.js +++ b/packages/builder/cypress/integration/createBinding.spec.js @@ -9,9 +9,10 @@ filterTests(['smoke', 'all'], () => { }) it("should add a current user binding", () => { - cy.searchAndAddComponent("Paragraph").then(() => { + cy.searchAndAddComponent("Paragraph").then(componentId => { addSettingBinding("text", ["Current User", "_id"], "Current User._id") }) + cy.deleteComponentByName("New Paragraph") }) it("should handle an invalid binding", () => { @@ -21,6 +22,7 @@ filterTests(['smoke', 'all'], () => { .type("{{}{{}{{} Current User._id {}}{}}") .blur() cy.getComponent(componentId).should("have.text", "{{{ [user].[_id] }}") + cy.deleteComponentByName("New Paragraph") }) }) diff --git a/packages/builder/cypress/integration/datasources/rest.spec.js b/packages/builder/cypress/integration/datasources/rest.spec.js index 7cfe1ce9bb..7f715ae50c 100644 --- a/packages/builder/cypress/integration/datasources/rest.spec.js +++ b/packages/builder/cypress/integration/datasources/rest.spec.js @@ -1,7 +1,7 @@ import filterTests from "../../support/filterTests" filterTests(["smoke", "all"], () => { - context("REST Datasource Testing", () => { + xcontext("REST Datasource Testing", () => { before(() => { cy.login() cy.createTestApp() diff --git a/packages/builder/cypress/support/commands.js b/packages/builder/cypress/support/commands.js index c8d977258c..278c6504f8 100644 --- a/packages/builder/cypress/support/commands.js +++ b/packages/builder/cypress/support/commands.js @@ -440,8 +440,8 @@ Cypress.Commands.add("createTable", (tableName, initialTable) => { // Creates an internal Budibase DB table if (!initialTable) { cy.navigateToDataSection() - cy.get(`[data-cy="new-datasource"]`, { timeout: 2000 }).click() } + cy.get(`[data-cy="new-datasource"]`, { timeout: 2000 }).click() cy.wait(2000) cy.get(".item", { timeout: 2000 }) .contains("Budibase DB") @@ -458,6 +458,9 @@ Cypress.Commands.add("createTable", (tableName, initialTable) => { }) // Ensure modal has closed and table is created cy.get(".spectrum-Modal", { timeout: 2000 }).should("not.exist") + cy.get(".nav-item", { timeout: 2000 }) + .contains("Budibase DB") + .click({ force: true }) cy.get(".spectrum-Tabs-content", { timeout: 2000 }).should( "contain", tableName @@ -525,7 +528,7 @@ Cypress.Commands.add("addRowMultiValue", values => { }) Cypress.Commands.add("selectTable", tableName => { - cy.expandBudibaseConnection() + cy.get(".nav-item").contains("Budibase DB").click() cy.contains(".nav-item", tableName).click() }) @@ -576,6 +579,18 @@ Cypress.Commands.add("searchAndAddComponent", component => { }) }) +Cypress.Commands.add("deleteComponentByName", componentName => { + cy.get(".body") + .eq(0) + .contains(componentName) + .siblings(".actions") + .within(() => { + cy.get(".spectrum-Icon").click({ force: true }) + }) + cy.get(".spectrum-Menu").contains("Delete").click() + cy.get(".spectrum-Dialog").contains("Delete Component").click() +}) + Cypress.Commands.add("addComponent", (category, component) => { if (category) { cy.get(`[data-cy="category-${category}"]`, { timeout: 3000 }).click({ diff --git a/packages/builder/package.json b/packages/builder/package.json index 2e8367db1f..2ab073e4d6 100644 --- a/packages/builder/package.json +++ b/packages/builder/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/builder", - "version": "2.1.32-alpha.3", + "version": "2.1.32-alpha.9", "license": "GPL-3.0", "private": true, "scripts": { @@ -71,10 +71,10 @@ } }, "dependencies": { - "@budibase/bbui": "2.1.32-alpha.3", - "@budibase/client": "2.1.32-alpha.3", - "@budibase/frontend-core": "2.1.32-alpha.3", - "@budibase/string-templates": "2.1.32-alpha.3", + "@budibase/bbui": "2.1.32-alpha.9", + "@budibase/client": "2.1.32-alpha.9", + "@budibase/frontend-core": "2.1.32-alpha.9", + "@budibase/string-templates": "2.1.32-alpha.9", "@sentry/browser": "5.19.1", "@spectrum-css/page": "^3.0.1", "@spectrum-css/vars": "^3.0.1", diff --git a/packages/cli/package.json b/packages/cli/package.json index 45f269b1a3..bbeb869168 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/cli", - "version": "2.1.32-alpha.3", + "version": "2.1.32-alpha.9", "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.1.32-alpha.3", - "@budibase/string-templates": "2.1.32-alpha.3", - "@budibase/types": "2.1.32-alpha.3", + "@budibase/backend-core": "2.1.32-alpha.9", + "@budibase/string-templates": "2.1.32-alpha.9", + "@budibase/types": "2.1.32-alpha.9", "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 3b2bd31fe7..4bd7bc2b5d 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -285,7 +285,7 @@ "editable": true, "size": { "width": 105, - "height": 35 + "height": 32 }, "settings": [ { @@ -684,7 +684,7 @@ "editable": true, "size": { "width": 400, - "height": 30 + "height": 24 }, "settings": [ { @@ -809,7 +809,7 @@ "editable": true, "size": { "width": 400, - "height": 40 + "height": 32 }, "settings": [ { @@ -2448,6 +2448,7 @@ ] }, "stringfield": { + "skeleton": false, "name": "Text Field", "icon": "Text", "styles": [ @@ -2456,7 +2457,7 @@ "editable": true, "size": { "width": 400, - "height": 50 + "height": 32 }, "settings": [ { @@ -2539,6 +2540,7 @@ ] }, "numberfield": { + "skeleton": false, "name": "Number Field", "icon": "123", "styles": [ @@ -2653,6 +2655,7 @@ ] }, "optionsfield": { + "skeleton": false, "name": "Options Picker", "icon": "Menu", "styles": [ @@ -2821,6 +2824,7 @@ ] }, "multifieldselect": { + "skeleton": false, "name": "Multi-select Picker", "icon": "ViewList", "styles": [ @@ -2983,12 +2987,13 @@ ] }, "booleanfield": { + "skeleton": false, "name": "Checkbox", "icon": "SelectBox", "editable": true, "size": { - "width": 400, - "height": 50 + "width": 20, + "height": 20 }, "settings": [ { @@ -3140,6 +3145,7 @@ ] }, "datetimefield": { + "skeleton": false, "name": "Date Picker", "icon": "Date", "styles": [ @@ -3221,6 +3227,7 @@ ] }, "codescanner": { + "skeleton": false, "name": "Barcode/QR Scanner", "icon": "Camera", "styles": [ @@ -3386,6 +3393,7 @@ ] }, "attachmentfield": { + "skeleton": false, "name": "Attachment", "icon": "Attach", "styles": [ @@ -3444,6 +3452,7 @@ ] }, "relationshipfield": { + "skeleton": false, "name": "Relationship Picker", "icon": "TaskList", "styles": [ @@ -3507,6 +3516,7 @@ ] }, "jsonfield": { + "skeleton": false, "name": "JSON Field", "icon": "Brackets", "styles": [ @@ -3708,6 +3718,7 @@ } }, "table": { + "skeleton": false, "name": "Table", "icon": "Table", "illegalChildren": [ diff --git a/packages/client/package.json b/packages/client/package.json index 14ecbbf5d8..8c31d4ff48 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -1,6 +1,6 @@ { "name": "@budibase/client", - "version": "2.1.32-alpha.3", + "version": "2.1.32-alpha.9", "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.1.32-alpha.3", - "@budibase/frontend-core": "2.1.32-alpha.3", - "@budibase/string-templates": "2.1.32-alpha.3", + "@budibase/bbui": "2.1.32-alpha.9", + "@budibase/frontend-core": "2.1.32-alpha.9", + "@budibase/string-templates": "2.1.32-alpha.9", "@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/BlockComponent.svelte b/packages/client/src/components/BlockComponent.svelte index 4f720e2931..841aeb219a 100644 --- a/packages/client/src/components/BlockComponent.svelte +++ b/packages/client/src/components/BlockComponent.svelte @@ -24,6 +24,7 @@ // to render this part of the block, taking advantage of binding enrichment $: id = `${block.id}-${context ?? rand}` $: instance = { + _blockElementHasChildren: $$slots?.default ?? false, _component: `@budibase/standard-components/${type}`, _id: id, _instanceName: name || type[0].toUpperCase() + type.slice(1), diff --git a/packages/client/src/components/Component.svelte b/packages/client/src/components/Component.svelte index 8a72fb042a..e5fe100372 100644 --- a/packages/client/src/components/Component.svelte +++ b/packages/client/src/components/Component.svelte @@ -29,6 +29,7 @@ import Placeholder from "components/app/Placeholder.svelte" import ScreenPlaceholder from "components/app/ScreenPlaceholder.svelte" import ComponentPlaceholder from "components/app/ComponentPlaceholder.svelte" + import Skeleton from "components/app/Skeleton.svelte" export let instance = {} export let isLayout = false @@ -38,6 +39,7 @@ // Get parent contexts const context = getContext("context") + const loading = getContext("loading") const insideScreenslot = !!getContext("screenslot") // Create component context @@ -471,9 +473,21 @@ componentStore.actions.unregisterInstance(id) } }) + + $: showSkeleton = + $loading && + definition.name !== "Screenslot" && + children.length === 0 && + !instance._blockElementHasChildren && + definition.skeleton !== false -{#if constructor && initialSettings && (visible || inSelectedPath) && !builderHidden} +{#if showSkeleton} + +{:else if constructor && initialSettings && (visible || inSelectedPath) && !builderHidden}
+ import { writable } from "svelte/store" import { setContext, getContext, onMount } from "svelte" import Router, { querystring } from "svelte-spa-router" import { routeStore, stateStore } from "stores" @@ -9,6 +10,9 @@ const component = getContext("component") setContext("screenslot", true) + const loading = writable(false) + setContext("loading", loading) + // Only wrap this as an array to take advantage of svelte keying, // to ensure the svelte-spa-router is fully remounted when route config // changes diff --git a/packages/client/src/components/app/DataProvider.svelte b/packages/client/src/components/app/DataProvider.svelte index 8cd2f00eec..c28cdef24c 100644 --- a/packages/client/src/components/app/DataProvider.svelte +++ b/packages/client/src/components/app/DataProvider.svelte @@ -1,6 +1,7 @@ {#if $component.empty} - {:else if rows.length > 0} + {:else if !$loading && rows.length === 0} +
{noRowsMessage}
+ {:else} {#each rows as row, index} {/each} - {:else if loaded && noRowsMessage} -
{noRowsMessage}
{/if}
diff --git a/packages/client/src/components/app/Skeleton.svelte b/packages/client/src/components/app/Skeleton.svelte new file mode 100644 index 0000000000..5c247bf3e4 --- /dev/null +++ b/packages/client/src/components/app/Skeleton.svelte @@ -0,0 +1,31 @@ + + +
+ + + +
diff --git a/packages/client/src/components/app/forms/AttachmentField.svelte b/packages/client/src/components/app/forms/AttachmentField.svelte index 9887901d4c..da04c57e82 100644 --- a/packages/client/src/components/app/forms/AttachmentField.svelte +++ b/packages/client/src/components/app/forms/AttachmentField.svelte @@ -76,18 +76,26 @@ bind:fieldApi defaultValue={[]} > - {#if fieldState} - - {/if} +
+ {#if fieldState} + + {/if} +
+ + diff --git a/packages/client/src/components/app/forms/Field.svelte b/packages/client/src/components/app/forms/Field.svelte index d6dddbbe39..a14c6ac9c8 100644 --- a/packages/client/src/components/app/forms/Field.svelte +++ b/packages/client/src/components/app/forms/Field.svelte @@ -1,6 +1,7 @@