diff --git a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx
index 73cdca34ed..faa1e046ef 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Tab.jsx
@@ -18,6 +18,7 @@
*/
import React from 'react';
import PropTypes from 'prop-types';
+import { styled } from '@superset-ui/core';
import DashboardComponent from '../../containers/DashboardComponent';
import DragDroppable from '../dnd/DragDroppable';
@@ -62,6 +63,17 @@ const defaultProps = {
onResizeStop() {},
};
+const TabTitleContainer = styled.div`
+ ${({ isHighlighted, theme: { gridUnit, colors } }) => `
+ padding: ${gridUnit}px ${gridUnit * 2}px;
+ margin: ${-gridUnit}px ${gridUnit * -2}px;
+ transition: box-shadow 0.2s ease-in-out;
+ ${
+ isHighlighted && `box-shadow: 0 0 ${gridUnit}px ${colors.primary.light1};`
+ }
+ `}
+`;
+
export default class Tab extends React.PureComponent {
constructor(props) {
super(props);
@@ -192,6 +204,7 @@ export default class Tab extends React.PureComponent {
editMode,
filters,
isFocused,
+ isHighlighted,
} = this.props;
return (
@@ -205,7 +218,11 @@ export default class Tab extends React.PureComponent {
editMode={editMode}
>
{({ dropIndicatorProps, dragSourceRef }) => (
-
+
}
-
+
)}
);
diff --git a/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx b/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx
index 427145b89e..bdf60f8f42 100644
--- a/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx
+++ b/superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx
@@ -33,7 +33,38 @@ import getLeafComponentIdFromPath from '../../util/getLeafComponentIdFromPath';
import { componentShape } from '../../util/propShapes';
import { NEW_TAB_ID, DASHBOARD_ROOT_ID } from '../../util/constants';
import { RENDER_TAB, RENDER_TAB_CONTENT } from './Tab';
-import { TAB_TYPE } from '../../util/componentTypes';
+import { CHART_TYPE, TAB_TYPE } from '../../util/componentTypes';
+import { getChartIdsInFilterScope } from '../../util/activeDashboardFilters';
+
+const findTabsWithChartsInScope = (
+ dashboardLayout,
+ chartsInScope,
+ childId,
+ tabId,
+ tabsToHighlight,
+) => {
+ if (
+ dashboardLayout[childId].type === CHART_TYPE &&
+ chartsInScope.includes(dashboardLayout[childId].meta.chartId)
+ ) {
+ tabsToHighlight.add(tabId);
+ }
+ if (
+ dashboardLayout[childId].children.length === 0 ||
+ (dashboardLayout[childId].type === TAB_TYPE && tabsToHighlight.has(childId))
+ ) {
+ return;
+ }
+ dashboardLayout[childId].children.forEach(subChildId =>
+ findTabsWithChartsInScope(
+ dashboardLayout,
+ chartsInScope,
+ subChildId,
+ tabId,
+ tabsToHighlight,
+ ),
+ );
+};
const propTypes = {
id: PropTypes.string.isRequired,
@@ -268,11 +299,30 @@ class Tabs extends React.PureComponent {
renderHoverMenu,
isComponentVisible: isCurrentTabVisible,
editMode,
+ focusedFilterScope,
+ dashboardLayout,
} = this.props;
const { children: tabIds } = tabsComponent;
const { tabIndex: selectedTabIndex, activeKey } = this.state;
+ const tabsToHighlight = new Set();
+ if (focusedFilterScope) {
+ const chartsInScope = getChartIdsInFilterScope({
+ filterScope: focusedFilterScope.scope,
+ });
+ tabIds.forEach(tabId => {
+ if (!tabsToHighlight.has(tabId)) {
+ findTabsWithChartsInScope(
+ dashboardLayout,
+ chartsInScope,
+ tabId,
+ tabId,
+ tabsToHighlight,
+ );
+ }
+ });
+ }
return (
}
>
diff --git a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
index f47a8734ab..42f408cd0d 100644
--- a/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
+++ b/superset-frontend/src/dashboard/containers/DashboardComponent.jsx
@@ -107,6 +107,7 @@ function mapStateToProps(
const component = dashboardLayout[id];
const props = {
component,
+ dashboardLayout,
parentComponent: dashboardLayout[parentId],
editMode: dashboardState.editMode,
undoLength: undoableLayout.past.length,