You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@superset.apache.org by vi...@apache.org on 2021/08/16 05:49:20 UTC
[superset] 30/34: fix(dashboard): cross filter chart highlight when
filters badge icon clicked (#16233)
This is an automated email from the ASF dual-hosted git repository.
villebro pushed a commit to branch 1.3
in repository https://gitbox.apache.org/repos/asf/superset.git
commit 90ad28bbe6b878b2008b5cec2fe891f4ba59d410
Author: Kamil Gabryjelski <ka...@gmail.com>
AuthorDate: Fri Aug 13 10:02:28 2021 +0200
fix(dashboard): cross filter chart highlight when filters badge icon clicked (#16233)
* fix(dashboard): cross filter chart highlight when filters badge icon pressed
* Fix tests
* Fix tests
* break out label logic
Co-authored-by: Ville Brofeldt <vi...@gmail.com>
(cherry picked from commit 517a678cd7a8531ceb2f0fdf64d275ef8c928879)
---
.../DetailsPanel/DetailsPanel.test.tsx | 5 ++
.../components/FiltersBadge/DetailsPanel/index.tsx | 10 ++++
.../dashboard/components/FiltersBadge/selectors.ts | 65 +++++++++++++---------
3 files changed, 54 insertions(+), 26 deletions(-)
diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel/DetailsPanel.test.tsx b/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel/DetailsPanel.test.tsx
index 239df0f..12efe2c 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel/DetailsPanel.test.tsx
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel/DetailsPanel.test.tsx
@@ -96,6 +96,7 @@ test('Should render "appliedCrossFilterIndicators"', () => {
<DetailsPanel {...props}>
<div data-test="details-panel-content">Content</div>
</DetailsPanel>,
+ { useRedux: true },
);
userEvent.click(screen.getByTestId('details-panel-content'));
@@ -129,6 +130,7 @@ test('Should render "appliedIndicators"', () => {
<DetailsPanel {...props}>
<div data-test="details-panel-content">Content</div>
</DetailsPanel>,
+ { useRedux: true },
);
userEvent.click(screen.getByTestId('details-panel-content'));
@@ -160,6 +162,7 @@ test('Should render "incompatibleIndicators"', () => {
<DetailsPanel {...props}>
<div data-test="details-panel-content">Content</div>
</DetailsPanel>,
+ { useRedux: true },
);
userEvent.click(screen.getByTestId('details-panel-content'));
@@ -193,6 +196,7 @@ test('Should render "unsetIndicators"', () => {
<DetailsPanel {...props}>
<div data-test="details-panel-content">Content</div>
</DetailsPanel>,
+ { useRedux: true },
);
userEvent.click(screen.getByTestId('details-panel-content'));
@@ -227,6 +231,7 @@ test('Should render empty', () => {
<DetailsPanel {...props}>
<div data-test="details-panel-content">Content</div>
</DetailsPanel>,
+ { useRedux: true },
);
expect(screen.getByTestId('details-panel-content')).toBeInTheDocument();
diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel/index.tsx b/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel/index.tsx
index 6a311c3..5405823 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel/index.tsx
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/DetailsPanel/index.tsx
@@ -17,6 +17,7 @@
* under the License.
*/
import React, { useEffect, useState } from 'react';
+import { useSelector } from 'react-redux';
import { Global, css } from '@emotion/react';
import { t, useTheme } from '@superset-ui/core';
import {
@@ -35,6 +36,7 @@ import {
} from 'src/dashboard/components/FiltersBadge/Styles';
import { Indicator } from 'src/dashboard/components/FiltersBadge/selectors';
import FilterIndicator from 'src/dashboard/components/FiltersBadge/FilterIndicator';
+import { RootState } from 'src/dashboard/types';
export interface DetailsPanelProps {
appliedCrossFilterIndicators: Indicator[];
@@ -55,6 +57,9 @@ const DetailsPanelPopover = ({
}: DetailsPanelProps) => {
const [visible, setVisible] = useState(false);
const theme = useTheme();
+ const activeTabs = useSelector<RootState>(
+ state => state.dashboardState?.activeTabs,
+ );
// we don't need to clean up useEffect, setting { once: true } removes the event listener after handle function is called
useEffect(() => {
@@ -65,6 +70,11 @@ const DetailsPanelPopover = ({
}
}, [visible]);
+ // if tabs change, popover doesn't close automatically
+ useEffect(() => {
+ setVisible(false);
+ }, [activeTabs]);
+
const getDefaultActivePanel = () => {
const result = [];
if (appliedCrossFilterIndicators.length) {
diff --git a/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts b/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts
index 48d706f..34bdfce 100644
--- a/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts
+++ b/superset-frontend/src/dashboard/components/FiltersBadge/selectors.ts
@@ -20,7 +20,12 @@ import { NO_TIME_RANGE, TIME_FILTER_MAP } from 'src/explore/constants';
import { getChartIdsInFilterScope } from 'src/dashboard/util/activeDashboardFilters';
import { ChartConfiguration, Filters } from 'src/dashboard/reducers/types';
import { DataMaskStateWithId, DataMaskType } from 'src/dataMask/types';
-import { FeatureFlag, isFeatureEnabled } from '@superset-ui/core';
+import {
+ ensureIsArray,
+ FeatureFlag,
+ FilterState,
+ isFeatureEnabled,
+} from '@superset-ui/core';
import { Layout } from '../../types';
import { getTreeCheckedItems } from '../nativeFilters/FiltersConfigModal/FiltersConfigForm/FilterScope/utils';
@@ -50,6 +55,16 @@ type Filter = {
datasourceId: string;
};
+const extractLabel = (filter?: FilterState): string | null => {
+ if (filter?.label) {
+ return filter.label;
+ }
+ if (filter?.value) {
+ return ensureIsArray(filter?.value).join(', ');
+ }
+ return null;
+};
+
const selectIndicatorValue = (
columnKey: string,
filter: Filter,
@@ -182,16 +197,16 @@ export const selectNativeIndicatorsForChart = (
const rejectedColumns = getRejectedColumns(chart);
const getStatus = ({
- value,
+ label,
column,
type = DataMaskType.NativeFilters,
}: {
- value: any;
+ label: string | null;
column?: string;
type?: DataMaskType;
}): IndicatorStatus => {
// a filter is only considered unset if it's value is null
- const hasValue = value !== null;
+ const hasValue = label !== null;
if (type === DataMaskType.CrossFilters && hasValue) {
return IndicatorStatus.CrossFilterApplied;
}
@@ -220,19 +235,14 @@ export const selectNativeIndicatorsForChart = (
)
.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];
- }
+ const filterState = dataMask[nativeFilter.id]?.filterState;
+ const label = extractLabel(filterState);
return {
column,
name: nativeFilter.name,
path: [nativeFilter.id],
- status: getStatus({ value, column }),
- value,
+ status: getStatus({ label, column }),
+ value: label,
};
});
}
@@ -249,23 +259,26 @@ export const selectNativeIndicatorsForChart = (
),
)
.map(chartConfig => {
- let value =
- dataMask[chartConfig.id]?.filterState?.label ??
- dataMask[chartConfig.id]?.filterState?.value ??
- null;
- if (!Array.isArray(value) && value !== null) {
- value = [value];
- }
+ const filterState = dataMask[chartConfig.id]?.filterState;
+ const label = extractLabel(filterState);
+ const filtersState = filterState?.filters;
+ const column = filtersState && Object.keys(filtersState)[0];
+
+ const dashboardLayoutItem = Object.values(dashboardLayout).find(
+ layoutItem => layoutItem?.meta?.chartId === chartConfig.id,
+ );
return {
- name: Object.values(dashboardLayout).find(
- layoutItem => layoutItem?.meta?.chartId === chartConfig.id,
- )?.meta?.sliceName as string,
- path: [`${chartConfig.id}`],
+ column,
+ name: dashboardLayoutItem?.meta?.sliceName as string,
+ path: [
+ ...(dashboardLayoutItem?.parents ?? []),
+ dashboardLayoutItem?.id,
+ ],
status: getStatus({
- value,
+ label,
type: DataMaskType.CrossFilters,
}),
- value,
+ value: label,
};
})
.filter(filter => filter.status === IndicatorStatus.CrossFilterApplied);