Add action to close peek modal and proxy notifications from the iframe
This commit is contained in:
parent
c50460b88f
commit
473ccd27fa
|
@ -0,0 +1,17 @@
|
|||
<script>
|
||||
import { Body } from "@budibase/bbui"
|
||||
</script>
|
||||
|
||||
<div class="root">
|
||||
<Body size="S">This action doesn't require any additional settings.</Body>
|
||||
<Body size="S">
|
||||
This action won't do anything if there isn't a screen-peek modal open.
|
||||
</Body>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.root {
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
|
@ -6,6 +6,7 @@ import TriggerAutomation from "./TriggerAutomation.svelte"
|
|||
import ValidateForm from "./ValidateForm.svelte"
|
||||
import LogOut from "./LogOut.svelte"
|
||||
import ClearForm from "./ClearForm.svelte"
|
||||
import CloseScreenPeekModal from "./CloseScreenPeekModal.svelte"
|
||||
|
||||
// Defines which actions are available to configure in the front end.
|
||||
// Unfortunately the "name" property is used as the identifier so please don't
|
||||
|
@ -47,4 +48,8 @@ export default [
|
|||
name: "Clear Form",
|
||||
component: ClearForm,
|
||||
},
|
||||
{
|
||||
name: "Close Screen-Peek Modal",
|
||||
component: CloseScreenPeekModal,
|
||||
},
|
||||
]
|
||||
|
|
|
@ -1,49 +1,61 @@
|
|||
<script>
|
||||
import { peekStore, dataSourceStore, routeStore } from "../store"
|
||||
import { peekStore, dataSourceStore, notificationStore } from "../store"
|
||||
import { Modal, ModalContent, Button } from "@budibase/bbui"
|
||||
import { onDestroy } from "svelte"
|
||||
|
||||
let iframe
|
||||
let fullscreen = false
|
||||
let listenersAttached = false
|
||||
|
||||
const invalidateDataSource = event => {
|
||||
const { dataSourceId } = event.detail
|
||||
dataSourceStore.actions.invalidateDataSource(dataSourceId)
|
||||
}
|
||||
|
||||
const proxyNotification = event => {
|
||||
const { message, type, icon } = event.detail
|
||||
notificationStore.actions.send(message, type, icon)
|
||||
}
|
||||
|
||||
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-peek",
|
||||
peekStore.actions.hidePeek
|
||||
)
|
||||
// Proxy notifications back to the parent window instead of iframe
|
||||
iframe.contentWindow.addEventListener("notification", proxyNotification)
|
||||
}
|
||||
|
||||
const handleCancel = () => {
|
||||
peekStore.actions.hidePeek()
|
||||
iframe.contentWindow.removeEventListener(
|
||||
"invalidate-datasource",
|
||||
invalidateDataSource
|
||||
)
|
||||
peekStore.actions.hidePeek()
|
||||
fullscreen = false
|
||||
}
|
||||
|
||||
const navigate = () => {
|
||||
if ($peekStore.external) {
|
||||
window.location = $peekStore.href
|
||||
} else {
|
||||
routeStore.actions.navigate($peekStore.url)
|
||||
}
|
||||
peekStore.actions.hidePeek()
|
||||
iframe.contentWindow.removeEventListener(
|
||||
"close-screen-peek",
|
||||
peekStore.actions.hidePeek
|
||||
)
|
||||
iframe.contentWindow.removeEventListener("notification", proxyNotification)
|
||||
}
|
||||
|
||||
$: {
|
||||
if (iframe) {
|
||||
iframe.contentWindow.addEventListener(
|
||||
"invalidate-datasource",
|
||||
invalidateDataSource
|
||||
)
|
||||
if (iframe && !listenersAttached) {
|
||||
attachListeners()
|
||||
listenersAttached = true
|
||||
} else if (!iframe) {
|
||||
listenersAttached = false
|
||||
}
|
||||
}
|
||||
|
||||
onDestroy(() => {
|
||||
if (iframe) {
|
||||
iframe.contentWindow.removeEventListener(
|
||||
"invalidate-datasource",
|
||||
invalidateDataSource
|
||||
)
|
||||
handleCancel()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
@ -53,7 +65,7 @@
|
|||
<ModalContent
|
||||
showCancelButton={false}
|
||||
showConfirmButton={false}
|
||||
size="XL"
|
||||
size="L"
|
||||
showDivider={false}
|
||||
showCloseIcon={false}
|
||||
>
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { writable, get } from "svelte/store"
|
||||
import { generate } from "shortid"
|
||||
import { routeStore } from "./routes"
|
||||
|
||||
const NOTIFICATION_TIMEOUT = 3000
|
||||
|
||||
|
@ -22,6 +23,17 @@ const createNotificationStore = () => {
|
|||
if (block) {
|
||||
return
|
||||
}
|
||||
|
||||
// If peeking, pass notifications back to parent window
|
||||
if (get(routeStore).queryParams?.peek) {
|
||||
window.dispatchEvent(
|
||||
new CustomEvent("notification", {
|
||||
detail: { message, type, icon },
|
||||
})
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
store.set({
|
||||
id: generate(),
|
||||
type,
|
||||
|
@ -38,6 +50,7 @@ const createNotificationStore = () => {
|
|||
return {
|
||||
subscribe: store.subscribe,
|
||||
actions: {
|
||||
send,
|
||||
info: msg => send(msg, "info", "Info"),
|
||||
success: msg => send(msg, "success", "CheckmarkCircle"),
|
||||
warning: msg => send(msg, "warning", "Alert"),
|
||||
|
|
|
@ -44,7 +44,12 @@ const createRouteStore = () => {
|
|||
}
|
||||
const setQueryParams = queryParams => {
|
||||
store.update(state => {
|
||||
state.queryParams = queryParams
|
||||
state.queryParams = {
|
||||
...queryParams,
|
||||
// Never unset the peek param - screen peek modals should always be
|
||||
// in a peek state, even if they navigate to a different page
|
||||
peek: queryParams.peek || state.queryParams?.peek,
|
||||
}
|
||||
return state
|
||||
})
|
||||
}
|
||||
|
|
|
@ -99,6 +99,12 @@ const clearFormHandler = async (action, context) => {
|
|||
)
|
||||
}
|
||||
|
||||
const closeScreenPeekModalHandler = () => {
|
||||
// Emit this as a window event, so parent screens which are iframing us in
|
||||
// can close the modal
|
||||
window.dispatchEvent(new Event("close-screen-peek"))
|
||||
}
|
||||
|
||||
const handlerMap = {
|
||||
["Save Row"]: saveRowHandler,
|
||||
["Delete Row"]: deleteRowHandler,
|
||||
|
@ -109,6 +115,7 @@ const handlerMap = {
|
|||
["Refresh Datasource"]: refreshDatasourceHandler,
|
||||
["Log Out"]: logoutHandler,
|
||||
["Clear Form"]: clearFormHandler,
|
||||
["Close Screen-Peek Modal"]: closeScreenPeekModalHandler,
|
||||
}
|
||||
|
||||
const confirmTextMap = {
|
||||
|
|
Loading…
Reference in New Issue