From 85999836e6cc7ab54f1357fafdd563e301352c6c Mon Sep 17 00:00:00 2001 From: anastasiia Date: Thu, 11 Jan 2024 08:16:45 -0500 Subject: [PATCH] support moving tab to another panel at specific place --- .../CurrentTabContent/Header/TabButton.tsx | 46 ++++++++---- .../CurrentTabContent/Header/index.tsx | 70 ++++++++++++++----- .../providers/RepositoriesContextProvider.tsx | 36 +++++----- 3 files changed, 104 insertions(+), 48 deletions(-) diff --git a/client/src/Project/CurrentTabContent/Header/TabButton.tsx b/client/src/Project/CurrentTabContent/Header/TabButton.tsx index caee41fd65..a0d8895994 100644 --- a/client/src/Project/CurrentTabContent/Header/TabButton.tsx +++ b/client/src/Project/CurrentTabContent/Header/TabButton.tsx @@ -23,7 +23,12 @@ type Props = TabType & { isActive: boolean; side: 'left' | 'right'; isOnlyTab: boolean; - moveTab: (i: number, j: number) => void; + moveTab: ( + i: number, + j: number, + sourceSide: 'left' | 'right', + targetSide: 'left' | 'right', + ) => void; i: number; repoRef?: string; path?: string; @@ -59,21 +64,23 @@ const TabButton = ({ useContext(TabsContext.Handlers); const ref = useRef(null); const [{ handlerId }, drop] = useDrop({ - accept: `tab-${side}`, - canDrop: (item: DraggableTabItem) => item.side === side, + accept: [`tab-left`, `tab-right`], + canDrop: (item: DraggableTabItem) => true, collect(monitor) { return { handlerId: monitor.getHandlerId(), }; }, hover(item: DraggableTabItem, monitor) { - if (!ref.current || item.side !== side) { + if (!ref.current) { return; } const dragIndex = item.index; const hoverIndex = i; + const sourceSide = item.side as 'left' | 'right'; + const targetSide = side as 'left' | 'right'; // Don't replace items with themselves - if (dragIndex === hoverIndex) { + if (dragIndex === hoverIndex && sourceSide === targetSide) { return; } // Determine rectangle on screen @@ -83,26 +90,37 @@ const TabButton = ({ (hoverBoundingRect.right - hoverBoundingRect.left) / 2; // Determine mouse position const clientOffset = monitor.getClientOffset(); - // Get pixels to the top + // Get pixels to the left const hoverClientX = (clientOffset?.x || 0) - hoverBoundingRect.left; - // Only perform the move when the mouse has crossed half of the items height - // When dragging downwards, only move when the cursor is below 50% - // When dragging upwards, only move when the cursor is above 50% - // Dragging downwards - if (dragIndex < hoverIndex && hoverClientX < hoverMiddleX) { + // Only perform the move when the mouse has crossed half of the items width + // When dragging left, only move when the cursor is below 50% + // When dragging right, only move when the cursor is above 50% + // Dragging left + if ( + dragIndex < hoverIndex && + hoverClientX < hoverMiddleX && + sourceSide === targetSide + ) { return; } - // Dragging upwards - if (dragIndex > hoverIndex && hoverClientX > hoverMiddleX) { + // Dragging right + if ( + dragIndex > hoverIndex && + hoverClientX > hoverMiddleX && + sourceSide === targetSide + ) { return; } // Time to actually perform the action - moveTab(dragIndex, hoverIndex); + moveTab(dragIndex, hoverIndex, sourceSide, targetSide); // Note: we're mutating the monitor item here! // Generally it's better to avoid mutations, // but it's good here for the sake of performance // to avoid expensive index searches. item.index = hoverIndex; + if (sourceSide !== targetSide) { + item.side = targetSide; + } }, }); const [{ isDragging }, drag] = useDrag({ diff --git a/client/src/Project/CurrentTabContent/Header/index.tsx b/client/src/Project/CurrentTabContent/Header/index.tsx index c1c648c33e..af024fa5fa 100644 --- a/client/src/Project/CurrentTabContent/Header/index.tsx +++ b/client/src/Project/CurrentTabContent/Header/index.tsx @@ -1,7 +1,7 @@ import React, { memo, useCallback, useContext, useMemo } from 'react'; import HeaderRightPart from '../../../components/Header/HeaderRightPart'; import { TabsContext } from '../../../context/tabsContext'; -import { TabTypesEnum } from '../../../types/general'; +import { TabType, TabTypesEnum } from '../../../types/general'; import AddTabButton from './AddTabButton'; import TabButton from './TabButton'; @@ -14,27 +14,63 @@ const ProjectHeader = ({ side }: Props) => { const { tab } = useContext( TabsContext[side === 'left' ? 'CurrentLeft' : 'CurrentRight'], ); - const { setLeftTabs, setRightTabs } = useContext(TabsContext.Handlers); + const { setLeftTabs, setRightTabs, setActiveRightTab, setActiveLeftTab } = + useContext(TabsContext.Handlers); const tabs = useMemo(() => { return side === 'left' ? leftTabs : rightTabs; }, [side, rightTabs, leftTabs]); const moveTab = useCallback( - (dragIndex: number, hoverIndex: number) => { - const action = side === 'left' ? setLeftTabs : setRightTabs; - action((prevTabs) => { - const newTabs = JSON.parse(JSON.stringify(prevTabs)); - newTabs.splice(dragIndex, 1); - const newTab = prevTabs[dragIndex]; - newTabs.splice( - hoverIndex, - 0, - newTab.type === TabTypesEnum.FILE && newTab.isTemp - ? { ...newTab, isTemp: false } - : newTab, - ); - return newTabs; - }); + ( + dragIndex: number, + hoverIndex: number, + sourceSide: 'left' | 'right', + targetSide: 'left' | 'right', + ) => { + if (sourceSide === targetSide) { + const action = side === 'left' ? setLeftTabs : setRightTabs; + action((prevTabs) => { + const newTabs = JSON.parse(JSON.stringify(prevTabs)); + newTabs.splice(dragIndex, 1); + const newTab = prevTabs[dragIndex]; + newTabs.splice( + hoverIndex, + 0, + newTab.type === TabTypesEnum.FILE && newTab.isTemp + ? { ...newTab, isTemp: false } + : newTab, + ); + return newTabs; + }); + } else { + const sourceAction = sourceSide === 'left' ? setLeftTabs : setRightTabs; + const sourceTabAction = + sourceSide === 'left' ? setActiveLeftTab : setActiveRightTab; + const targetAction = targetSide === 'left' ? setLeftTabs : setRightTabs; + const targetTabAction = + targetSide === 'left' ? setActiveLeftTab : setActiveRightTab; + + sourceAction((prevSourceTabs) => { + const newSourceTabs = JSON.parse(JSON.stringify(prevSourceTabs)); + const [movedTab] = newSourceTabs.splice(dragIndex, 1); + sourceTabAction( + newSourceTabs.length + ? newSourceTabs[dragIndex - 1] || newSourceTabs[0] + : null, + ); + + targetAction((prevTargetTabs) => { + const newTargetTabs = JSON.parse(JSON.stringify(prevTargetTabs)); + if (!newTargetTabs.find((t: TabType) => t.key === movedTab.key)) { + newTargetTabs.splice(hoverIndex, 0, movedTab); + } + targetTabAction(movedTab); + return newTargetTabs; + }); + + return newSourceTabs; + }); + } }, [side], ); diff --git a/client/src/context/providers/RepositoriesContextProvider.tsx b/client/src/context/providers/RepositoriesContextProvider.tsx index 13b9e5ee31..347fdfaa9c 100644 --- a/client/src/context/providers/RepositoriesContextProvider.tsx +++ b/client/src/context/providers/RepositoriesContextProvider.tsx @@ -41,23 +41,25 @@ const RepositoriesContextProvider = ({ const data = JSON.parse(ev.data); console.log('data', data); if (data.ev?.status_change === SyncStatus.Done) { - toast(t('Repository indexed'), { - id: `${data.ref}-indexed`, - description: ( - - repoName has - finished indexing. You can use it in your projects now. - - ), - icon: , - unstyled: true, - }); + if (!data.ev?.rsync) { + toast(t('Repository indexed'), { + id: `${data.ref}-indexed`, + description: ( + + repoName has + finished indexing. You can use it in your projects now. + + ), + icon: , + unstyled: true, + }); + } if (project?.repos.find((r) => r.repo.ref === data.ref)) { refreshCurrentProjectRepos(); }