diff --git a/packages/bruno-app/src/components/Dropdown/StyledWrapper.js b/packages/bruno-app/src/components/Dropdown/StyledWrapper.js
index 6ad94e289..7af8b9081 100644
--- a/packages/bruno-app/src/components/Dropdown/StyledWrapper.js
+++ b/packages/bruno-app/src/components/Dropdown/StyledWrapper.js
@@ -40,10 +40,15 @@ const Wrapper = styled.div`
color: ${(props) => props.theme.dropdown.iconColor};
}
- &:hover {
+ &:hover:not(:disabled) {
background-color: ${(props) => props.theme.dropdown.hoverBg};
}
+ &:disabled {
+ cursor: not-allowed;
+ color: gray;
+ }
+
&.border-top {
border-top: solid 1px ${(props) => props.theme.dropdown.separator};
}
diff --git a/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js b/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js
index 680782169..8b9bb0c35 100644
--- a/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js
+++ b/packages/bruno-app/src/components/RequestTabs/RequestTab/index.js
@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState, useRef, Fragment } from 'react';
import get from 'lodash/get';
import { closeTabs } from 'providers/ReduxStore/slices/tabs';
import { saveRequest } from 'providers/ReduxStore/slices/collections/actions';
@@ -12,12 +12,18 @@ import ConfirmRequestClose from './ConfirmRequestClose';
import RequestTabNotFound from './RequestTabNotFound';
import SpecialTab from './SpecialTab';
import StyledWrapper from './StyledWrapper';
+import Dropdown from 'components/Dropdown';
+import CloneCollectionItem from 'components/Sidebar/Collections/Collection/CollectionItem/CloneCollectionItem/index';
+import NewRequest from 'components/Sidebar/NewRequest/index';
-const RequestTab = ({ tab, collection, folderUid }) => {
+const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUid }) => {
const dispatch = useDispatch();
const { storedTheme } = useTheme();
const [showConfirmClose, setShowConfirmClose] = useState(false);
+ const dropdownTippyRef = useRef();
+ const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref);
+
const handleCloseClick = (event) => {
event.stopPropagation();
event.preventDefault();
@@ -28,6 +34,19 @@ const RequestTab = ({ tab, collection, folderUid }) => {
);
};
+ const handleRightClick = (_event) => {
+ const menuDropdown = dropdownTippyRef.current;
+ if (!menuDropdown) {
+ return;
+ }
+
+ if (menuDropdown.state.isShown) {
+ menuDropdown.hide();
+ } else {
+ menuDropdown.show();
+ }
+ };
+
const handleMouseUp = (e) => {
if (e.button === 1) {
e.stopPropagation();
@@ -143,6 +162,7 @@ const RequestTab = ({ tab, collection, folderUid }) => {
)}
{
if (!item.draft) return handleMouseUp(e);
@@ -159,6 +179,15 @@ const RequestTab = ({ tab, collection, folderUid }) => {
{item.name}
+
{
);
};
+function RequestTabMenu({ onDropdownCreate, collectionRequestTabs, tabIndex, collection, dropdownTippyRef, dispatch }) {
+ const [showCloneRequestModal, setShowCloneRequestModal] = useState(false);
+ const [showAddNewRequestModal, setShowAddNewRequestModal] = useState(false);
+
+ const totalTabs = collectionRequestTabs.length || 0;
+ const currentTabUid = collectionRequestTabs[tabIndex]?.uid;
+ const currentTabItem = findItemInCollection(collection, currentTabUid);
+
+ const hasLeftTabs = tabIndex !== 0;
+ const hasRightTabs = totalTabs > tabIndex + 1;
+ const hasOtherTabs = totalTabs > 1;
+
+ async function handleCloseTab(event, tabUid) {
+ event.stopPropagation();
+ dropdownTippyRef.current.hide();
+
+ if (!tabUid) {
+ return;
+ }
+
+ try {
+ const item = findItemInCollection(collection, tabUid);
+ // silently save unsaved changes before closing the tab
+ if (item.draft) {
+ await dispatch(saveRequest(item.uid, collection.uid, true));
+ }
+
+ dispatch(closeTabs({ tabUids: [tabUid] }));
+ } catch (err) {}
+ }
+
+ function handleCloseOtherTabs(event) {
+ dropdownTippyRef.current.hide();
+
+ const otherTabs = collectionRequestTabs.filter((_, index) => index !== tabIndex);
+ otherTabs.forEach((tab) => handleCloseTab(event, tab.uid));
+ }
+
+ function handleCloseTabsToTheLeft(event) {
+ dropdownTippyRef.current.hide();
+
+ const leftTabs = collectionRequestTabs.filter((_, index) => index < tabIndex);
+ leftTabs.forEach((tab) => handleCloseTab(event, tab.uid));
+ }
+
+ function handleCloseTabsToTheRight(event) {
+ dropdownTippyRef.current.hide();
+
+ const rightTabs = collectionRequestTabs.filter((_, index) => index > tabIndex);
+ rightTabs.forEach((tab) => handleCloseTab(event, tab.uid));
+ }
+
+ function handleCloseSavedTabs(event) {
+ event.stopPropagation();
+
+ const savedTabs = collection.items.filter((item) => !item.draft);
+ const savedTabIds = savedTabs.map((item) => item.uid) || [];
+ dispatch(closeTabs({ tabUids: savedTabIds }));
+ }
+
+ function handleCloseAllTabs(event) {
+ collectionRequestTabs.forEach((tab) => handleCloseTab(event, tab.uid));
+ }
+
+ return (
+
+ {showAddNewRequestModal && (
+ setShowAddNewRequestModal(false)} />
+ )}
+
+ {showCloneRequestModal && (
+ setShowCloneRequestModal(false)}
+ />
+ )}
+
+ } placement="bottom-start">
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
export default RequestTab;
diff --git a/packages/bruno-app/src/components/RequestTabs/StyledWrapper.js b/packages/bruno-app/src/components/RequestTabs/StyledWrapper.js
index 26399d975..93829cca9 100644
--- a/packages/bruno-app/src/components/RequestTabs/StyledWrapper.js
+++ b/packages/bruno-app/src/components/RequestTabs/StyledWrapper.js
@@ -7,7 +7,6 @@ const Wrapper = styled.div`
padding: 0;
margin: 0;
display: flex;
- position: relative;
overflow: scroll;
&::-webkit-scrollbar {
diff --git a/packages/bruno-app/src/components/RequestTabs/index.js b/packages/bruno-app/src/components/RequestTabs/index.js
index fbafb55cf..d0cd0b459 100644
--- a/packages/bruno-app/src/components/RequestTabs/index.js
+++ b/packages/bruno-app/src/components/RequestTabs/index.js
@@ -110,7 +110,14 @@ const RequestTabs = () => {
role="tab"
onClick={() => handleClick(tab)}
>
-
+
);
})