import React, { useState, useRef, Fragment } from 'react'; import get from 'lodash/get'; 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'; import { useDispatch } from 'react-redux'; import darkTheme from 'themes/dark'; import lightTheme from 'themes/light'; import { findItemInCollection } from 'utils/collections'; 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'; import CloseTabIcon from './CloseTabIcon'; import DraftTabIcon from './DraftTabIcon'; import { flattenItems } from 'utils/collections/index'; const RequestTab = ({ tab, collection, tabIndex, collectionRequestTabs, folderUid }) => { const dispatch = useDispatch(); const { storedTheme } = useTheme(); const theme = storedTheme === 'dark' ? darkTheme : lightTheme; const [showConfirmClose, setShowConfirmClose] = useState(false); const dropdownTippyRef = useRef(); const onDropdownCreate = (ref) => (dropdownTippyRef.current = ref); const handleCloseClick = (event) => { event.stopPropagation(); event.preventDefault(); dispatch( closeTabs({ tabUids: [tab.uid] }) ); }; 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.preventDefault(); e.stopPropagation(); // Close the tab dispatch( closeTabs({ tabUids: [tab.uid] }) ); } }; const getMethodColor = (method = '') => { return theme.request.methods[method.toLocaleLowerCase()]; }; const folder = folderUid ? findItemInCollection(collection, folderUid) : null; if (['collection-settings', 'collection-overview', 'folder-settings', 'variables', 'collection-runner', 'security-settings'].includes(tab.type)) { return ( {tab.type === 'folder-settings' && !folder ? ( ) : tab.type === 'folder-settings' ? ( dispatch(makeTabPermanent({ uid: tab.uid }))} type={tab.type} tabName={folder?.name} /> ) : ( dispatch(makeTabPermanent({ uid: tab.uid }))} type={tab.type} /> )} ); } const item = findItemInCollection(collection, tab.uid); if (!item) { return ( { if (e.button === 1) { e.preventDefault(); e.stopPropagation(); dispatch(closeTabs({ tabUids: [tab.uid] })); } }} > ); } const isGrpc = item.type === 'grpc-request'; const method = item.draft ? get(item, 'draft.request.method') : get(item, 'request.method'); return ( {showConfirmClose && ( setShowConfirmClose(false)} onCloseWithoutSave={() => { dispatch( deleteRequestDraft({ itemUid: item.uid, collectionUid: collection.uid }) ); dispatch( closeTabs({ tabUids: [tab.uid] }) ); setShowConfirmClose(false); }} onSaveAndClose={() => { dispatch(saveRequest(item.uid, collection.uid)) .then(() => { dispatch( closeTabs({ tabUids: [tab.uid] }) ); setShowConfirmClose(false); }) .catch((err) => { console.log('err', err); }); }} /> )}
dispatch(makeTabPermanent({ uid: tab.uid }))} onMouseUp={(e) => { if (!item.draft) return handleMouseUp(e); if (e.button === 1) { e.stopPropagation(); e.preventDefault(); setShowConfirmClose(true); } }} > {isGrpc ? 'gRPC' : method} {item.name}
{ if (!item.draft) return handleCloseClick(e); e.stopPropagation(); e.preventDefault(); setShowConfirmClose(true); }} > {!item.draft ? ( ) : ( )}
); }; 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 items = flattenItems(collection?.items); const savedTabs = 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;