Merge pull request #3791 from Budibase/proxy-state-modals
Screen modal fixes for state and datasource invalidation
This commit is contained in:
commit
f3460ccb7d
|
@ -1,8 +1,9 @@
|
|||
<script>
|
||||
import { setContext, getContext } from "svelte"
|
||||
import { setContext, getContext, onMount } from "svelte"
|
||||
import Router, { querystring } from "svelte-spa-router"
|
||||
import { routeStore } from "stores"
|
||||
import { routeStore, stateStore } from "stores"
|
||||
import Screen from "./Screen.svelte"
|
||||
import { get } from "svelte/store"
|
||||
|
||||
const { styleable } = getContext("sdk")
|
||||
const component = getContext("component")
|
||||
|
@ -17,15 +18,17 @@
|
|||
}
|
||||
|
||||
// Keep query params up to date
|
||||
$: {
|
||||
$: routeStore.actions.setQueryParams(parseQueryString($querystring))
|
||||
|
||||
const parseQueryString = query => {
|
||||
let queryParams = {}
|
||||
if ($querystring) {
|
||||
const urlSearchParams = new URLSearchParams($querystring)
|
||||
if (query) {
|
||||
const urlSearchParams = new URLSearchParams(query)
|
||||
for (const [key, value] of urlSearchParams) {
|
||||
queryParams[key] = value
|
||||
}
|
||||
}
|
||||
routeStore.actions.setQueryParams(queryParams)
|
||||
return queryParams
|
||||
}
|
||||
|
||||
const getRouterConfig = routes => {
|
||||
|
@ -42,6 +45,19 @@
|
|||
const onRouteLoading = ({ detail }) => {
|
||||
routeStore.actions.setActiveRoute(detail.route)
|
||||
}
|
||||
|
||||
// Initialise state store from query string on initial load
|
||||
onMount(() => {
|
||||
const queryParams = parseQueryString(get(querystring))
|
||||
if (queryParams.state) {
|
||||
try {
|
||||
const state = JSON.parse(atob(queryParams.state))
|
||||
stateStore.actions.initialise(state)
|
||||
} catch (error) {
|
||||
// Swallow error and do nothing
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
{#key config.id}
|
||||
|
|
|
@ -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)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
@ -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 },
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 = {
|
||||
|
|
Loading…
Reference in New Issue