Skip to content

Add reorder option to tabs #4583#3872

Merged
Wroud merged 38 commits intodevelfrom
4583-cb-3739-add-reorder-option-to-tabs-scripts-objects
Nov 20, 2025
Merged

Add reorder option to tabs #4583#3872
Wroud merged 38 commits intodevelfrom
4583-cb-3739-add-reorder-option-to-tabs-scripts-objects

Conversation

@SychevAndrey
Copy link
Copy Markdown
Contributor

Panels

Screen.Recording.2025-11-05.at.15.43.18.mov

Navigator Tabs

Screen.Recording.2025-11-05.at.15.45.16.mov

ObjectView tabs remain not reorderable. Do we want to move them also?
Screenshot 2025-11-05 at 15 47 00

@SychevAndrey SychevAndrey self-assigned this Nov 5, 2025
@SychevAndrey
Copy link
Copy Markdown
Contributor Author

SqlResultsTabs

Screen.Recording.2025-11-05.at.18.01.56.mov

@SychevAndrey
Copy link
Copy Markdown
Contributor Author

Changed reorderArray implementation for useHeaderDnD (see implementation and tests). I believe this is the right implementation and we don't use this header dnd yet so it's safe to change it now.

Comment thread webapp/common-typescript/@dbeaver/js-helpers/src/reorderArray.ts Outdated
Comment thread webapp/packages/core-ui/src/Tabs/TabsContainer/TabsContainer.ts Outdated
manual,
});

const tabOrderKey = container ? `tabs-order-${container.areaLabel}` : 'tabs-no-persist';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

areaLabel can't be used as a stable storage key, please introduce new prop for TabsState


