From eae2b36f355e1ba27752f6cea1747f6d47943016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Munsch?= Date: Mon, 29 Sep 2025 12:18:55 +0200 Subject: [PATCH] feat: add RemoveCollections component in order to close multiple projects at once, Closes #5460 --- .../Collections/CollectionsBadge/index.js | 23 ++++-- .../Collections/RemoveCollections/index.js | 73 +++++++++++++++++++ 2 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 packages/bruno-app/src/components/Sidebar/Collections/RemoveCollections/index.js diff --git a/packages/bruno-app/src/components/Sidebar/Collections/CollectionsBadge/index.js b/packages/bruno-app/src/components/Sidebar/Collections/CollectionsBadge/index.js index 8790170b3..09cb7f9e4 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/CollectionsBadge/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/CollectionsBadge/index.js @@ -1,3 +1,5 @@ +import { useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; import { IconArrowsSort, IconFolders, @@ -6,7 +8,7 @@ import { IconX, } from '@tabler/icons'; import { sortCollections } from 'providers/ReduxStore/slices/collections/index'; -import { useDispatch, useSelector } from 'react-redux'; +import RemoveCollections from '../RemoveCollections/index'; const CollectionsBadge = () => { const dispatch = useDispatch(); @@ -37,6 +39,14 @@ const CollectionsBadge = () => { sortIcon = ; } + const [collectionsToClose, setCollectionsToClose] = useState([]); + const addAllCollectionsToClose = () => { + setCollectionsToClose(collections.map(c => c.uid)); + }; + const emptyCollections = () => { + setCollectionsToClose([]); + }; + return (
@@ -48,20 +58,19 @@ const CollectionsBadge = () => {
{collections.length >= 1 && (
- - + {collectionsToClose.length > 0 && ( + + )}
)}
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/RemoveCollections/index.js b/packages/bruno-app/src/components/Sidebar/Collections/RemoveCollections/index.js new file mode 100644 index 000000000..c659eaeef --- /dev/null +++ b/packages/bruno-app/src/components/Sidebar/Collections/RemoveCollections/index.js @@ -0,0 +1,73 @@ +import React from 'react'; +import toast from 'react-hot-toast'; +import { useDispatch, useSelector } from 'react-redux'; +import PropTypes from 'prop-types'; +import { IconFiles } from '@tabler/icons'; +import Modal from 'components/Modal'; +import { removeCollection } from 'providers/ReduxStore/slices/collections/actions'; +import { findCollectionByUid } from 'utils/collections/index'; + +const RemoveCollections = ({ collectionUids, onClose }) => { + const dispatch = useDispatch(); + const allCollections = useSelector(state => state.collections.collections || []); + + const selectedCollections = collectionUids + .map(uid => findCollectionByUid(allCollections, uid)) + .filter(Boolean); + + const collectionsNames = selectedCollections.map(c => c.name).join(', '); + const collectionsPathnames = selectedCollections.map(c => c.pathname).join(', '); + + const onConfirm = () => { + const removalPromises = selectedCollections.map(collection => { + return dispatch(removeCollection(collection.uid)); + }); + + Promise.all(removalPromises) + .then(() => { + toast.success('Collections are closed'); + }) + .catch(() => { + toast.error('An error occurred while closing collections'); + }) + .finally(() => { + if (onClose) onClose(); + }); + }; + + const getConfirmationText = () => { + if (collectionUids.length > 1) { + return `Are you sure you want to close all ${collectionUids.length} collections in Bruno?`; + } + return ( + + Are you sure you want to close the collection + {' '} + {collectionsNames} + {' '} + in Bruno? + + ); + }; + + return ( + +
+ + {collectionsNames} +
+
{collectionsPathnames}
+
{getConfirmationText()}
+
+ It will still be available in the file system at the above locations and can be re-opened later. +
+
+ ); +}; + +RemoveCollections.propTypes = { + collectionUids: PropTypes.arrayOf(PropTypes.string).isRequired, + onClose: PropTypes.func, +}; + +export default RemoveCollections;