Skip to content

Commit

Permalink
fix: dashboard top level tabs edit (apache#19722)
Browse files Browse the repository at this point in the history
  • Loading branch information
diegomedina248 authored and philipher29 committed Jun 9, 2022
1 parent c37e53a commit ba615d0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 34 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,14 @@
*/
/* eslint-env browser */
import cx from 'classnames';
import React, { FC, useCallback, useEffect, useState, useMemo } from 'react';
import React, {
FC,
useCallback,
useEffect,
useState,
useMemo,
useRef,
} from 'react';
import { JsonObject, styled, css, t } from '@superset-ui/core';
import { Global } from '@emotion/react';
import { useDispatch, useSelector } from 'react-redux';
Expand Down Expand Up @@ -319,6 +326,27 @@ const DashboardBuilder: FC<DashboardBuilderProps> = () => {
[dashboardFiltersOpen, editMode, nativeFiltersEnabled],
);

// If a new tab was added, update the directPathToChild to reflect it
const currentTopLevelTabs = useRef(topLevelTabs);
useEffect(() => {
const currentTabsLength = currentTopLevelTabs.current?.children?.length;
const newTabsLength = topLevelTabs?.children?.length;

if (
currentTabsLength !== undefined &&
newTabsLength !== undefined &&
newTabsLength > currentTabsLength
) {
const lastTab = getDirectPathToTabIndex(
getRootLevelTabsComponent(dashboardLayout),
newTabsLength - 1,
);
dispatch(setDirectPathToChild(lastTab));
}

currentTopLevelTabs.current = topLevelTabs;
}, [topLevelTabs]);

const renderDraggableContent = useCallback(
({ dropIndicatorProps }: { dropIndicatorProps: JsonObject }) => (
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
// ParentSize uses resize observer so the dashboard will update size
// when its container size changes, due to e.g., builder side panel opening
import React, { FC, useEffect, useMemo, useState } from 'react';
import React, { FC, useEffect, useMemo } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
FeatureFlag,
Expand All @@ -36,7 +36,6 @@ import {
LayoutItem,
RootState,
} from 'src/dashboard/types';
import getLeafComponentIdFromPath from 'src/dashboard/util/getLeafComponentIdFromPath';
import {
DASHBOARD_GRID_ID,
DASHBOARD_ROOT_DEPTH,
Expand Down Expand Up @@ -68,29 +67,27 @@ const useNativeFilterScopes = () => {
};

const DashboardContainer: FC<DashboardContainerProps> = ({ topLevelTabs }) => {
const nativeFilterScopes = useNativeFilterScopes();
const dispatch = useDispatch();

const dashboardLayout = useSelector<RootState, DashboardLayout>(
state => state.dashboardLayout.present,
);
const nativeFilterScopes = useNativeFilterScopes();
const directPathToChild = useSelector<RootState, string[]>(
state => state.dashboardState.directPathToChild,
);
const charts = useSelector<RootState, ChartsState>(state => state.charts);
const [tabIndex, setTabIndex] = useState(
getRootLevelTabIndex(dashboardLayout, directPathToChild),
);

const dispatch = useDispatch();

useEffect(() => {
const tabIndex = useMemo(() => {
const nextTabIndex = findTabIndexByComponentId({
currentComponent: getRootLevelTabsComponent(dashboardLayout),
directPathToChild,
});
if (nextTabIndex > -1) {
setTabIndex(nextTabIndex);
}
}, [getLeafComponentIdFromPath(directPathToChild)]);

return nextTabIndex > -1
? nextTabIndex
: getRootLevelTabIndex(dashboardLayout, directPathToChild);
}, [dashboardLayout, directPathToChild]);

useEffect(() => {
if (
Expand Down
38 changes: 18 additions & 20 deletions superset-frontend/src/dashboard/components/gridComponents/Tabs.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,22 +155,6 @@ export class Tabs extends React.PureComponent {
this.setState(() => ({ tabIndex: maxIndex }));
}

if (nextTabsIds.length) {
const lastTabId = nextTabsIds[nextTabsIds.length - 1];
// if a new tab is added focus on it immediately
if (nextTabsIds.length > currTabsIds.length) {
// a new tab's path may be empty, here also need to set tabIndex
this.setState(() => ({
activeKey: lastTabId,
tabIndex: maxIndex,
}));
}
// if a tab is removed focus on the first
if (nextTabsIds.length < currTabsIds.length) {
this.setState(() => ({ activeKey: nextTabsIds[0] }));
}
}

if (nextProps.isComponentVisible) {
const nextFocusComponent = getLeafComponentIdFromPath(
nextProps.directPathToChild,
Expand All @@ -179,7 +163,14 @@ export class Tabs extends React.PureComponent {
this.props.directPathToChild,
);

if (nextFocusComponent !== currentFocusComponent) {
// If the currently selected component is different than the new one,
// or the tab length/order changed, calculate the new tab index and
// replace it if it's different than the current one
if (
nextFocusComponent !== currentFocusComponent ||
(nextFocusComponent === currentFocusComponent &&
currTabsIds !== nextTabsIds)
) {
const nextTabIndex = findTabIndexByComponentId({
currentComponent: nextProps.component,
directPathToChild: nextProps.directPathToChild,
Expand Down Expand Up @@ -219,9 +210,12 @@ export class Tabs extends React.PureComponent {
});
};

handleEdit = (key, action) => {
handleEdit = (event, action) => {
const { component, createComponent } = this.props;
if (action === 'add') {
// Prevent the tab container to be selected
event?.stopPropagation?.();

createComponent({
destination: {
id: component.id,
Expand All @@ -234,7 +228,7 @@ export class Tabs extends React.PureComponent {
},
});
} else if (action === 'remove') {
this.showDeleteConfirmModal(key);
this.showDeleteConfirmModal(event);
}
};

Expand All @@ -261,7 +255,11 @@ export class Tabs extends React.PureComponent {
}

handleDeleteTab(tabIndex) {
this.handleClickTab(Math.max(0, tabIndex - 1));
// If we're removing the currently selected tab,
// select the previous one (if any)
if (this.state.tabIndex === tabIndex) {
this.handleClickTab(Math.max(0, tabIndex - 1));
}
}

handleDropOnTab(dropResult) {
Expand Down

0 comments on commit ba615d0

Please sign in to comment.