refactor switch into a key value handler object
tidy up - remove logs and comments update windowed modals to use postMessage
This commit is contained in:
parent
969d2f5377
commit
193d40bbf3
|
@ -33,6 +33,16 @@
|
|||
.instanceName("Content Placeholder")
|
||||
.json()
|
||||
|
||||
// Messages that can be sent from the iframe preview to the builder
|
||||
// Budibase events are and initalisation events
|
||||
const MessageTypes = {
|
||||
IFRAME_LOADED: "iframe-loaded",
|
||||
READY: "ready",
|
||||
ERROR: "error",
|
||||
BUDIBASE: "type",
|
||||
KEYDOWN: "keydown"
|
||||
}
|
||||
|
||||
// Construct iframe template
|
||||
$: template = iframeTemplate.replace(
|
||||
/\{\{ CLIENT_LIB_PATH }}/,
|
||||
|
@ -80,46 +90,44 @@
|
|||
// Refresh the preview when required
|
||||
$: refreshContent(strippedJson)
|
||||
|
||||
onMount(() => {
|
||||
// Initialise the app when mounted
|
||||
iframe.contentWindow.addEventListener(
|
||||
"ready",
|
||||
() => {
|
||||
function receiveMessage(message) {
|
||||
const handlers = {
|
||||
[MessageTypes.READY]: () => {
|
||||
// Initialise the app when mounted
|
||||
// Display preview immediately if the intelligent loading feature
|
||||
// is not supported
|
||||
if (!loading) return
|
||||
|
||||
if (!$store.clientFeatures.intelligentLoading) {
|
||||
loading = false
|
||||
}
|
||||
refreshContent(strippedJson)
|
||||
},
|
||||
{ once: true }
|
||||
)
|
||||
|
||||
// Catch any app errors
|
||||
iframe.contentWindow.addEventListener(
|
||||
"error",
|
||||
event => {
|
||||
[MessageTypes.ERROR]: event => {
|
||||
// Catch any app errors
|
||||
loading = false
|
||||
error = event.detail || "An unknown error occurred"
|
||||
error = event.error || "An unknown error occurred"
|
||||
},
|
||||
{ once: true }
|
||||
)
|
||||
[MessageTypes.KEYDOWN]: handleKeydownEvent
|
||||
}
|
||||
|
||||
// Add listener for events sent by client library in preview
|
||||
iframe.contentWindow.addEventListener("bb-event", handleBudibaseEvent)
|
||||
iframe.contentWindow.addEventListener("keydown", handleKeydownEvent)
|
||||
const messageHandler = handlers[message.data.type] || handleBudibaseEvent
|
||||
messageHandler(message)
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
window.addEventListener("message", receiveMessage)
|
||||
})
|
||||
|
||||
// Remove all iframe event listeners on component destroy
|
||||
onDestroy(() => {
|
||||
if (iframe.contentWindow) {
|
||||
iframe.contentWindow.removeEventListener("bb-event", handleBudibaseEvent)
|
||||
iframe.contentWindow.removeEventListener("keydown", handleKeydownEvent)
|
||||
window.removeEventListener("message", receiveMessage) //
|
||||
}
|
||||
})
|
||||
|
||||
const handleBudibaseEvent = event => {
|
||||
const { type, data } = event.detail
|
||||
const { type, data } = event.data
|
||||
if (type === "select-component" && data.id) {
|
||||
store.actions.components.select({ _id: data.id })
|
||||
} else if (type === "update-prop") {
|
||||
|
@ -151,13 +159,14 @@
|
|||
store.actions.components.paste(destination, data.mode)
|
||||
}
|
||||
} else {
|
||||
console.warning(`Client sent unknown event type: ${type}`)
|
||||
console.warn(`Client sent unknown event type: ${type}`)
|
||||
}
|
||||
}
|
||||
|
||||
const handleKeydownEvent = event => {
|
||||
const { key } = event.data
|
||||
if (
|
||||
(event.key === "Delete" || event.key === "Backspace") &&
|
||||
(key === "Delete" || key === "Backspace") &&
|
||||
selectedComponentId &&
|
||||
["input", "textarea"].indexOf(
|
||||
iframe.contentWindow.document.activeElement?.tagName.toLowerCase()
|
||||
|
|
|
@ -84,17 +84,20 @@ export default `
|
|||
if (window.loadBudibase) {
|
||||
window.loadBudibase()
|
||||
document.documentElement.classList.add("loaded")
|
||||
window.dispatchEvent(new Event("iframe-loaded"))
|
||||
window.parent.postMessage({ type: "iframe-loaded" })
|
||||
} else {
|
||||
throw "The client library couldn't be loaded"
|
||||
}
|
||||
} catch (error) {
|
||||
window.dispatchEvent(new CustomEvent("error", { detail: error }))
|
||||
window.parent.postMessage({ type: "error", error })
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("message", receiveMessage)
|
||||
window.dispatchEvent(new Event("ready"))
|
||||
window.addEventListener("keydown", evt => {
|
||||
window.parent.postMessage({ type: "keydown", key: event.key })
|
||||
})
|
||||
window.parent.postMessage({ type: "ready" })
|
||||
</script>
|
||||
</head>
|
||||
<body/>
|
||||
|
|
|
@ -8,6 +8,12 @@
|
|||
import { Modal, ModalContent, ActionButton } from "@budibase/bbui"
|
||||
import { onDestroy } from "svelte"
|
||||
|
||||
const MessageTypes = {
|
||||
NOTIFICATION: "notification",
|
||||
CLOSE_SCREEN_MODAL: "close-screen-modal",
|
||||
INVALIDATE_DATASOURCE: "invalidate-datasource",
|
||||
}
|
||||
|
||||
let iframe
|
||||
let listenersAttached = false
|
||||
|
||||
|
@ -21,32 +27,33 @@
|
|||
notificationStore.actions.send(message, type, icon)
|
||||
}
|
||||
|
||||
function receiveMessage(message) {
|
||||
const handlers = {
|
||||
[MessageTypes.NOTIFICATION]: () => {
|
||||
proxyNotification(message.data)
|
||||
},
|
||||
[MessageTypes.CLOSE_SCREEN_MODAL]: peekStore.actions.hidePeek,
|
||||
[MessageTypes.INVALIDATE_DATASOURCE]: () => {
|
||||
invalidateDataSource(message.data)
|
||||
},
|
||||
}
|
||||
|
||||
const messageHandler = handlers[message.data.type]
|
||||
if (messageHandler) {
|
||||
messageHandler(message)
|
||||
} else {
|
||||
console.warning("Unknown event type", message?.data?.type)
|
||||
}
|
||||
}
|
||||
|
||||
const attachListeners = () => {
|
||||
// Mirror datasource invalidation to keep the parent window up to date
|
||||
iframe.contentWindow.addEventListener(
|
||||
"invalidate-datasource",
|
||||
invalidateDataSource
|
||||
)
|
||||
// Listen for a close event to close the screen peek
|
||||
iframe.contentWindow.addEventListener(
|
||||
"close-screen-modal",
|
||||
peekStore.actions.hidePeek
|
||||
)
|
||||
// Proxy notifications back to the parent window instead of iframe
|
||||
iframe.contentWindow.addEventListener("notification", proxyNotification)
|
||||
window.addEventListener("message", receiveMessage)
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
peekStore.actions.hidePeek()
|
||||
iframe.contentWindow.removeEventListener(
|
||||
"invalidate-datasource",
|
||||
invalidateDataSource
|
||||
)
|
||||
iframe.contentWindow.removeEventListener(
|
||||
"close-screen-modal",
|
||||
peekStore.actions.hidePeek
|
||||
)
|
||||
iframe.contentWindow.removeEventListener("notification", proxyNotification)
|
||||
window.removeEventListener("message", receiveMessage)
|
||||
}
|
||||
|
||||
const handleFullscreen = () => {
|
||||
|
|
|
@ -4,11 +4,7 @@ import { findComponentById, findComponentPathById } from "../utils/components"
|
|||
import { pingEndUser } from "../api"
|
||||
|
||||
const dispatchEvent = (type, data = {}) => {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("bb-event", {
|
||||
detail: { type, data },
|
||||
})
|
||||
)
|
||||
window.parent.postMessage({ type, data })
|
||||
}
|
||||
|
||||
const createBuilderStore = () => {
|
||||
|
|
|
@ -26,11 +26,19 @@ const createNotificationStore = () => {
|
|||
|
||||
// If peeking, pass notifications back to parent window
|
||||
if (get(routeStore).queryParams?.peek) {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("notification", {
|
||||
detail: { message, type, icon },
|
||||
})
|
||||
)
|
||||
window.parent.postMessage({
|
||||
type: "notification",
|
||||
detail: {
|
||||
message,
|
||||
type,
|
||||
icon,
|
||||
},
|
||||
})
|
||||
// window.dispatchEvent(
|
||||
// new CustomEvent("notification", {
|
||||
// detail: { message, type, icon },
|
||||
// })
|
||||
// )
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,10 @@ function copyExistingPropsOver(
|
|||
return table
|
||||
}
|
||||
|
||||
export function finaliseExternalTables(tables: { [key: string]: any }, entities: { [key: string]: any }) {
|
||||
export function finaliseExternalTables(
|
||||
tables: { [key: string]: any },
|
||||
entities: { [key: string]: any }
|
||||
) {
|
||||
const finalTables: { [key: string]: any } = {}
|
||||
const errors: { [key: string]: string } = {}
|
||||
for (let [name, table] of Object.entries(tables)) {
|
||||
|
|
Loading…
Reference in New Issue