diff --git a/packages/builder/src/builderStore/store/frontend.js b/packages/builder/src/builderStore/store/frontend.js
index 5de58f02e7..4af3be4673 100644
--- a/packages/builder/src/builderStore/store/frontend.js
+++ b/packages/builder/src/builderStore/store/frontend.js
@@ -353,6 +353,35 @@ export const getFrontendStore = () => {
}
return await sequentialScreenPatch(patchFn, screenId)
},
+ replace: async (screenId, screen) => {
+ if (!screenId) {
+ return
+ }
+
+ // Handle deletion
+ if (!screen) {
+ store.update(state => ({
+ ...state,
+ screens: state.screens.filter(x => x._id !== screenId),
+ }))
+ return
+ }
+
+ // Add new datasource
+ const index = get(store).screens.findIndex(x => x._id === screen._id)
+ if (index === -1) {
+ store.update(state => ({
+ ...state,
+ screens: [...state.screens, screen],
+ }))
+ }
+
+ // Update existing datasource
+ store.update(state => {
+ state.screens[index] = screen
+ return state
+ })
+ },
delete: async screens => {
const screensToDelete = Array.isArray(screens) ? screens : [screens]
diff --git a/packages/builder/src/builderStore/websocket.js b/packages/builder/src/builderStore/websocket.js
index af6d58ee7f..8562c8024c 100644
--- a/packages/builder/src/builderStore/websocket.js
+++ b/packages/builder/src/builderStore/websocket.js
@@ -31,7 +31,7 @@ export const createBuilderWebsocket = appId => {
})
socket.onOther(BuilderSocketEvent.LockTransfer, ({ userId }) => {
if (userId === get(auth)?.user?._id) {
- notifications.success("You can now edit screens and automations")
+ notifications.success("You can now edit automations")
store.update(state => ({
...state,
hasLock: true,
@@ -39,15 +39,18 @@ export const createBuilderWebsocket = appId => {
}
})
- // Table events
+ // Data section events
socket.onOther(BuilderSocketEvent.TableChange, ({ id, table }) => {
tables.replaceTable(id, table)
})
-
- // Datasource events
socket.onOther(BuilderSocketEvent.DatasourceChange, ({ id, datasource }) => {
datasources.replaceDatasource(id, datasource)
})
+ // Design section events
+ socket.onOther(BuilderSocketEvent.ScreenChange, ({ id, screen }) => {
+ store.actions.screens.replace(id, screen)
+ })
+
return socket
}
diff --git a/packages/builder/src/helpers/urlStateSync.js b/packages/builder/src/helpers/urlStateSync.js
index 47f3438468..c4c48fb3fb 100644
--- a/packages/builder/src/helpers/urlStateSync.js
+++ b/packages/builder/src/helpers/urlStateSync.js
@@ -114,26 +114,24 @@ export const syncURLToState = options => {
// Updates the URL with new state values
const mapStateToUrl = state => {
- let needsUpdate = false
const urlValue = cachedParams?.[urlParam]
const stateValue = state?.[stateKey]
- if (stateValue !== urlValue) {
- needsUpdate = true
- log(`url.${urlParam} (${urlValue}) <= state.${stateKey} (${stateValue})`)
- if (validate && fallbackUrl) {
- if (!validate(stateValue)) {
- log("Invalid state param!", stateValue)
- redirectUrl(fallbackUrl)
- return
- }
+
+ // As the store updated, validate that the current state value is valid
+ if (validate && fallbackUrl) {
+ if (!validate(stateValue)) {
+ log("Invalid state param!", stateValue)
+ redirectUrl(fallbackUrl)
+ return
}
}
// Avoid updating the URL if not necessary to prevent a wasted render
// cycle
- if (!needsUpdate) {
+ if (stateValue === urlValue) {
return
}
+ log(`url.${urlParam} (${urlValue}) <= state.${stateKey} (${stateValue})`)
// Navigate to the new URL
if (!get(isChangingPage)) {
diff --git a/packages/builder/src/pages/builder/app/[application]/_layout.svelte b/packages/builder/src/pages/builder/app/[application]/_layout.svelte
index 0d5942c39e..3703279044 100644
--- a/packages/builder/src/pages/builder/app/[application]/_layout.svelte
+++ b/packages/builder/src/pages/builder/app/[application]/_layout.svelte
@@ -151,31 +151,19 @@
on:click={() => $goto("../../portal/apps")}
/>
- {#if $store.hasLock}
-