mirror of
https://github.com/apache/superset.git
synced 2026-06-08 09:09:27 +00:00
fix(dashboard): resolve tab reorder state sync issues (#36855)
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import type { FC } from 'react';
|
||||
import { css, styled, useTheme } from '@apache-superset/core/ui';
|
||||
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
@@ -161,7 +162,9 @@ export const StyledLineEditableTabs = styled(EditableTabs)`
|
||||
}
|
||||
`;
|
||||
|
||||
export const LineEditableTabs = Object.assign(StyledLineEditableTabs, {
|
||||
export const LineEditableTabs: FC<TabsProps> & {
|
||||
TabPane: typeof StyledTabPane;
|
||||
} = Object.assign(StyledLineEditableTabs, {
|
||||
TabPane: StyledTabPane,
|
||||
});
|
||||
|
||||
|
||||
@@ -362,7 +362,7 @@ const Tabs = props => {
|
||||
setActiveKey(currentActiveTabId);
|
||||
}
|
||||
},
|
||||
[props.component, props.updateComponents, selectedTabIndex],
|
||||
[props.component, props.updateComponents, selectedTabIndex, activeKey],
|
||||
);
|
||||
|
||||
const {
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
ReactElement,
|
||||
RefObject,
|
||||
useCallback,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react';
|
||||
import { styled } from '@apache-superset/core/ui';
|
||||
@@ -61,6 +62,16 @@ const StyledTabsContainer = styled.div<{ isDragging?: boolean }>`
|
||||
height: calc(100% - 47px);
|
||||
}
|
||||
|
||||
/* Ensure tab labels maintain full opacity during drag */
|
||||
.ant-tabs-tab {
|
||||
.dragdroppable-tab,
|
||||
.editable-title,
|
||||
textarea {
|
||||
opacity: 1;
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Hide ink-bar during drag */
|
||||
${({ isDragging }) =>
|
||||
isDragging &&
|
||||
@@ -126,7 +137,7 @@ const DraggableTabNode: React.FC<Readonly<DraggableTabNodeProps>> = ({
|
||||
...props.style,
|
||||
position: 'relative',
|
||||
transform: transform ? `translate3d(${transform.x}px, 0, 0)` : undefined,
|
||||
transition,
|
||||
transition: isDragging ? 'none' : transition,
|
||||
cursor: disabled ? 'default' : 'move',
|
||||
zIndex: isDragging ? 1000 : 'auto',
|
||||
opacity: 1,
|
||||
@@ -163,6 +174,10 @@ const TabsRenderer = memo<TabsRendererProps>(
|
||||
}) => {
|
||||
const [activeId, setActiveId] = useState<string | null>(null);
|
||||
|
||||
// Use ref to always have access to the current tabIds in callbacks
|
||||
const tabIdsRef = useRef(tabIds);
|
||||
tabIdsRef.current = tabIds;
|
||||
|
||||
const sensor = useSensor(PointerSensor, {
|
||||
activationConstraint: { distance: 10 },
|
||||
});
|
||||
@@ -173,14 +188,18 @@ const TabsRenderer = memo<TabsRendererProps>(
|
||||
|
||||
const onDragEnd = useCallback(
|
||||
({ active, over }: DragEndEvent) => {
|
||||
const currentTabIds = tabIdsRef.current;
|
||||
// Only reorder when we have a valid drop target and both IDs are found
|
||||
if (active.id !== over?.id && onTabsReorder) {
|
||||
const activeIndex = tabIds.findIndex(id => id === active.id);
|
||||
const overIndex = tabIds.findIndex(id => id === over?.id);
|
||||
onTabsReorder(activeIndex, overIndex);
|
||||
const activeIndex = currentTabIds.findIndex(id => id === active.id);
|
||||
const overIndex = currentTabIds.findIndex(id => id === over?.id);
|
||||
if (activeIndex !== -1 && overIndex !== -1) {
|
||||
onTabsReorder(activeIndex, overIndex);
|
||||
}
|
||||
}
|
||||
setActiveId(null);
|
||||
},
|
||||
[onTabsReorder, tabIds],
|
||||
[onTabsReorder],
|
||||
);
|
||||
|
||||
const onDragCancel = useCallback(() => {
|
||||
@@ -220,6 +239,7 @@ const TabsRenderer = memo<TabsRendererProps>(
|
||||
{...(editMode && {
|
||||
renderTabBar: (tabBarProps, DefaultTabBar) => (
|
||||
<DndContext
|
||||
key={tabIds.join('-')}
|
||||
sensors={[sensor]}
|
||||
onDragStart={onDragStart}
|
||||
onDragEnd={onDragEnd}
|
||||
|
||||
Reference in New Issue
Block a user