diff --git a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx index 474d2730a757f..96c2329f6ffc4 100644 --- a/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx +++ b/superset-frontend/src/dashboard/components/nativeFilters/FilterBar/index.tsx @@ -232,32 +232,10 @@ const FilterBar: React.FC = ({ // eslint-disable-next-line react-hooks/exhaustive-deps }, [dashboardId, dataMaskAppliedText, history, updateKey, tabId]); - useEffect(() => { - window.parent.postMessage('iframe ready', '*'); - window.addEventListener('message', event => { - if (event.data.raFilter) { - const receivedFilterState = JSON.parse(event.data.raFilter); - const filterIds = Object.keys(receivedFilterState); - filterIds.forEach(filterId => { - setDataMaskSelected(draft => { - draft[receivedFilterState[filterId].id] = { - ...(getInitialDataMask( - receivedFilterState[filterId].id, - ) as DataMaskWithId), - ...receivedFilterState[filterId], - }; - }); - }); - } - }); - }, [setDataMaskSelected]); - const handleApply = useCallback(() => { dispatch(logEvent(LOG_ACTIONS_CHANGE_DASHBOARD_FILTER, {})); const filterIds = Object.keys(dataMaskSelected); - window.parent.postMessage(JSON.stringify(dataMaskSelected), '*'); - setUpdateKey(1); filterIds.forEach(filterId => { if (dataMaskSelected[filterId]) { diff --git a/superset-frontend/src/katalon/KatalonSyncDashboardState.tsx b/superset-frontend/src/katalon/KatalonSyncDashboardState.tsx new file mode 100644 index 0000000000000..4cc016605851e --- /dev/null +++ b/superset-frontend/src/katalon/KatalonSyncDashboardState.tsx @@ -0,0 +1,69 @@ +import React, { useEffect, useState } from 'react'; +import { useDispatch, shallowEqual, useSelector } from 'react-redux'; +import { useHistory } from 'react-router-dom'; +import { + useInitialization, + useNativeFiltersDataMask, +} from '../dashboard/components/nativeFilters/FilterBar/state'; +import { hydrateDashboard } from '../dashboard/actions/hydrate'; +import { useDashboard, useDashboardCharts } from '../hooks/apiResources'; + +function KatalonSyncDashboardState({ children }: any) { + const dispatch = useDispatch(); + const history = useHistory(); + const dashboardId = useSelector( + ({ dashboardInfo }) => dashboardInfo?.id, + ); + const isInitialized = useInitialization(); + const { result: dashboard } = useDashboard(dashboardId); + const { result: charts } = useDashboardCharts(dashboardId); + const currentFilters = useNativeFiltersDataMask(); + const [previousFilters, setPreviousFilters] = useState(currentFilters); + const [filtersFromParent, setFiltersFromParent] = useState(); + + // Send filters to parent + useEffect(() => { + const isApplyFiltersClicked = + isInitialized && !shallowEqual(previousFilters, currentFilters); + if (isApplyFiltersClicked) { + window.parent.postMessage(JSON.stringify(currentFilters), '*'); + } + setPreviousFilters(currentFilters); + }, [currentFilters]); + + // Receive filters from parent + useEffect(() => { + window.addEventListener('message', event => { + if (event.data.raFilter) { + const receivedFilters = JSON.parse(event.data.raFilter); + setFiltersFromParent(receivedFilters); + } + }); + }, []); + + // Send ready message to parent, so it can start sending filters + useEffect(() => { + if (isInitialized) { + window.parent.postMessage('iframe ready', '*'); + } + }, [isInitialized]); + + // Hydrate dashboard with received filters + useEffect(() => { + if (isInitialized && filtersFromParent) { + dispatch( + hydrateDashboard({ + history, + dashboard, + charts, + activeTabs: undefined, + dataMask: filtersFromParent, + }), + ); + } + }, [filtersFromParent]); + + return <>{children}; +} + +export default KatalonSyncDashboardState; diff --git a/superset-frontend/src/setup/setupPluginsExtra.ts b/superset-frontend/src/setup/setupPluginsExtra.ts index f95f284344560..0282aeb2526b6 100644 --- a/superset-frontend/src/setup/setupPluginsExtra.ts +++ b/superset-frontend/src/setup/setupPluginsExtra.ts @@ -18,9 +18,12 @@ */ import { getExtensionsRegistry } from '@superset-ui/core'; import KatalonSliceHeaderControls from 'src/katalon/KatalonSliceHeaderControls'; +import KatalonSyncDashboardState from '../katalon/KatalonSyncDashboardState'; // For individual deployments to add custom overrides export default function setupPluginsExtra() { const extensionRegistry = getExtensionsRegistry(); + + extensionRegistry.set('root.context.provider', KatalonSyncDashboardState); extensionRegistry.set('dashboard.slice.header', KatalonSliceHeaderControls); }