diff --git a/superset-frontend/spec/javascripts/dashboard/components/FiltersBadge_spec.tsx b/superset-frontend/spec/javascripts/dashboard/components/FiltersBadge_spec.tsx
index d6bd4974d54..f24b973199d 100644
--- a/superset-frontend/spec/javascripts/dashboard/components/FiltersBadge_spec.tsx
+++ b/superset-frontend/spec/javascripts/dashboard/components/FiltersBadge_spec.tsx
@@ -20,10 +20,15 @@ import React from 'react';
import { shallow } from 'enzyme';
import { supersetTheme } from '@superset-ui/core';
import { Provider } from 'react-redux';
+import { Store } from 'redux';
import * as SupersetUI from '@superset-ui/core';
-import { CHART_UPDATE_SUCCEEDED } from 'src/chart/chartAction';
+import { styledMount as mount } from 'spec/helpers/theming';
+import {
+ CHART_RENDERING_SUCCEEDED,
+ CHART_UPDATE_SUCCEEDED,
+} from 'src/chart/chartAction';
import { buildActiveFilters } from 'src/dashboard/util/activeDashboardFilters';
-import FiltersBadge from 'src/dashboard/containers/FiltersBadge';
+import { FiltersBadge } from 'src/dashboard/components/FiltersBadge';
import {
getMockStoreWithFilters,
getMockStoreWithNativeFilters,
@@ -34,6 +39,15 @@ import { dashboardWithFilter } from 'spec/fixtures/mockDashboardLayout';
import Icons from 'src/components/Icons';
import { FeatureFlag } from 'src/featureFlags';
+const defaultStore = getMockStoreWithFilters();
+function setup(store: Store = defaultStore) {
+ return mount(
+
+
+ ,
+ );
+}
+
describe('FiltersBadge', () => {
// there's this bizarre "active filters" thing
// that doesn't actually use any kind of state management.
@@ -71,9 +85,7 @@ describe('FiltersBadge', () => {
,
,
);
- expect(
- wrapper.dive().find('[data-test="applied-filter-count"]'),
- ).not.toExist();
+ expect(wrapper.find('[data-test="applied-filter-count"]')).not.toExist();
});
it('shows the indicator when filters have been applied', () => {
@@ -91,14 +103,13 @@ describe('FiltersBadge', () => {
],
dashboardFilters,
});
- const wrapper = shallow(
- ,
- ).dive();
- expect(wrapper.dive().find('DetailsPanelPopover')).toExist();
- expect(
- wrapper.dive().find('[data-test="applied-filter-count"]'),
- ).toHaveText('1');
- expect(wrapper.dive().find('WarningFilled')).not.toExist();
+ store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
+ const wrapper = setup(store);
+ expect(wrapper.find('DetailsPanelPopover')).toExist();
+ expect(wrapper.find('[data-test="applied-filter-count"]')).toHaveText(
+ '1',
+ );
+ expect(wrapper.find('WarningFilled')).not.toExist();
});
it("shows a warning when there's a rejected filter", () => {
@@ -118,19 +129,18 @@ describe('FiltersBadge', () => {
],
dashboardFilters,
});
- const wrapper = shallow(
- ,
- ).dive();
- expect(wrapper.dive().find('DetailsPanelPopover')).toExist();
+ store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
+ const wrapper = setup(store);
+ expect(wrapper.find('DetailsPanelPopover')).toExist();
+ expect(wrapper.find('[data-test="applied-filter-count"]')).toHaveText(
+ '0',
+ );
expect(
- wrapper.dive().find('[data-test="applied-filter-count"]'),
- ).toHaveText('0');
- expect(
- wrapper.dive().find('[data-test="incompatible-filter-count"]'),
+ wrapper.find('[data-test="incompatible-filter-count"]'),
).toHaveText('1');
// to look at the shape of the wrapper use:
- // console.log(wrapper.dive().debug())
- expect(wrapper.dive().find(Icons.AlertSolid)).toExist();
+ // console.log(wrapper.debug())
+ expect(wrapper.find(Icons.AlertSolid)).toExist();
});
});
@@ -149,14 +159,9 @@ describe('FiltersBadge', () => {
},
],
});
- const wrapper = shallow(
-
- ,
- ,
- );
- expect(
- wrapper.dive().find('[data-test="applied-filter-count"]'),
- ).not.toExist();
+ store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
+ const wrapper = setup(store);
+ expect(wrapper.find('[data-test="applied-filter-count"]')).not.toExist();
});
it('shows the indicator when filters have been applied', () => {
@@ -177,14 +182,13 @@ describe('FiltersBadge', () => {
},
],
});
- const wrapper = shallow(
- ,
- ).dive();
- expect(wrapper.dive().find('DetailsPanelPopover')).toExist();
- expect(
- wrapper.dive().find('[data-test="applied-filter-count"]'),
- ).toHaveText('1');
- expect(wrapper.dive().find('WarningFilled')).not.toExist();
+ store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
+ const wrapper = setup(store);
+ expect(wrapper.find('DetailsPanelPopover')).toExist();
+ expect(wrapper.find('[data-test="applied-filter-count"]')).toHaveText(
+ '1',
+ );
+ expect(wrapper.find('WarningFilled')).not.toExist();
});
it("shows a warning when there's a rejected filter", () => {
@@ -207,17 +211,16 @@ describe('FiltersBadge', () => {
},
],
});
- const wrapper = shallow(
- ,
- ).dive();
- expect(wrapper.dive().find('DetailsPanelPopover')).toExist();
+ store.dispatch({ type: CHART_RENDERING_SUCCEEDED, key: sliceId });
+ const wrapper = setup(store);
+ expect(wrapper.find('DetailsPanelPopover')).toExist();
+ expect(wrapper.find('[data-test="applied-filter-count"]')).toHaveText(
+ '0',
+ );
expect(
- wrapper.dive().find('[data-test="applied-filter-count"]'),
- ).toHaveText('0');
- expect(
- wrapper.dive().find('[data-test="incompatible-filter-count"]'),
+ wrapper.find('[data-test="incompatible-filter-count"]'),
).toHaveText('1');
- expect(wrapper.dive().find(Icons.AlertSolid)).toExist();
+ expect(wrapper.find(Icons.AlertSolid)).toExist();
});
});
});
diff --git a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tabs_spec.jsx b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tabs_spec.jsx
index 517ac305ace..0985fd6ed93 100644
--- a/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tabs_spec.jsx
+++ b/superset-frontend/spec/javascripts/dashboard/components/gridComponents/Tabs_spec.jsx
@@ -31,7 +31,7 @@ import DashboardComponent from 'src/dashboard/containers/DashboardComponent';
import DeleteComponentButton from 'src/dashboard/components/DeleteComponentButton';
import HoverMenu from 'src/dashboard/components/menu/HoverMenu';
import DragDroppable from 'src/dashboard/components/dnd/DragDroppable';
-import Tabs from 'src/dashboard/components/gridComponents/Tabs';
+import { Tabs } from 'src/dashboard/components/gridComponents/Tabs';
import { DASHBOARD_ROOT_ID } from 'src/dashboard/util/constants';
import emptyDashboardLayout from 'src/dashboard/fixtures/emptyDashboardLayout';
import { dashboardLayoutWithTabs } from 'spec/fixtures/mockDashboardLayout';
@@ -66,14 +66,15 @@ describe('Tabs', () => {
nativeFilters: nativeFilters.filters,
};
+ const mockStore = getMockStore({
+ ...initialState,
+ dashboardLayout: dashboardLayoutWithTabs,
+ dashboardFilters: {},
+ });
+
function setup(overrideProps) {
// We have to wrap provide DragDropContext for the underlying DragDroppable
// otherwise we cannot assert on DragDroppable children
- const mockStore = getMockStore({
- ...initialState,
- dashboardLayout: dashboardLayoutWithTabs,
- dashboardFilters: {},
- });
const wrapper = mount(
diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/index.tsx b/superset-frontend/src/dashboard/components/FiltersBadge/index.tsx
index 506dc5216fe..5cc86e1ebdb 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/index.tsx
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/index.tsx
@@ -16,29 +16,159 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React from 'react';
+import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import { useDispatch, useSelector } from 'react-redux';
+import { uniqWith } from 'lodash';
import cx from 'classnames';
import Icon from 'src/components/Icon';
import Icons from 'src/components/Icons';
+import { usePrevious } from 'src/common/hooks/usePrevious';
+import { DataMaskStateWithId } from 'src/dataMask/types';
import DetailsPanelPopover from './DetailsPanel';
import { Pill } from './Styles';
-import { Indicator } from './selectors';
+import {
+ Indicator,
+ IndicatorStatus,
+ selectIndicatorsForChart,
+ selectNativeIndicatorsForChart,
+} from './selectors';
+import { setDirectPathToChild } from '../../actions/dashboardState';
+import {
+ ChartsState,
+ DashboardInfo,
+ DashboardLayout,
+ RootState,
+} from '../../types';
+import { Filters } from '../../reducers/types';
export interface FiltersBadgeProps {
- appliedCrossFilterIndicators: Indicator[];
- appliedIndicators: Indicator[];
- unsetIndicators: Indicator[];
- incompatibleIndicators: Indicator[];
- onHighlightFilterSource: (path: string[]) => void;
+ chartId: number;
}
-const FiltersBadge = ({
- appliedCrossFilterIndicators,
- appliedIndicators,
- unsetIndicators,
- incompatibleIndicators,
- onHighlightFilterSource,
-}: FiltersBadgeProps) => {
+const sortByStatus = (indicators: Indicator[]): Indicator[] => {
+ const statuses = [
+ IndicatorStatus.Applied,
+ IndicatorStatus.Unset,
+ IndicatorStatus.Incompatible,
+ ];
+ return indicators.sort(
+ (a, b) =>
+ statuses.indexOf(a.status as IndicatorStatus) -
+ statuses.indexOf(b.status as IndicatorStatus),
+ );
+};
+
+export const FiltersBadge = ({ chartId }: FiltersBadgeProps) => {
+ const dispatch = useDispatch();
+ const datasources = useSelector(state => state.datasources);
+ const dashboardFilters = useSelector(
+ state => state.dashboardFilters,
+ );
+ const nativeFilters = useSelector(
+ state => state.nativeFilters?.filters,
+ );
+ const dashboardInfo = useSelector(
+ state => state.dashboardInfo,
+ );
+ const charts = useSelector(state => state.charts);
+ const present = useSelector(
+ state => state.dashboardLayout.present,
+ );
+ const dataMask = useSelector(
+ state => state.dataMask,
+ );
+
+ const [nativeIndicators, setNativeIndicators] = useState([]);
+ const [dashboardIndicators, setDashboardIndicators] = useState(
+ [],
+ );
+
+ const onHighlightFilterSource = useCallback(
+ (path: string[]) => {
+ dispatch(setDirectPathToChild(path));
+ },
+ [dispatch],
+ );
+
+ const chart = charts[chartId];
+ const prevChartStatus = usePrevious(chart?.chartStatus);
+
+ const showIndicators = useCallback(
+ () =>
+ chart?.chartStatus && ['rendered', 'success'].includes(chart.chartStatus),
+ [chart.chartStatus],
+ );
+ useEffect(() => {
+ if (!showIndicators) {
+ setDashboardIndicators([]);
+ }
+ if (prevChartStatus !== 'success') {
+ setDashboardIndicators(
+ selectIndicatorsForChart(chartId, dashboardFilters, datasources, chart),
+ );
+ }
+ }, [
+ chart,
+ chartId,
+ dashboardFilters,
+ datasources,
+ prevChartStatus,
+ showIndicators,
+ ]);
+
+ useEffect(() => {
+ if (!showIndicators) {
+ setNativeIndicators([]);
+ }
+ if (prevChartStatus !== 'success') {
+ setNativeIndicators(
+ selectNativeIndicatorsForChart(
+ nativeFilters,
+ dataMask,
+ chartId,
+ chart,
+ present,
+ dashboardInfo.metadata?.chart_configuration,
+ ),
+ );
+ }
+ }, [
+ chart,
+ chartId,
+ dashboardInfo.metadata?.chart_configuration,
+ dataMask,
+ nativeFilters,
+ present,
+ prevChartStatus,
+ showIndicators,
+ ]);
+
+ const indicators = useMemo(
+ () =>
+ uniqWith(
+ sortByStatus([...dashboardIndicators, ...nativeIndicators]),
+ (ind1, ind2) =>
+ ind1.column === ind2.column &&
+ ind1.name === ind2.name &&
+ (ind1.status !== IndicatorStatus.Applied ||
+ ind2.status !== IndicatorStatus.Applied),
+ ),
+ [dashboardIndicators, nativeIndicators],
+ );
+
+ const appliedCrossFilterIndicators = indicators.filter(
+ indicator => indicator.status === IndicatorStatus.CrossFilterApplied,
+ );
+ const appliedIndicators = indicators.filter(
+ indicator => indicator.status === IndicatorStatus.Applied,
+ );
+ const unsetIndicators = indicators.filter(
+ indicator => indicator.status === IndicatorStatus.Unset,
+ );
+ const incompatibleIndicators = indicators.filter(
+ indicator => indicator.status === IndicatorStatus.Incompatible,
+ );
+
if (
!appliedCrossFilterIndicators.length &&
!appliedIndicators.length &&
@@ -89,4 +219,4 @@ const FiltersBadge = ({
);
};
-export default FiltersBadge;
+export default React.memo(FiltersBadge);
diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts b/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts
index 8b5854dfe16..48d706fc835 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts
@@ -18,10 +18,7 @@
*/
import { NO_TIME_RANGE, TIME_FILTER_MAP } from 'src/explore/constants';
import { getChartIdsInFilterScope } from 'src/dashboard/util/activeDashboardFilters';
-import {
- ChartConfiguration,
- NativeFiltersState,
-} from 'src/dashboard/reducers/types';
+import { ChartConfiguration, Filters } from 'src/dashboard/reducers/types';
import { DataMaskStateWithId, DataMaskType } from 'src/dataMask/types';
import { FeatureFlag, isFeatureEnabled } from '@superset-ui/core';
import { Layout } from '../../types';
@@ -147,12 +144,8 @@ export const selectIndicatorsForChart = (
chartId: number,
filters: { [key: number]: Filter },
datasources: { [key: string]: Datasource },
- charts: any,
+ chart: any,
): Indicator[] => {
- const chart = charts[chartId];
- // no indicators if chart is loading
- if (chart.chartStatus === 'loading') return [];
-
// for now we only need to know which columns are compatible/incompatible,
// so grab the columns from the applied/rejected filters
const appliedColumns = getAppliedColumns(chart);
@@ -178,15 +171,13 @@ export const selectIndicatorsForChart = (
};
export const selectNativeIndicatorsForChart = (
- nativeFilters: NativeFiltersState,
+ nativeFilters: Filters,
dataMask: DataMaskStateWithId,
chartId: number,
- charts: any,
+ chart: any,
dashboardLayout: Layout,
chartConfiguration: ChartConfiguration = {},
): Indicator[] => {
- const chart = charts[chartId];
-
const appliedColumns = getAppliedColumns(chart);
const rejectedColumns = getRejectedColumns(chart);
@@ -218,29 +209,32 @@ export const selectNativeIndicatorsForChart = (
let nativeFilterIndicators: any = [];
if (isFeatureEnabled(FeatureFlag.DASHBOARD_NATIVE_FILTERS)) {
- nativeFilterIndicators = Object.values(nativeFilters.filters)
- .filter(nativeFilter =>
- getTreeCheckedItems(nativeFilter.scope, dashboardLayout).some(
- layoutItem => dashboardLayout[layoutItem]?.meta?.chartId === chartId,
- ),
- )
- .map(nativeFilter => {
- const column = nativeFilter.targets[0]?.column?.name;
- let value =
- dataMask[nativeFilter.id]?.filterState?.label ??
- dataMask[nativeFilter.id]?.filterState?.value ??
- null;
- if (!Array.isArray(value) && value !== null) {
- value = [value];
- }
- return {
- column,
- name: nativeFilter.name,
- path: [nativeFilter.id],
- status: getStatus({ value, column }),
- value,
- };
- });
+ nativeFilterIndicators =
+ nativeFilters &&
+ Object.values(nativeFilters)
+ .filter(nativeFilter =>
+ getTreeCheckedItems(nativeFilter.scope, dashboardLayout).some(
+ layoutItem =>
+ dashboardLayout[layoutItem]?.meta?.chartId === chartId,
+ ),
+ )
+ .map(nativeFilter => {
+ const column = nativeFilter.targets[0]?.column?.name;
+ let value =
+ dataMask[nativeFilter.id]?.filterState?.label ??
+ dataMask[nativeFilter.id]?.filterState?.value ??
+ null;
+ if (!Array.isArray(value) && value !== null) {
+ value = [value];
+ }
+ return {
+ column,
+ name: nativeFilter.name,
+ path: [nativeFilter.id],
+ status: getStatus({ value, column }),
+ value,
+ };
+ });
}
let crossFilterIndicators: any = [];
diff --git a/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx b/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
index fc67bb56299..3416fef388d 100644
--- a/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeader/SliceHeader.test.tsx
@@ -93,7 +93,7 @@ jest.mock('src/dashboard/components/SliceHeaderControls', () => ({
),
}));
-jest.mock('src/dashboard/containers/FiltersBadge', () => ({
+jest.mock('src/dashboard/components/FiltersBadge', () => ({
__esModule: true,
default: (props: any) => (
diff --git a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
index d6f41100da5..2e0e234b611 100644
--- a/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
+++ b/superset-frontend/src/dashboard/components/SliceHeader/index.tsx
@@ -22,7 +22,7 @@ import { Tooltip } from 'src/components/Tooltip';
import { useSelector } from 'react-redux';
import EditableTitle from 'src/components/EditableTitle';
import SliceHeaderControls from 'src/dashboard/components/SliceHeaderControls';
-import FiltersBadge from 'src/dashboard/containers/FiltersBadge';
+import FiltersBadge from 'src/dashboard/components/FiltersBadge';
import Icon from 'src/components/Icon';
import { RootState } from 'src/dashboard/types';
import FilterIndicator from 'src/dashboard/components/FiltersBadge/FilterIndicator';
diff --git a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
index 01be44f91ff..32b07953e1e 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/ChartHolder.jsx
@@ -20,6 +20,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import cx from 'classnames';
import { useTheme } from '@superset-ui/core';
+import { useSelector } from 'react-redux';
import { getChartIdsInFilterScope } from 'src/dashboard/util/activeDashboardFilters';
import Chart from '../../containers/Chart';
@@ -30,13 +31,13 @@ import HoverMenu from '../menu/HoverMenu';
import ResizableContainer from '../resizable/ResizableContainer';
import getChartAndLabelComponentIdFromPath from '../../util/getChartAndLabelComponentIdFromPath';
import { componentShape } from '../../util/propShapes';
-import { ROW_TYPE, COLUMN_TYPE } from '../../util/componentTypes';
+import { COLUMN_TYPE, ROW_TYPE } from '../../util/componentTypes';
import {
- GRID_MIN_COLUMN_COUNT,
- GRID_MIN_ROW_UNITS,
GRID_BASE_UNIT,
GRID_GUTTER_SIZE,
+ GRID_MIN_COLUMN_COUNT,
+ GRID_MIN_ROW_UNITS,
} from '../../util/constants';
const CHART_MARGIN = 32;
@@ -72,6 +73,21 @@ const defaultProps = {
directPathLastUpdated: 0,
};
+/**
+ * Selects the chart scope of the filter input that has focus.
+ *
+ * @returns {{chartId: number, scope: { scope: string[], immune: string[] }} | null }
+ * the scope of the currently focused filter, if any
+ */
+function selectFocusedFilterScope(dashboardState, dashboardFilters) {
+ if (!dashboardState.focusedFilterField) return null;
+ const { chartId, column } = dashboardState.focusedFilterField;
+ return {
+ chartId,
+ scope: dashboardFilters[chartId].scopes[column],
+ };
+}
+
/**
* Renders any styles necessary to highlight the chart's relationship to the focused filter.
*
@@ -85,8 +101,16 @@ const defaultProps = {
* If ChartHolder were a function component, this could be implemented as a hook instead.
*/
const FilterFocusHighlight = React.forwardRef(
- ({ chartId, focusedFilterScope, nativeFilters, ...otherProps }, ref) => {
+ ({ chartId, ...otherProps }, ref) => {
const theme = useTheme();
+
+ const nativeFilters = useSelector(state => state.nativeFilters);
+ const dashboardState = useSelector(state => state.dashboardState);
+ const dashboardFilters = useSelector(state => state.dashboardFilters);
+ const focusedFilterScope = selectFocusedFilterScope(
+ dashboardState,
+ dashboardFilters,
+ );
const focusedNativeFilterId = nativeFilters.focusedFilterId;
if (!(focusedFilterScope || focusedNativeFilterId))
return ;
@@ -239,8 +263,6 @@ class ChartHolder extends React.Component {
editMode,
isComponentVisible,
dashboardId,
- focusedFilterScope,
- nativeFilters,
} = this.props;
// inherit the size of parent columns
@@ -298,8 +320,6 @@ class ChartHolder extends React.Component {
>
jest.fn(props => (
diff --git a/superset-frontend/src/dashboard/components/gridComponents/index.js b/superset-frontend/src/dashboard/components/gridComponents/index.js
index 27f419c9dd9..ce014f8d57c 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/index.js
+++ b/superset-frontend/src/dashboard/components/gridComponents/index.js
@@ -34,7 +34,7 @@ import Divider from './Divider';
import Header from './Header';
import Row from './Row';
import Tab from './Tab';
-import Tabs from './Tabs';
+import TabsConnected from './Tabs';
export { default as ChartHolder } from './ChartHolder';
export { default as Markdown } from './Markdown';
@@ -53,5 +53,5 @@ export const componentLookup = {
[HEADER_TYPE]: Header,
[ROW_TYPE]: Row,
[TAB_TYPE]: Tab,
- [TABS_TYPE]: Tabs,
+ [TABS_TYPE]: TabsConnected,
};
diff --git a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
index 296b3bd1413..eb31a724882 100644
--- a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
+++ b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
@@ -64,29 +64,8 @@ const defaultProps = {
isComponentVisible: true,
};
-/**
- * Selects the chart scope of the filter input that has focus.
- *
- * @returns {{chartId: number, scope: { scope: string[], immune: string[] }} | null }
- * the scope of the currently focused filter, if any
- */
-function selectFocusedFilterScope(dashboardState, dashboardFilters) {
- if (!dashboardState.focusedFilterField) return null;
- const { chartId, column } = dashboardState.focusedFilterField;
- return {
- chartId,
- scope: dashboardFilters[chartId].scopes[column],
- };
-}
-
function mapStateToProps(
- {
- dashboardLayout: undoableLayout,
- dashboardState,
- dashboardInfo,
- dashboardFilters,
- nativeFilters,
- },
+ { dashboardLayout: undoableLayout, dashboardState, dashboardInfo },
ownProps,
) {
const dashboardLayout = undoableLayout.present;
@@ -104,11 +83,6 @@ function mapStateToProps(
activeTabs: dashboardState.activeTabs,
directPathLastUpdated: dashboardState.directPathLastUpdated,
dashboardId: dashboardInfo.id,
- nativeFilters,
- focusedFilterScope: selectFocusedFilterScope(
- dashboardState,
- dashboardFilters,
- ),
};
// rows and columns need more data about their child dimensions
diff --git a/superset-frontend/src/dashboard/containers/FiltersBadge.tsx b/superset-frontend/src/dashboard/containers/FiltersBadge.tsx
deleted file mode 100644
index 546b96303f8..00000000000
--- a/superset-frontend/src/dashboard/containers/FiltersBadge.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-import { connect } from 'react-redux';
-import { bindActionCreators, Dispatch } from 'redux';
-import { uniqWith } from 'lodash';
-import { setDirectPathToChild } from 'src/dashboard/actions/dashboardState';
-import {
- selectIndicatorsForChart,
- Indicator,
- IndicatorStatus,
- selectNativeIndicatorsForChart,
-} from 'src/dashboard/components/FiltersBadge/selectors';
-import FiltersBadge from 'src/dashboard/components/FiltersBadge';
-
-export interface FiltersBadgeProps {
- chartId: number;
-}
-
-const mapDispatchToProps = (dispatch: Dispatch) =>
- bindActionCreators(
- {
- onHighlightFilterSource: setDirectPathToChild,
- },
- dispatch,
- );
-
-const sortByStatus = (indicators: Indicator[]): Indicator[] => {
- const statuses = [
- IndicatorStatus.Applied,
- IndicatorStatus.Unset,
- IndicatorStatus.Incompatible,
- ];
- return indicators.sort(
- (a, b) =>
- statuses.indexOf(a.status as IndicatorStatus) -
- statuses.indexOf(b.status as IndicatorStatus),
- );
-};
-
-const mapStateToProps = (
- {
- datasources,
- dashboardFilters,
- nativeFilters,
- dashboardInfo,
- charts,
- dataMask,
- dashboardLayout: { present },
- }: any,
- { chartId }: FiltersBadgeProps,
-) => {
- const dashboardIndicators = selectIndicatorsForChart(
- chartId,
- dashboardFilters,
- datasources,
- charts,
- );
-
- const nativeIndicators = selectNativeIndicatorsForChart(
- nativeFilters,
- dataMask,
- chartId,
- charts,
- present,
- dashboardInfo.metadata?.chart_configuration,
- );
-
- const indicators = uniqWith(
- sortByStatus([...dashboardIndicators, ...nativeIndicators]),
- (ind1, ind2) =>
- ind1.column === ind2.column &&
- ind1.name === ind2.name &&
- (ind1.status !== IndicatorStatus.Applied ||
- ind2.status !== IndicatorStatus.Applied),
- );
-
- const appliedCrossFilterIndicators = indicators.filter(
- indicator => indicator.status === IndicatorStatus.CrossFilterApplied,
- );
- const appliedIndicators = indicators.filter(
- indicator => indicator.status === IndicatorStatus.Applied,
- );
- const unsetIndicators = indicators.filter(
- indicator => indicator.status === IndicatorStatus.Unset,
- );
- const incompatibleIndicators = indicators.filter(
- indicator => indicator.status === IndicatorStatus.Incompatible,
- );
-
- return {
- chartId,
- appliedIndicators,
- appliedCrossFilterIndicators,
- unsetIndicators,
- incompatibleIndicators,
- };
-};
-
-export default connect(mapStateToProps, mapDispatchToProps)(FiltersBadge);