diff --git a/packages/bruno-app/src/components/RequestTabs/RequestTab/SpecialTab.js b/packages/bruno-app/src/components/RequestTabs/RequestTab/SpecialTab.js index 1cbb0aa05..b895c10fe 100644 --- a/packages/bruno-app/src/components/RequestTabs/RequestTab/SpecialTab.js +++ b/packages/bruno-app/src/components/RequestTabs/RequestTab/SpecialTab.js @@ -2,15 +2,15 @@ import React from 'react'; import CloseTabIcon from './CloseTabIcon'; import { IconVariable, IconSettings, IconRun, IconFolder, IconShieldLock } from '@tabler/icons'; -const SpecialTab = ({ handleCloseClick, type, tabName }) => { +const SpecialTab = ({ handleCloseClick, type, tabName, handleDoubleClick }) => { const getTabInfo = (type, tabName) => { switch (type) { case 'collection-settings': { return ( - <> +
Collection - +
); } case 'collection-overview': { @@ -31,7 +31,7 @@ const SpecialTab = ({ handleCloseClick, type, tabName }) => { } case 'folder-settings': { return ( -
+
{tabName || 'Folder'}
diff --git a/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js b/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js index 2d74a4290..562fc319f 100644 --- a/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js +++ b/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js @@ -1,6 +1,6 @@ import React, { useState, useRef, Fragment } from 'react'; import get from 'lodash/get'; -import { closeTabs } from 'providers/ReduxStore/slices/tabs'; +import { closeTabs, makeTabPermanent } from 'providers/ReduxStore/slices/tabs'; import { saveRequest } from 'providers/ReduxStore/slices/collections/actions'; import { deleteRequestDraft } from 'providers/ReduxStore/slices/collections'; import { useTheme } from 'providers/Theme'; @@ -73,13 +73,13 @@ const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUi if (['collection-settings', 'collection-overview', 'folder-settings', 'variables', 'collection-runner', 'security-settings'].includes(tab.type)) { return ( {tab.type === 'folder-settings' ? ( - + dispatch(makeTabPermanent({ uid: tab.uid }))} type={tab.type} tabName={folder?.name} /> ) : ( - + dispatch(makeTabPermanent({ uid: tab.uid }))} type={tab.type} /> )} ); @@ -144,8 +144,9 @@ const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUi /> )}
dispatch(makeTabPermanent({ uid: tab.uid }))} onMouseUp={(e) => { if (!item.draft) return handleMouseUp(e); diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js index 2bfece171..3da23bcf5 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/CollectionItem/index.js @@ -5,7 +5,7 @@ import classnames from 'classnames'; import { useDrag, useDrop } from 'react-dnd'; import { IconChevronRight, IconDots } from '@tabler/icons'; import { useSelector, useDispatch } from 'react-redux'; -import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs'; +import { addTab, focusTab, makeTabPermanent } from 'providers/ReduxStore/slices/tabs'; import { moveItem, showInFolder, sendRequest } from 'providers/ReduxStore/slices/collections/actions'; import { collectionFolderClicked } from 'providers/ReduxStore/slices/collections'; import Dropdown from 'components/Dropdown'; @@ -23,7 +23,9 @@ import { hideHomePage } from 'providers/ReduxStore/slices/app'; import toast from 'react-hot-toast'; import StyledWrapper from './StyledWrapper'; import NetworkError from 'components/ResponsePane/NetworkError/index'; -import CollectionItemIcon from './CollectionItemIcon/index'; +import { findItemInCollection } from 'utils/collections'; +import CollectionItemIcon from './CollectionItemIcon'; +import { scrollToTheActiveTab } from 'utils/tabs'; const CollectionItem = ({ item, collection, searchText }) => { const tabs = useSelector((state) => state.tabs.tabs); @@ -83,13 +85,6 @@ const CollectionItem = ({ item, collection, searchText }) => { 'item-hovered': isOver }); - const scrollToTheActiveTab = () => { - const activeTab = document.querySelector('.request-tab.active'); - if (activeTab) { - activeTab.scrollIntoView({ behavior: 'smooth', block: 'start' }); - } - }; - const handleRun = async () => { dispatch(sendRequest(item, collection.uid)).catch((err) => toast.custom((t) => toast.dismiss(t.id)} />, { @@ -99,10 +94,13 @@ const CollectionItem = ({ item, collection, searchText }) => { }; const handleClick = (event) => { + if (event.detail != 1) return; //scroll to the active tab setTimeout(scrollToTheActiveTab, 50); - - if (isItemARequest(item)) { + + const isRequest = isItemARequest(item); + + if (isRequest) { dispatch(hideHomePage()); if (itemIsOpenedInTabs(item, tabs)) { dispatch( @@ -112,20 +110,21 @@ const CollectionItem = ({ item, collection, searchText }) => { ); return; } + dispatch( addTab({ uid: item.uid, collectionUid: collection.uid, - requestPaneTab: getDefaultRequestPaneTab(item) + requestPaneTab: getDefaultRequestPaneTab(item), + type: 'request', }) ); - return; - } + } else { dispatch( addTab({ uid: item.uid, collectionUid: collection.uid, - type: 'folder-settings' + type: 'folder-settings', }) ); dispatch( @@ -134,9 +133,12 @@ const CollectionItem = ({ item, collection, searchText }) => { collectionUid: collection.uid }) ); + } }; - const handleFolderCollapse = () => { + const handleFolderCollapse = (e) => { + e.stopPropagation(); + e.preventDefault(); dispatch( collectionFolderClicked({ itemUid: item.uid, @@ -156,10 +158,6 @@ const CollectionItem = ({ item, collection, searchText }) => { } }; - const handleDoubleClick = (event) => { - setRenameItemModalOpen(true); - }; - let indents = range(item.depth); const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); const isFolder = isItemAFolder(item); @@ -180,6 +178,10 @@ const CollectionItem = ({ item, collection, searchText }) => { } } + const handleDoubleClick = (event) => { + dispatch(makeTabPermanent({ uid: item.uid })) + }; + // we need to sort request items by seq property const sortRequestItems = (items = []) => { return items.sort((a, b) => a.seq - b.seq); diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js index 1b16f4eea..f8e4484bc 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js @@ -7,8 +7,8 @@ import { IconChevronRight, IconDots, IconLoader2 } from '@tabler/icons'; import Dropdown from 'components/Dropdown'; import { collapseCollection } from 'providers/ReduxStore/slices/collections'; import { mountCollection, moveItemToRootOfCollection } from 'providers/ReduxStore/slices/collections/actions'; -import { useDispatch } from 'react-redux'; -import { addTab } from 'providers/ReduxStore/slices/tabs'; +import { useDispatch, useSelector } from 'react-redux'; +import { addTab, makeTabPermanent } from 'providers/ReduxStore/slices/tabs'; import NewRequest from 'components/Sidebar/NewRequest'; import NewFolder from 'components/Sidebar/NewFolder'; import CollectionItem from './CollectionItem'; @@ -20,7 +20,8 @@ import { isItemAFolder, isItemARequest } from 'utils/collections'; import RenameCollection from './RenameCollection'; import StyledWrapper from './StyledWrapper'; import CloneCollection from './CloneCollection'; -import { areItemsLoading } from 'utils/collections'; +import { areItemsLoading, findItemInCollection } from 'utils/collections'; +import { scrollToTheActiveTab } from 'utils/tabs'; const Collection = ({ collection, searchText }) => { const [showNewFolderModal, setShowNewFolderModal] = useState(false); @@ -29,6 +30,7 @@ const Collection = ({ collection, searchText }) => { const [showCloneCollectionModalOpen, setShowCloneCollectionModalOpen] = useState(false); const [showExportCollectionModal, setShowExportCollectionModal] = useState(false); const [showRemoveCollectionModal, setShowRemoveCollectionModal] = useState(false); + const tabs = useSelector((state) => state.tabs.tabs); const dispatch = useDispatch(); const isLoading = areItemsLoading(collection); @@ -60,9 +62,11 @@ const Collection = ({ collection, searchText }) => { }); const handleClick = (event) => { + if (event.detail != 1) return; // Check if the click came from the chevron icon const isChevronClick = event.target.closest('svg')?.classList.contains('chevron-icon'); - + setTimeout(scrollToTheActiveTab, 50); + if (collection.mountStatus === 'unmounted') { dispatch(mountCollection({ collectionUid: collection.uid, @@ -70,20 +74,30 @@ const Collection = ({ collection, searchText }) => { brunoConfig: collection.brunoConfig })); } + dispatch(collapseCollection(collection.uid)); - - // Only open collection settings if not clicking the chevron + if(!isChevronClick) { dispatch( addTab({ - uid: uuid(), + uid: collection.uid, collectionUid: collection.uid, - type: 'collection-settings' + type: 'collection-settings', }) ); } }; + const handleDoubleClick = (event) => { + dispatch(makeTabPermanent({ uid: collection.uid })) + }; + + const handleCollectionCollapse = (e) => { + e.stopPropagation(); + e.preventDefault(); + dispatch(collapseCollection(collection.uid)); + } + const handleRightClick = (event) => { const _menuDropdown = menuDropdownTippyRef.current; if (_menuDropdown) { @@ -158,6 +172,7 @@ const Collection = ({ collection, searchText }) => {
{ strokeWidth={2} className={`chevron-icon ${iconClassName}`} style={{ width: 16, minWidth: 16, color: 'rgb(160 160 160)' }} + onClick={handleCollectionCollapse} />