const onReorder =
onReorderProp ||
((draggedTabId: string, targetTabId: string, position: 'before' | 'after') => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please use named function

Comment thread webapp/packages/core-ui/src/Tabs/useTabDragAndDrop.ts
SychevAndrey and others added 4 commits November 12, 2025 10:58
- moved the tab order persistence logic into a new useTabOrderPersistence hook to make the flow is more obvious (we use this default persistence only with tabs container)
- introduced new reorderStateKey tab state to have an identifier for a tab panel, use it in canDrop check to prevent cross-panel DnD
-replaced reorderable prop with reorderStateKey, because without a key you can't use reordering
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds drag-and-drop reordering functionality to various tab components in the application, including Panels, Navigator Tabs, and SQL Result Tabs. The implementation introduces a new reusable hook system for tab reordering with persistent state storage.

Key changes:

  • Implemented a generic reorderArray utility function with comprehensive test coverage
  • Added useTabDragAndDrop and useTabOrderPersistence hooks for managing tab reordering
  • Integrated reordering capabilities into multiple tab components (ToolsPanel, NavigationTabs, SqlResultTabs, SideBarPanel)

Reviewed Changes

Copilot reviewed 28 out of 29 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
webapp/yarn.lock Added new dependencies for testing and drag-and-drop functionality
webapp/packages/plugin-tools-panel/src/ToolsPanel/ToolsPanel.tsx Integrated tab reordering with persistence for tools panel
webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabs.tsx Added reorder handler for SQL result tabs
webapp/packages/plugin-navigation-tabs/tsconfig.json Added js-helpers package reference
webapp/packages/plugin-navigation-tabs/src/NavigationTabs/NavigationTabsService.ts Refactored tabIdList getter to use persisted tab order and added reorderTab method
webapp/packages/plugin-navigation-tabs/src/NavigationTabs/NavigationTabsBar/NavigationTabsBar.tsx Implemented reorder callback for navigation tabs
webapp/packages/plugin-navigation-tabs/package.json Added js-helpers dependency
webapp/packages/core-ui/tsconfig.json Added references to react-dnd, react-tests, and cli packages
webapp/packages/core-ui/src/index.ts Exported new tab drag-and-drop utilities
webapp/packages/core-ui/src/Tabs/useTabOrderPersistence.ts New hook for persisting tab order across sessions
webapp/packages/core-ui/src/Tabs/useTabDragAndDrop.ts New hook providing drag-and-drop functionality for tabs
webapp/packages/core-ui/src/Tabs/TabsState.tsx Added reorder state key and callback support
webapp/packages/core-ui/src/Tabs/TabsContext.ts Extended context interface with reorder functionality
webapp/packages/core-ui/src/Tabs/TabsContainer/TabsContainer.ts Implemented applyOrder method for tab ordering
webapp/packages/core-ui/src/Tabs/TabsContainer/ITabsContainer.ts Added applyOrder to interface
webapp/packages/core-ui/src/Tabs/TabsBox/TabsBox.tsx Added reorder props support
webapp/packages/core-ui/src/Tabs/Tab/useTab.ts Added reorderStateKey getter
webapp/packages/core-ui/src/Tabs/Tab/Tab.tsx Integrated drag-and-drop functionality with visual feedback
webapp/packages/core-ui/src/Tabs/Tab/Tab.module.css Added CSS styles for drag-and-drop visual states
webapp/packages/core-ui/src/SideBarPanel/SideBarPanel.tsx Enabled tab reordering for sidebar panels
webapp/packages/core-ui/package.json Added test dependencies and react-dnd package
webapp/common-typescript/@dbeaver/js-helpers/src/reorderArray.ts New utility function for reordering array elements with multiple signature overloads
webapp/common-typescript/@dbeaver/js-helpers/src/reorderArray.test.ts Comprehensive test suite for reorderArray function
webapp/common-typescript/@dbeaver/js-helpers/src/index.ts Exported reorderArray utility
webapp/common-react/@dbeaver/react-data-grid/tsconfig.json Added js-helpers package reference
webapp/common-react/@dbeaver/react-data-grid/src/useHeaderDnD.ts Updated to use shared reorderArray utility
webapp/common-react/@dbeaver/react-data-grid/src/reorderArray.ts Removed local implementation in favor of shared utility
webapp/common-react/@dbeaver/react-data-grid/src/index.ts Removed reorderArray export
webapp/common-react/@dbeaver/react-data-grid/package.json Added js-helpers dependency

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread webapp/common-typescript/@dbeaver/js-helpers/src/reorderArray.ts
Comment thread webapp/packages/core-ui/src/Tabs/Tab/Tab.module.css
Comment thread webapp/packages/core-ui/src/Tabs/useTabOrderPersistence.ts Outdated
Comment thread webapp/packages/core-ui/src/Tabs/useTabOrderPersistence.ts Outdated
Comment thread webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabs.tsx Outdated
Comment thread webapp/packages/core-ui/src/Tabs/TabsState.tsx Outdated
…' of github.com:dbeaver/cloudbeaver into 4583-cb-3739-add-reorder-option-to-tabs-scripts-objects
sergeyteleshev
sergeyteleshev previously approved these changes Nov 13, 2025
Comment thread webapp/packages/core-ui/src/SideBarPanel/SideBarPanel.tsx Outdated
dropProps,
} = useTabDragAndDrop({
tabId,
stateKey: tab.reorderStateKey || undefined,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like tab.reorderStateKey has type of reorderStateKey?: string so there is no need for fallback?

export interface ITabDragAndDropOptions {
tabId: string;
stateKey: string | undefined;
onReorder: ((draggedTabId: string, targetTabId: string, position: 'before' | 'after') => void) | null;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we duplicate position: 'before' | 'after', probably we want to move it to separate type like TabReorderPosition

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We fixed it in one place but the type declaration repeats across entire pr)

draggable: !!stateKey,
onDragStart: (event, store) => {
event.stopPropagation();
store.setData('dbeaver-tab-id', tabId);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We repeat this variables across the hook, should we move them to const and use like this?
DBEAVER_TAB_ID = dbeaver-tab-id
store?.getData(DBEAVER_TAB_ID);

…er and update useTabOrderPersistence to not have dependencies on container
…olsPanel

Since we are not mutating a container state anymore, we have to update sorting separately in TabList level because it reads directly from the container.
Comment thread webapp/packages/core-ui/src/Tabs/useTabOrderPersistence.ts
Comment thread webapp/packages/core-ui/src/SideBarPanel/SideBarPanel.tsx Outdated
Comment thread webapp/packages/core-ui/src/Tabs/Tab/useTab.ts Outdated
Comment thread webapp/packages/core-ui/src/Tabs/TabsState.tsx Outdated
Comment thread webapp/packages/plugin-sql-editor/src/SqlResultTabs/SqlResultTabs.tsx Outdated
Comment thread webapp/packages/plugin-tools-panel/src/ToolsPanel/ToolsPanel.tsx Outdated
@SychevAndrey SychevAndrey requested a review from Wroud November 14, 2025 14:56
@Wroud Wroud merged commit 24b7b60 into devel Nov 20, 2025
9 of 10 checks passed
@Wroud Wroud deleted the 4583-cb-3739-add-reorder-option-to-tabs-scripts-objects branch November 20, 2025 11:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants