diff --git a/packages/builder/src/components/common/AppLockModal.svelte b/packages/builder/src/components/common/AppLockModal.svelte new file mode 100644 index 0000000000..98da510a89 --- /dev/null +++ b/packages/builder/src/components/common/AppLockModal.svelte @@ -0,0 +1,135 @@ + + +
+ {#if lockedBy} + + {/if} +
+ + + +

+ Apps are locked to prevent work from being lost from overlapping changes + between your team. +

+ + {#if lockedByYou && lockExpiry > 0} + {processStringSync( + "This lock will expire in {{ duration time 'millisecond' }} from now", + { + time: lockExpiry, + } + )} + {/if} +
+ + + {#if lockedByYou && lockExpiry > 0} + + {/if} + +
+
+
+ + diff --git a/packages/builder/src/components/common/DashCard.svelte b/packages/builder/src/components/common/DashCard.svelte new file mode 100644 index 0000000000..c6d52489f6 --- /dev/null +++ b/packages/builder/src/components/common/DashCard.svelte @@ -0,0 +1,62 @@ + + +
+
{ + if (actionDefined) { + action() + } + }} + > + + {title} + + + {#if actionDefined} + + {/if} + +
+
+ +
+
+ + diff --git a/packages/builder/src/components/start/AppRow.svelte b/packages/builder/src/components/start/AppRow.svelte index ea2f005216..e81d04c4d2 100644 --- a/packages/builder/src/components/start/AppRow.svelte +++ b/packages/builder/src/components/start/AppRow.svelte @@ -1,22 +1,15 @@ @@ -26,7 +19,7 @@
-
editApp(app)}> +
appOverview(app)}> {app.name} @@ -43,19 +36,7 @@ {/if}
- - {#if app.lockedYou} - Locked by you - {:else if app.lockedOther} - Locked by {app.lockedBy.email} - {:else} - Open - {/if} - +
@@ -70,23 +51,15 @@
- {#if app.deployed} - - {:else} - - {/if} +
@@ -119,6 +92,7 @@ } .app-status { display: grid; + grid-gap: var(--spacing-s); grid-template-columns: 24px 100px; } .app-status span.disabled { diff --git a/packages/builder/src/pages/builder/portal/apps/index.svelte b/packages/builder/src/pages/builder/portal/apps/index.svelte index a25e7e2c6a..9b70068e10 100644 --- a/packages/builder/src/pages/builder/portal/apps/index.svelte +++ b/packages/builder/src/pages/builder/portal/apps/index.svelte @@ -182,6 +182,10 @@ window.open(`/${app.devId}`) } + const appOverview = app => { + $goto(`../overview/${app.devId}`) + } + const editApp = app => { if (app.lockedOther) { notifications.error( @@ -404,6 +408,7 @@ {deleteApp} {updateApp} {previewApp} + {appOverview} /> {/each}
diff --git a/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte b/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte new file mode 100644 index 0000000000..46fd95c1e9 --- /dev/null +++ b/packages/builder/src/pages/builder/portal/overview/[application]/index.svelte @@ -0,0 +1,254 @@ + + + + + + + + {#await promise} +
+ +
+ {:then _} +
+
+ +
+ {selectedApp?.name} +
{appUrl}
+
+
+
+ + + + + +
+
+ { + selectedTab = e.detail + }} + > + + + + +
Automation History contents
+
+ +
Backups contents
+
+ + + + + + +
+ {:catch error} +

Something went wrong: {error.message}

+ {/await} +
+
+ + diff --git a/packages/builder/src/pages/builder/portal/overview/_components/AutomationTab.svelte b/packages/builder/src/pages/builder/portal/overview/_components/AutomationTab.svelte new file mode 100644 index 0000000000..56dcc40f87 --- /dev/null +++ b/packages/builder/src/pages/builder/portal/overview/_components/AutomationTab.svelte @@ -0,0 +1,11 @@ + + +
+ + diff --git a/packages/builder/src/pages/builder/portal/overview/_components/OverviewTab.svelte b/packages/builder/src/pages/builder/portal/overview/_components/OverviewTab.svelte new file mode 100644 index 0000000000..4319f51e0c --- /dev/null +++ b/packages/builder/src/pages/builder/portal/overview/_components/OverviewTab.svelte @@ -0,0 +1,174 @@ + + +
+
+ +
+
+ {#if isPublished} + + Published + {:else} + + Unpublished + {/if} +
+ +

+ {#if deployments?.length} + {processStringSync( + "Last published {{ duration time 'millisecond' }} ago", + { + time: + new Date().getTime() - + new Date(deployments[0].updatedAt).getTime(), + } + )} + {/if} + {#if !deployments?.length} + - + {/if} +

+
+
+ + {app.updatedAt} +
+ +
+ + +
{app.updatedBy.firstName}
+
+

+ {#if app} + {processStringSync( + "Last edited {{ duration time 'millisecond' }} ago", + { + time: new Date().getTime() - new Date(app?.updatedAt).getTime(), + } + )} + {/if} +

+
+
+ { + navigateTab("App Version") + }} + > +
+ {app?.version} + {#if updateAvailable} +

+ New version {clientPackage.version} is available - + { + if (typeof navigateTab === "function") { + navigateTab("App Version") + } + }} + > + Update + +

+ {:else} +

You're running the latest!

+ {/if} +
+
+
+
+ { + navigateTab("Automation History") + }} + > +
+
+
+ 0 +
+ + Success +
+
+
+ 0 +
+ + Error +
+
+
+
+
+ +
test
+
+
+
+ + diff --git a/packages/builder/src/pages/builder/portal/overview/_components/SelfHostTab.svelte b/packages/builder/src/pages/builder/portal/overview/_components/SelfHostTab.svelte new file mode 100644 index 0000000000..16804a8eb6 --- /dev/null +++ b/packages/builder/src/pages/builder/portal/overview/_components/SelfHostTab.svelte @@ -0,0 +1,37 @@ + + +
+ + + + Self-host Budibase + + +

+ Self-host Budibase for free to get unlimited apps and more - and it + only takes a few minutes! +

+
+ +
+ +
+
+
+
+ + diff --git a/packages/builder/src/pages/builder/portal/overview/_components/VersionModalBody.svelte b/packages/builder/src/pages/builder/portal/overview/_components/VersionModalBody.svelte new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/builder/src/pages/builder/portal/overview/_components/VersionTab.svelte b/packages/builder/src/pages/builder/portal/overview/_components/VersionTab.svelte new file mode 100644 index 0000000000..583c6af603 --- /dev/null +++ b/packages/builder/src/pages/builder/portal/overview/_components/VersionTab.svelte @@ -0,0 +1,48 @@ + + +
+ + + + App Version + + + {#if updateAvailable} +

+ The app is currently using version {app?.version} + but version {clientPackage.version} is available. +

+ {:else} +

+ The app is currently using version {app?.version}. You're running the latest! +

+ {/if} +

+ Updates can contain new features, performance improvements and bug + fixes. +

+
+ +
+ +
+
+
+
+ + diff --git a/packages/server/src/middleware/builder.js b/packages/server/src/middleware/builder.js index f4568722c1..964efee451 100644 --- a/packages/server/src/middleware/builder.js +++ b/packages/server/src/middleware/builder.js @@ -6,7 +6,7 @@ const { setDebounce, } = require("../utilities/redis") const { doWithDB } = require("@budibase/backend-core/db") -const { DocumentTypes } = require("../db/utils") +const { DocumentTypes, getGlobalIDFromUserMetadataID } = require("../db/utils") const { PermissionTypes } = require("@budibase/backend-core/permissions") const { app: appCache } = require("@budibase/backend-core/cache") @@ -51,6 +51,21 @@ async function updateAppUpdatedAt(ctx) { await doWithDB(appId, async db => { const metadata = await db.get(DocumentTypes.APP_METADATA) metadata.updatedAt = new Date().toISOString() + + const getInitials = user => { + let initials = "" + initials += user.firstName ? user.firstName[0] : "" + initials += user.lastName ? user.lastName[0] : "" + return initials == "" ? undefined : initials + } + + metadata.updatedBy = { + email: ctx.user.email, + firstName: ctx.user.firstName, + lastName: ctx.user.lastName, + initials: getInitials(ctx.user), + _id: getGlobalIDFromUserMetadataID(ctx.user.userId), + } const response = await db.put(metadata) metadata._rev = response.rev await appCache.invalidateAppMetadata(appId, metadata) @@ -67,7 +82,15 @@ module.exports = async (ctx, permType) => { } const isBuilderApi = permType === PermissionTypes.BUILDER const referer = ctx.headers["referer"] - const editingApp = referer ? referer.includes(appId) : false + + const overviewPath = "/builder/portal/overview/" + const overviewContext = !referer ? false : referer.includes(overviewPath) + if (overviewContext) { + return + } + + const hasAppId = !referer ? false : referer.includes(appId) + const editingApp = referer ? hasAppId : false // check this is a builder call and editing if (!isBuilderApi || !editingApp) { return diff --git a/packages/server/src/utilities/redis.js b/packages/server/src/utilities/redis.js index ca2fa3254d..0c25bab27a 100644 --- a/packages/server/src/utilities/redis.js +++ b/packages/server/src/utilities/redis.js @@ -48,7 +48,9 @@ exports.updateLock = async (devAppId, user) => { ...user, userId: globalId, _id: globalId, + lockedAt: new Date().getTime(), } + await devAppClient.store(devAppId, inputUser, APP_DEV_LOCK_SECONDS) }