diff --git a/packages/builder/src/api.js b/packages/builder/src/api.js
index 37894d9bbc..ac878bf82f 100644
--- a/packages/builder/src/api.js
+++ b/packages/builder/src/api.js
@@ -5,7 +5,7 @@ import {
} from "@budibase/frontend-core"
import { store } from "./builderStore"
import { get } from "svelte/store"
-import { auth } from "./stores/portal"
+import { auth, navigation } from "./stores/portal"
export const API = createAPIClient({
attachHeaders: headers => {
@@ -45,4 +45,15 @@ export const API = createAPIClient({
}
}
},
+ onMigrationDetected: appId => {
+ const updatingUrl = `/builder/app/updating/${appId}`
+
+ if (window.location.pathname === updatingUrl) {
+ return
+ }
+
+ get(navigation).goto(
+ `${updatingUrl}?returnUrl=${encodeURIComponent(window.location.pathname)}`
+ )
+ },
})
diff --git a/packages/builder/src/pages/builder/_layout.svelte b/packages/builder/src/pages/builder/_layout.svelte
index b216958045..62d3951fb5 100644
--- a/packages/builder/src/pages/builder/_layout.svelte
+++ b/packages/builder/src/pages/builder/_layout.svelte
@@ -1,6 +1,6 @@
+
+
diff --git a/packages/builder/src/stores/portal/index.js b/packages/builder/src/stores/portal/index.js
index e70df5c3ee..7f1b9e10f0 100644
--- a/packages/builder/src/stores/portal/index.js
+++ b/packages/builder/src/stores/portal/index.js
@@ -16,5 +16,6 @@ export { environment } from "./environment"
export { menu } from "./menu"
export { auditLogs } from "./auditLogs"
export { features } from "./features"
+export { navigation } from "./navigation"
export const sideBarCollapsed = writable(false)
diff --git a/packages/builder/src/stores/portal/navigation.js b/packages/builder/src/stores/portal/navigation.js
new file mode 100644
index 0000000000..67a06eff53
--- /dev/null
+++ b/packages/builder/src/stores/portal/navigation.js
@@ -0,0 +1,31 @@
+import { writable } from "svelte/store"
+
+export function createNavigationStore() {
+ const store = writable({
+ initialisated: false,
+ goto: undefined,
+ })
+ const { set, subscribe } = store
+
+ const init = gotoFunc => {
+ if (typeof gotoFunc !== "function") {
+ throw new Error(
+ `gotoFunc must be a function, found a "${typeof gotoFunc}" instead`
+ )
+ }
+
+ set({
+ initialisated: true,
+ goto: gotoFunc,
+ })
+ }
+
+ return {
+ subscribe,
+ actions: {
+ init,
+ },
+ }
+}
+
+export const navigation = createNavigationStore()
diff --git a/packages/frontend-core/src/api/index.js b/packages/frontend-core/src/api/index.js
index d4b4f3636e..066ab16f6e 100644
--- a/packages/frontend-core/src/api/index.js
+++ b/packages/frontend-core/src/api/index.js
@@ -33,6 +33,7 @@ import { buildEnvironmentVariableEndpoints } from "./environmentVariables"
import { buildEventEndpoints } from "./events"
import { buildAuditLogsEndpoints } from "./auditLogs"
import { buildLogsEndpoints } from "./logs"
+import { buildMigrationEndpoints } from "./migrations"
/**
* Random identifier to uniquely identify a session in a tab. This is
@@ -298,6 +299,7 @@ export const createAPIClient = config => {
...buildEventEndpoints(API),
...buildAuditLogsEndpoints(API),
...buildLogsEndpoints(API),
+ ...buildMigrationEndpoints(API),
viewV2: buildViewV2Endpoints(API),
}
}
diff --git a/packages/frontend-core/src/api/migrations.js b/packages/frontend-core/src/api/migrations.js
new file mode 100644
index 0000000000..2da70d6fcb
--- /dev/null
+++ b/packages/frontend-core/src/api/migrations.js
@@ -0,0 +1,10 @@
+export const buildMigrationEndpoints = API => ({
+ /**
+ * Gets the info about the current app migration
+ */
+ getMigrationStatus: async () => {
+ return await API.get({
+ url: "/api/migrations/status",
+ })
+ },
+})
diff --git a/packages/frontend-core/src/components/Updating.svelte b/packages/frontend-core/src/components/Updating.svelte
new file mode 100644
index 0000000000..7d4a101fee
--- /dev/null
+++ b/packages/frontend-core/src/components/Updating.svelte
@@ -0,0 +1,79 @@
+
+
+
+
+
+ {#if !timedOut}
+ Please wait and we will be back in a second!
+ {:else}
+ An error occurred, please try again later.
+
+ Contact
+ support if the
+ issue persists.
+ {/if}
+
+
+
diff --git a/packages/frontend-core/src/components/index.js b/packages/frontend-core/src/components/index.js
index 01a7c78cb8..f724e1e4d9 100644
--- a/packages/frontend-core/src/components/index.js
+++ b/packages/frontend-core/src/components/index.js
@@ -3,4 +3,5 @@ export { default as TestimonialPage } from "./TestimonialPage.svelte"
export { default as Testimonial } from "./Testimonial.svelte"
export { default as UserAvatar } from "./UserAvatar.svelte"
export { default as UserAvatars } from "./UserAvatars.svelte"
+export { default as Updating } from "./Updating.svelte"
export { Grid } from "./grid"
diff --git a/packages/server/src/appMigrations/index.ts b/packages/server/src/appMigrations/index.ts
index b382d8b533..0758b9f324 100644
--- a/packages/server/src/appMigrations/index.ts
+++ b/packages/server/src/appMigrations/index.ts
@@ -17,7 +17,7 @@ export const getLatestMigrationId = () =>
.sort()
.reverse()[0]
-const getTimestamp = (versionId: string) => versionId?.split("_")[0]
+const getTimestamp = (versionId: string) => versionId?.split("_")[0] || ""
export async function checkMissingMigrations(
ctx: UserCtx,