diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js index cea4e98dfe..b9cd134067 100644 --- a/packages/builder/src/builderStore/store/frontend.js +++ b/packages/builder/src/builderStore/store/frontend.js @@ -76,6 +76,7 @@ export const getFrontendStore = () => { clientLibPath, previousTopNavPath: {}, version: application.version, + revertableVersion: application.revertableVersion, })) await hostingStore.actions.fetch() diff --git a/packages/builder/src/components/deploy/VersionModal.svelte b/packages/builder/src/components/deploy/VersionModal.svelte index 4a42fac0c1..541f37ad50 100644 --- a/packages/builder/src/components/deploy/VersionModal.svelte +++ b/packages/builder/src/components/deploy/VersionModal.svelte @@ -5,6 +5,7 @@ notifications, ModalContent, Body, + Button, } from "@budibase/bbui" import { store } from "builderStore" import api from "builderStore/api" @@ -14,6 +15,19 @@ $: appId = $store.appId $: updateAvailable = clientPackage.version !== $store.version + $: revertAvailable = $store.revertableVersion != null + + const refreshAppPackage = async () => { + const applicationPkg = await api.get( + `/api/applications/${appId}/appPackage` + ) + const pkg = await applicationPkg.json() + if (applicationPkg.ok) { + await store.actions.initialise(pkg) + } else { + throw new Error(pkg) + } + } const update = async () => { try { @@ -24,18 +38,7 @@ if (response.status !== 200) { throw json.message } - - // Reset frontend state after revert - const applicationPkg = await api.get( - `/api/applications/${appId}/appPackage` - ) - const pkg = await applicationPkg.json() - if (applicationPkg.ok) { - await store.actions.initialise(pkg) - } else { - throw new Error(pkg) - } - + await refreshAppPackage() notifications.success( `App updated successfully to version ${clientPackage.version}` ) @@ -43,6 +46,25 @@ notifications.error(`Error updating app: ${err}`) } } + + const revert = async () => { + try { + const response = await api.post( + `/api/applications/${appId}/client/revert` + ) + const json = await response.json() + if (response.status !== 200) { + throw json.message + } + await refreshAppPackage() + notifications.success( + `App reverted successfully to version ${$store.revertableVersion}` + ) + } catch (err) { + notifications.error(`Error reverting app: ${err}`) + } + updateModal.hide() + }
@@ -56,13 +78,16 @@ onConfirm={update} showConfirmButton={updateAvailable} > +
+ {#if revertAvailable} + + {/if} +
{#if updateAvailable} This app is currently using version {$store.version}, but version - {clientPackage.version} is available. Updates can contain new - features, performance improvements and bug fixes. -

- Would you like to update this app? + {clientPackage.version} is available. Updates can contain new features, + performance improvements and bug fixes. {:else} @@ -70,6 +95,13 @@ latest version available. {/if} + {#if revertAvailable} + + You can revert this app to version + {$store.revertableVersion} + if you're experiencing issues with the current version. + + {/if} diff --git a/packages/server/src/api/controllers/application.js b/packages/server/src/api/controllers/application.js index 6719a95211..e8ace42bcd 100644 --- a/packages/server/src/api/controllers/application.js +++ b/packages/server/src/api/controllers/application.js @@ -241,8 +241,19 @@ exports.update = async function (ctx) { } exports.updateClient = async function (ctx) { + // Get current app version + const db = new CouchDB(ctx.params.appId) + const application = await db.get(DocumentTypes.APP_METADATA) + const currentVersion = application.version + + // Update client library and manifest await uploadClientLibrary(ctx.params.appId) - const appPackageUpdates = { version: packageJson.version } + + // Update versions in app package + const appPackageUpdates = { + version: packageJson.version, + revertableVersion: currentVersion, + } const data = await updateAppPackage(ctx, appPackageUpdates, ctx.params.appId) ctx.status = 200 ctx.body = data