From 86b795cd3631353de0b208b1746e125d314332ab Mon Sep 17 00:00:00 2001 From: Mohamed Halat <halatmohamed@hotmail.com> Date: Thu, 3 Apr 2025 06:37:52 -0400 Subject: [PATCH] feat(embedding-sdk): emit data-mask events through embedded sdk to iframe parent (#31331) --- superset-embedded-sdk/src/index.ts | 23 ++++++++++++++----- .../src/components/UiConfigContext/index.tsx | 4 ++++ superset-frontend/src/embedded/index.tsx | 19 ++++++++++++++- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/superset-embedded-sdk/src/index.ts b/superset-embedded-sdk/src/index.ts index 7bcf5dcd2e..3944c8cc4f 100644 --- a/superset-embedded-sdk/src/index.ts +++ b/superset-embedded-sdk/src/index.ts @@ -37,6 +37,7 @@ export type UiConfigType = { hideTitle?: boolean hideTab?: boolean hideChartControls?: boolean + emitDataMasks?: boolean filters?: { [key: string]: boolean | undefined visible?: boolean @@ -73,11 +74,12 @@ export type Size = { } export type EmbeddedDashboard = { - getScrollSize: () => Promise<Size> - unmount: () => void - getDashboardPermalink: (anchor: string) => Promise<string> - getActiveTabs: () => Promise<string[]> -} + getScrollSize: () => Promise<Size>; + unmount: () => void; + getDashboardPermalink: (anchor: string) => Promise<string>; + getActiveTabs: () => Promise<string[]>; + getDataMasks: (callbackFn: (dataMasks: any[]) => void) => void; +}; /** * Embeds a Superset dashboard into the page using an iframe. @@ -117,6 +119,9 @@ export async function embedDashboard({ if(dashboardUiConfig.hideChartControls) { configNumber += 8 } + if (dashboardUiConfig.emitDataMasks) { + configNumber += 16 + } } return configNumber } @@ -204,12 +209,18 @@ export async function embedDashboard({ const getScrollSize = () => ourPort.get<Size>('getScrollSize'); const getDashboardPermalink = (anchor: string) => ourPort.get<string>('getDashboardPermalink', { anchor }); - const getActiveTabs = () => ourPort.get<string[]>('getActiveTabs') + const getActiveTabs = () => ourPort.get<string[]>('getActiveTabs'); + const getDataMasks = (callbackFn: (dataMasks: any[]) => void) => { + ourPort.start(); + ourPort.defineMethod("getDataMasks", callbackFn); + }; + return { getScrollSize, unmount, getDashboardPermalink, getActiveTabs, + getDataMasks, }; } diff --git a/superset-frontend/src/components/UiConfigContext/index.tsx b/superset-frontend/src/components/UiConfigContext/index.tsx index 99c0a506a5..7843967669 100644 --- a/superset-frontend/src/components/UiConfigContext/index.tsx +++ b/superset-frontend/src/components/UiConfigContext/index.tsx @@ -26,6 +26,8 @@ interface UiConfigType { hideTab: boolean; hideNav: boolean; hideChartControls: boolean; + // Only used in superset-embedded-sdk to emit data masks to the parent window + emitDataMasks: boolean; } interface EmbeddedUiConfigProviderProps { children: JSX.Element; @@ -36,6 +38,7 @@ export const UiConfigContext = createContext<UiConfigType>({ hideTab: false, hideNav: false, hideChartControls: false, + emitDataMasks: false, }); export const useUiConfig = () => useContext(UiConfigContext); @@ -49,6 +52,7 @@ export const EmbeddedUiConfigProvider: FC<EmbeddedUiConfigProviderProps> = ({ hideTab: (config & 2) !== 0, hideNav: (config & 4) !== 0, hideChartControls: (config & 8) !== 0, + emitDataMasks: (config & 16) !== 0, }); return ( diff --git a/superset-frontend/src/embedded/index.tsx b/superset-frontend/src/embedded/index.tsx index 5145052c8b..5331c20421 100644 --- a/superset-frontend/src/embedded/index.tsx +++ b/superset-frontend/src/embedded/index.tsx @@ -24,6 +24,7 @@ import Switchboard from '@superset-ui/switchboard'; import getBootstrapData from 'src/utils/getBootstrapData'; import setupClient from 'src/setup/setupClient'; import setupPlugins from 'src/setup/setupPlugins'; +import { useUiConfig } from 'src/components/UiConfigContext'; import { RootContextProviders } from 'src/views/RootContextProviders'; import { store, USER_LOADED } from 'src/views/store'; import ErrorBoundary from 'src/components/ErrorBoundary'; @@ -51,11 +52,27 @@ const LazyDashboardPage = lazy( ), ); +const EmbededLazyDashboardPage = () => { + const uiConfig = useUiConfig(); + + // Emit data mask changes to the parent window + if (uiConfig?.emitDataMasks) { + log('setting up Switchboard event emitter'); + + store.subscribe(() => { + const state = store.getState(); + Switchboard.emit('getDataMasks', state.dataMask); + }); + } + + return <LazyDashboardPage idOrSlug={bootstrapData.embedded!.dashboard_id} />; +}; + const EmbeddedRoute = () => ( <Suspense fallback={<Loading />}> <RootContextProviders> <ErrorBoundary> - <LazyDashboardPage idOrSlug={bootstrapData.embedded!.dashboard_id} /> + <EmbededLazyDashboardPage /> </ErrorBoundary> <ToastContainer position="top" /> </RootContextProviders> -- GitLab