mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-08 22:45:25 +00:00
Redesign dropdowns (#6235)
* redesign dropdowns * fix: colors --------- Co-authored-by: Anoop M D <anoop@usebruno.com>
This commit is contained in:
@@ -4,7 +4,22 @@ import range from 'lodash/range';
|
||||
import filter from 'lodash/filter';
|
||||
import classnames from 'classnames';
|
||||
import { useDrag, useDrop } from 'react-dnd';
|
||||
import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||
import {
|
||||
IconChevronRight,
|
||||
IconDots,
|
||||
IconFilePlus,
|
||||
IconFolderPlus,
|
||||
IconPlayerPlay,
|
||||
IconEdit,
|
||||
IconCopy,
|
||||
IconClipboard,
|
||||
IconCode,
|
||||
IconPhoto,
|
||||
IconFolder,
|
||||
IconTrash,
|
||||
IconSettings,
|
||||
IconInfoCircle
|
||||
} from '@tabler/icons';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
import { addTab, focusTab, makeTabPermanent } from 'providers/ReduxStore/slices/tabs';
|
||||
import { handleCollectionItemDrop, sendRequest, showInFolder, pasteItem, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
|
||||
@@ -489,6 +504,18 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
</div>
|
||||
<div className="menu-icon pr-2">
|
||||
<Dropdown onCreate={onDropdownCreate} icon={<MenuIcon />} placement="bottom-start">
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
dropdownTippyRef.current.hide();
|
||||
setItemInfoModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconInfoCircle size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Info
|
||||
</div>
|
||||
{isFolder && (
|
||||
<>
|
||||
<div
|
||||
@@ -498,6 +525,9 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
setNewRequestModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconFilePlus size={16} strokeWidth={2} />
|
||||
</span>
|
||||
New Request
|
||||
</div>
|
||||
<div
|
||||
@@ -507,6 +537,9 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
setNewFolderModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconFolderPlus size={16} strokeWidth={2} />
|
||||
</span>
|
||||
New Folder
|
||||
</div>
|
||||
<div
|
||||
@@ -516,19 +549,13 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
setRunCollectionModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconPlayerPlay size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Run
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
dropdownTippyRef.current.hide();
|
||||
setRenameItemModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Rename
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
@@ -536,6 +563,9 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
setCloneItemModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconCopy size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Clone
|
||||
</div>
|
||||
{!isFolder && (
|
||||
@@ -543,6 +573,9 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
className="dropdown-item"
|
||||
onClick={handleCopyRequest}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconCopy size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Copy
|
||||
</div>
|
||||
)}
|
||||
@@ -551,21 +584,36 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
className="dropdown-item"
|
||||
onClick={handlePasteRequest}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconClipboard size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Paste
|
||||
</div>
|
||||
)}
|
||||
{!isFolder && (
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
dropdownTippyRef.current.hide();
|
||||
handleClick(null);
|
||||
handleRun();
|
||||
}}
|
||||
>
|
||||
Run
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
dropdownTippyRef.current.hide();
|
||||
setRenameItemModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconEdit size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Rename
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
dropdownTippyRef.current.hide();
|
||||
handleShowInFolder();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconFolder size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Show in Folder
|
||||
</div>
|
||||
{!isFolder && (item.type === 'http-request' || item.type === 'graphql-request') && (
|
||||
<div
|
||||
className="dropdown-item"
|
||||
@@ -573,6 +621,9 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
handleGenerateCode(e);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconCode size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Generate Code
|
||||
</div>
|
||||
)}
|
||||
@@ -584,27 +635,13 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
setCreateExampleModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconPhoto size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Create Example
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
dropdownTippyRef.current.hide();
|
||||
handleShowInFolder();
|
||||
}}
|
||||
>
|
||||
Show in Folder
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item delete-item"
|
||||
onClick={(e) => {
|
||||
dropdownTippyRef.current.hide();
|
||||
setDeleteItemModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Delete
|
||||
</div>
|
||||
<div className="dropdown-separator"></div>
|
||||
{isFolder && (
|
||||
<div
|
||||
className="dropdown-item"
|
||||
@@ -613,17 +650,23 @@ const CollectionItem = ({ item, collectionUid, collectionPathname, searchText })
|
||||
viewFolderSettings();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconSettings size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Settings
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="dropdown-item item-info"
|
||||
className="dropdown-item delete-item"
|
||||
onClick={(e) => {
|
||||
dropdownTippyRef.current.hide();
|
||||
setItemInfoModalOpen(true);
|
||||
setDeleteItemModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Info
|
||||
<span className="dropdown-icon">
|
||||
<IconTrash size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Delete
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,21 @@ import classnames from 'classnames';
|
||||
import { uuid } from 'utils/common';
|
||||
import filter from 'lodash/filter';
|
||||
import { useDrop, useDrag } from 'react-dnd';
|
||||
import { IconChevronRight, IconDots, IconLoader2 } from '@tabler/icons';
|
||||
import {
|
||||
IconChevronRight,
|
||||
IconDots,
|
||||
IconLoader2,
|
||||
IconFilePlus,
|
||||
IconFolderPlus,
|
||||
IconCopy,
|
||||
IconClipboard,
|
||||
IconPlayerPlay,
|
||||
IconEdit,
|
||||
IconShare,
|
||||
IconFoldDown,
|
||||
IconX,
|
||||
IconSettings
|
||||
} from '@tabler/icons';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import { toggleCollection, collapseFullCollection } from 'providers/ReduxStore/slices/collections';
|
||||
import { mountCollection, moveCollectionAndPersist, handleCollectionItemDrop, pasteItem } from 'providers/ReduxStore/slices/collections/actions';
|
||||
@@ -277,6 +291,9 @@ const Collection = ({ collection, searchText }) => {
|
||||
setShowNewRequestModal(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconFilePlus size={16} strokeWidth={2} />
|
||||
</span>
|
||||
New Request
|
||||
</div>
|
||||
<div
|
||||
@@ -286,8 +303,24 @@ const Collection = ({ collection, searchText }) => {
|
||||
setShowNewFolderModal(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconFolderPlus size={16} strokeWidth={2} />
|
||||
</span>
|
||||
New Folder
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
ensureCollectionIsMounted();
|
||||
handleRun();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconPlayerPlay size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Run
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
data-testid="clone-collection"
|
||||
@@ -296,6 +329,9 @@ const Collection = ({ collection, searchText }) => {
|
||||
setShowCloneCollectionModalOpen(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconCopy size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Clone
|
||||
</div>
|
||||
{hasCopiedItems && (
|
||||
@@ -303,19 +339,12 @@ const Collection = ({ collection, searchText }) => {
|
||||
className="dropdown-item"
|
||||
onClick={handlePasteRequest}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconClipboard size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Paste
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
ensureCollectionIsMounted();
|
||||
handleRun();
|
||||
}}
|
||||
>
|
||||
Run
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
@@ -323,6 +352,9 @@ const Collection = ({ collection, searchText }) => {
|
||||
setShowRenameCollectionModal(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconEdit size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Rename
|
||||
</div>
|
||||
<div
|
||||
@@ -333,6 +365,9 @@ const Collection = ({ collection, searchText }) => {
|
||||
setShowShareCollectionModal(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconShare size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Share
|
||||
</div>
|
||||
<div
|
||||
@@ -342,8 +377,24 @@ const Collection = ({ collection, searchText }) => {
|
||||
handleCollapseFullCollection();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconFoldDown size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Collapse
|
||||
</div>
|
||||
<div className="dropdown-separator"></div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
viewCollectionSettings();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconSettings size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Settings
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
@@ -351,17 +402,11 @@ const Collection = ({ collection, searchText }) => {
|
||||
setShowRemoveCollectionModal(true);
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconX size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Close
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(_e) => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
viewCollectionSettings();
|
||||
}}
|
||||
>
|
||||
Settings
|
||||
</div>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,7 +5,7 @@ import CreateCollection from '../CreateCollection';
|
||||
import ImportCollection from 'components/Sidebar/ImportCollection';
|
||||
import ImportCollectionLocation from 'components/Sidebar/ImportCollectionLocation';
|
||||
|
||||
import { IconDots } from '@tabler/icons';
|
||||
import { IconDots, IconPlus, IconFolder, IconDownload, IconDeviceDesktop } from '@tabler/icons';
|
||||
import { useState, forwardRef, useRef } from 'react';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { showHomePage } from 'providers/ReduxStore/slices/app';
|
||||
@@ -90,6 +90,7 @@ const TitleBar = () => {
|
||||
</button>
|
||||
<div className="collection-dropdown flex flex-grow items-center justify-end">
|
||||
<Dropdown onCreate={onMenuDropdownCreate} icon={<MenuIcon />} placement="bottom-start">
|
||||
<div className="label-item">Collections</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
@@ -97,6 +98,9 @@ const TitleBar = () => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconPlus size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Create Collection
|
||||
</div>
|
||||
<div
|
||||
@@ -106,7 +110,10 @@ const TitleBar = () => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
}}
|
||||
>
|
||||
Open Collection
|
||||
<span className="dropdown-icon">
|
||||
<IconFolder size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Open
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
@@ -115,8 +122,37 @@ const TitleBar = () => {
|
||||
setImportCollectionModalOpen(true);
|
||||
}}
|
||||
>
|
||||
Import Collection
|
||||
<span className="dropdown-icon">
|
||||
<IconDownload size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Import
|
||||
</div>
|
||||
<div className="label-item">API Specs</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
setCreateCollectionModalOpen(true);
|
||||
menuDropdownTippyRef.current.hide();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconPlus size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Create Collection
|
||||
</div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
handleOpenCollection();
|
||||
menuDropdownTippyRef.current.hide();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconFolder size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Open
|
||||
</div>
|
||||
<div className="dropdown-separator"></div>
|
||||
<div
|
||||
className="dropdown-item"
|
||||
onClick={(e) => {
|
||||
@@ -124,6 +160,9 @@ const TitleBar = () => {
|
||||
openDevTools();
|
||||
}}
|
||||
>
|
||||
<span className="dropdown-icon">
|
||||
<IconDeviceDesktop size={16} strokeWidth={2} />
|
||||
</span>
|
||||
Devtools
|
||||
</div>
|
||||
</Dropdown>
|
||||
|
||||
Reference in New Issue
Block a user