Add action to close peek modal and proxy notifications from the iframe
This commit is contained in:
parent
3916b735a1
commit
def7f7a949
|
@ -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 ValidateForm from "./ValidateForm.svelte"
|
||||||
import LogOut from "./LogOut.svelte"
|
import LogOut from "./LogOut.svelte"
|
||||||
import ClearForm from "./ClearForm.svelte"
|
import ClearForm from "./ClearForm.svelte"
|
||||||
|
import CloseScreenPeekModal from "./CloseScreenPeekModal.svelte"
|
||||||
|
|
||||||
// Defines which actions are available to configure in the front end.
|
// Defines which actions are available to configure in the front end.
|
||||||
// Unfortunately the "name" property is used as the identifier so please don't
|
// Unfortunately the "name" property is used as the identifier so please don't
|
||||||
|
@ -47,4 +48,8 @@ export default [
|
||||||
name: "Clear Form",
|
name: "Clear Form",
|
||||||
component: ClearForm,
|
component: ClearForm,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "Close Screen-Peek Modal",
|
||||||
|
component: CloseScreenPeekModal,
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,49 +1,61 @@
|
||||||
<script>
|
<script>
|
||||||
import { peekStore, dataSourceStore, routeStore } from "../store"
|
import { peekStore, dataSourceStore, notificationStore } from "../store"
|
||||||
import { Modal, ModalContent, Button } from "@budibase/bbui"
|
import { Modal, ModalContent, Button } from "@budibase/bbui"
|
||||||
import { onDestroy } from "svelte"
|
import { onDestroy } from "svelte"
|
||||||
|
|
||||||
let iframe
|
let iframe
|
||||||
let fullscreen = false
|
let listenersAttached = false
|
||||||
|
|
||||||
const invalidateDataSource = event => {
|
const invalidateDataSource = event => {
|
||||||
const { dataSourceId } = event.detail
|
const { dataSourceId } = event.detail
|
||||||
dataSourceStore.actions.invalidateDataSource(dataSourceId)
|
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 = () => {
|
const handleCancel = () => {
|
||||||
|
peekStore.actions.hidePeek()
|
||||||
iframe.contentWindow.removeEventListener(
|
iframe.contentWindow.removeEventListener(
|
||||||
"invalidate-datasource",
|
"invalidate-datasource",
|
||||||
invalidateDataSource
|
invalidateDataSource
|
||||||
)
|
)
|
||||||
peekStore.actions.hidePeek()
|
iframe.contentWindow.removeEventListener(
|
||||||
fullscreen = false
|
"close-screen-peek",
|
||||||
}
|
peekStore.actions.hidePeek
|
||||||
|
)
|
||||||
const navigate = () => {
|
iframe.contentWindow.removeEventListener("notification", proxyNotification)
|
||||||
if ($peekStore.external) {
|
|
||||||
window.location = $peekStore.href
|
|
||||||
} else {
|
|
||||||
routeStore.actions.navigate($peekStore.url)
|
|
||||||
}
|
|
||||||
peekStore.actions.hidePeek()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$: {
|
$: {
|
||||||
if (iframe) {
|
if (iframe && !listenersAttached) {
|
||||||
iframe.contentWindow.addEventListener(
|
attachListeners()
|
||||||
"invalidate-datasource",
|
listenersAttached = true
|
||||||
invalidateDataSource
|
} else if (!iframe) {
|
||||||
)
|
listenersAttached = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
iframe.contentWindow.removeEventListener(
|
handleCancel()
|
||||||
"invalidate-datasource",
|
|
||||||
invalidateDataSource
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
@ -53,7 +65,7 @@
|
||||||
<ModalContent
|
<ModalContent
|
||||||
showCancelButton={false}
|
showCancelButton={false}
|
||||||
showConfirmButton={false}
|
showConfirmButton={false}
|
||||||
size="XL"
|
size="L"
|
||||||
showDivider={false}
|
showDivider={false}
|
||||||
showCloseIcon={false}
|
showCloseIcon={false}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { writable, get } from "svelte/store"
|
import { writable, get } from "svelte/store"
|
||||||
import { generate } from "shortid"
|
import { generate } from "shortid"
|
||||||
|
import { routeStore } from "./routes"
|
||||||
|
|
||||||
const NOTIFICATION_TIMEOUT = 3000
|
const NOTIFICATION_TIMEOUT = 3000
|
||||||
|
|
||||||
|
@ -22,6 +23,17 @@ const createNotificationStore = () => {
|
||||||
if (block) {
|
if (block) {
|
||||||
return
|
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({
|
store.set({
|
||||||
id: generate(),
|
id: generate(),
|
||||||
type,
|
type,
|
||||||
|
@ -38,6 +50,7 @@ const createNotificationStore = () => {
|
||||||
return {
|
return {
|
||||||
subscribe: store.subscribe,
|
subscribe: store.subscribe,
|
||||||
actions: {
|
actions: {
|
||||||
|
send,
|
||||||
info: msg => send(msg, "info", "Info"),
|
info: msg => send(msg, "info", "Info"),
|
||||||
success: msg => send(msg, "success", "CheckmarkCircle"),
|
success: msg => send(msg, "success", "CheckmarkCircle"),
|
||||||
warning: msg => send(msg, "warning", "Alert"),
|
warning: msg => send(msg, "warning", "Alert"),
|
||||||
|
|
|
@ -44,7 +44,12 @@ const createRouteStore = () => {
|
||||||
}
|
}
|
||||||
const setQueryParams = queryParams => {
|
const setQueryParams = queryParams => {
|
||||||
store.update(state => {
|
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
|
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 = {
|
const handlerMap = {
|
||||||
["Save Row"]: saveRowHandler,
|
["Save Row"]: saveRowHandler,
|
||||||
["Delete Row"]: deleteRowHandler,
|
["Delete Row"]: deleteRowHandler,
|
||||||
|
@ -109,6 +115,7 @@ const handlerMap = {
|
||||||
["Refresh Datasource"]: refreshDatasourceHandler,
|
["Refresh Datasource"]: refreshDatasourceHandler,
|
||||||
["Log Out"]: logoutHandler,
|
["Log Out"]: logoutHandler,
|
||||||
["Clear Form"]: clearFormHandler,
|
["Clear Form"]: clearFormHandler,
|
||||||
|
["Close Screen-Peek Modal"]: closeScreenPeekModalHandler,
|
||||||
}
|
}
|
||||||
|
|
||||||
const confirmTextMap = {
|
const confirmTextMap = {
|
||||||
|
|
Loading…
Reference in New Issue