From 98cd12db5fc6d96826dc1a3b4480c66ae146d058 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 14 Dec 2021 14:04:10 +0000 Subject: [PATCH 1/4] Proxy state updates back from peek modals --- .../overlay/PeekScreenDisplay.svelte | 22 ++++++++++++++++--- packages/client/src/utils/buttonActions.js | 9 ++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/packages/client/src/components/overlay/PeekScreenDisplay.svelte b/packages/client/src/components/overlay/PeekScreenDisplay.svelte index 51ff4412dc..7d3531d236 100644 --- a/packages/client/src/components/overlay/PeekScreenDisplay.svelte +++ b/packages/client/src/components/overlay/PeekScreenDisplay.svelte @@ -4,6 +4,7 @@ dataSourceStore, notificationStore, routeStore, + stateStore, } from "stores" import { Modal, ModalContent, ActionButton } from "@budibase/bbui" import { onDestroy } from "svelte" @@ -12,12 +13,13 @@ NOTIFICATION: "notification", CLOSE_SCREEN_MODAL: "close-screen-modal", INVALIDATE_DATASOURCE: "invalidate-datasource", + UPDATE_STATE: "update-state", } let iframe let listenersAttached = false - const invalidateDataSource = event => { + const proxyInvalidation = event => { const { dataSourceId } = event.detail dataSourceStore.actions.invalidateDataSource(dataSourceId) } @@ -27,14 +29,28 @@ notificationStore.actions.send(message, type, icon) } + const proxyStateUpdate = event => { + const { type, key, value, persist } = event.detail + if (type === "set") { + stateStore.actions.setValue(key, value, persist) + } else if (type === "delete") { + stateStore.actions.deleteValue(key) + } + } + function receiveMessage(message) { const handlers = { [MessageTypes.NOTIFICATION]: () => { proxyNotification(message.data) }, - [MessageTypes.CLOSE_SCREEN_MODAL]: peekStore.actions.hidePeek, + [MessageTypes.CLOSE_SCREEN_MODAL]: () => { + peekStore.actions.hidePeek() + }, [MessageTypes.INVALIDATE_DATASOURCE]: () => { - invalidateDataSource(message.data) + proxyInvalidation(message.data) + }, + [MessageTypes.UPDATE_STATE]: () => { + proxyStateUpdate(message.data) }, } diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js index 5ee571ae5d..9c6ae73c1f 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -116,6 +116,15 @@ const updateStateHandler = action => { } else if (type === "delete") { stateStore.actions.deleteValue(key) } + + // Emit this as an event so that parent windows which are iframing us in + // can also update their state + if (get(routeStore).queryParams?.peek) { + window.parent.postMessage({ + type: "update-state", + detail: { type, key, value, persist }, + }) + } } const handlerMap = { From d58b1ae7f024202b8a428a0c5d1b2bf1f9cdc787 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Tue, 14 Dec 2021 14:04:37 +0000 Subject: [PATCH 2/4] Fix datasource invalidation proxying from peek modals not working --- packages/client/src/stores/dataSource.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/client/src/stores/dataSource.js b/packages/client/src/stores/dataSource.js index ee615b8bfb..efec755b99 100644 --- a/packages/client/src/stores/dataSource.js +++ b/packages/client/src/stores/dataSource.js @@ -1,6 +1,7 @@ import { writable, get } from "svelte/store" import { fetchTableDefinition } from "../api" import { FieldTypes } from "../constants" +import { routeStore } from "./routes" export const createDataSourceStore = () => { const store = writable([]) @@ -60,10 +61,12 @@ export const createDataSourceStore = () => { // Emit this as a window event, so parent screens which are iframing us in // can also invalidate the same datasource - window.parent.postMessage({ - type: "close-screen-modal", - detail: { dataSourceId }, - }) + if (get(routeStore).queryParams?.peek) { + window.parent.postMessage({ + type: "invalidate-datasource", + detail: { dataSourceId }, + }) + } let invalidations = [dataSourceId] From 26d89f75d599794dd9be28ba440deabde40b2146 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 15 Dec 2021 08:55:22 +0000 Subject: [PATCH 3/4] Pass current state to peek modals when opening them via query param --- packages/client/src/components/Router.svelte | 28 +++++++++++++++----- packages/client/src/stores/peek.js | 8 ++++-- packages/client/src/stores/state.js | 5 +++- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/client/src/components/Router.svelte b/packages/client/src/components/Router.svelte index 95f52236a4..49cbc3f821 100644 --- a/packages/client/src/components/Router.svelte +++ b/packages/client/src/components/Router.svelte @@ -1,8 +1,9 @@ {#key config.id} diff --git a/packages/client/src/stores/peek.js b/packages/client/src/stores/peek.js index df41f5daff..83974b09f3 100644 --- a/packages/client/src/stores/peek.js +++ b/packages/client/src/stores/peek.js @@ -1,4 +1,5 @@ -import { writable } from "svelte/store" +import { writable, get } from "svelte/store" +import { stateStore } from "./state.js" const initialState = { showPeek: false, @@ -14,7 +15,10 @@ const createPeekStore = () => { let href = url let external = !url.startsWith("/") if (!external) { - href = `${window.location.href.split("#")[0]}#${url}?peek=true` + const state = get(stateStore) + const serialised = encodeURIComponent(btoa(JSON.stringify(state))) + const query = `peek=true&state=${serialised}` + href = `${window.location.href.split("#")[0]}#${url}?${query}` } store.set({ showPeek: true, diff --git a/packages/client/src/stores/state.js b/packages/client/src/stores/state.js index ce977c4333..4ad31c3854 100644 --- a/packages/client/src/stores/state.js +++ b/packages/client/src/stores/state.js @@ -34,6 +34,9 @@ const createStateStore = () => { }) } + // Initialises the temporary state store with a certain value + const initialise = tempStore.set + // Derive the combination of both persisted and non persisted stores const store = derived( [tempStore, persistentStore], @@ -47,7 +50,7 @@ const createStateStore = () => { return { subscribe: store.subscribe, - actions: { setValue, deleteValue }, + actions: { setValue, deleteValue, initialise }, } } From 1c23dc3a3c739eba3b9fed4f61ba376b09f92a78 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Wed, 15 Dec 2021 09:00:14 +0000 Subject: [PATCH 4/4] Fix using wrong local storage key when persisting state in client apps --- packages/client/src/stores/state.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/client/src/stores/state.js b/packages/client/src/stores/state.js index 4ad31c3854..0297b4c532 100644 --- a/packages/client/src/stores/state.js +++ b/packages/client/src/stores/state.js @@ -1,9 +1,9 @@ import { writable, get, derived } from "svelte/store" import { localStorageStore } from "builder/src/builderStore/store/localStorage" -import { appStore } from "./app" const createStateStore = () => { - const localStorageKey = `${get(appStore).appId}.state` + const appId = window["##BUDIBASE_APP_ID##"] || "app" + const localStorageKey = `${appId}.state` const persistentStore = localStorageStore(localStorageKey, {}) // Initialise the temp store to mirror the persistent store