diff --git a/packages/bruno-app/src/components/Modal/StyledWrapper.js b/packages/bruno-app/src/components/Modal/StyledWrapper.js
index d0f894d9..98b0f147 100644
--- a/packages/bruno-app/src/components/Modal/StyledWrapper.js
+++ b/packages/bruno-app/src/components/Modal/StyledWrapper.js
@@ -40,18 +40,22 @@ const Wrapper = styled.div`
&.modal-sm {
min-width: 300px;
+ max-width: 500px;
}
&.modal-md {
min-width: 500px;
+ max-width: 800px;
}
&.modal-lg {
min-width: 800px;
+ max-width: 1140px;
}
&.modal-xl {
min-width: 1140px;
+ max-width: calc(100% - 30px);
}
animation: fade-and-slide-in-from-top .50s forwards cubic-bezier(.19,1,.22,1);
diff --git a/packages/bruno-app/src/components/Modal/index.js b/packages/bruno-app/src/components/Modal/index.js
index 486f98e9..0d5badc8 100644
--- a/packages/bruno-app/src/components/Modal/index.js
+++ b/packages/bruno-app/src/components/Modal/index.js
@@ -47,7 +47,8 @@ const Modal = ({
handleConfirm,
children,
confirmDisabled,
- hideCancel
+ hideCancel,
+ hideFooter
}) => {
const [isClosing, setIsClosing] = useState(false);
const escFunction = (event) => {
@@ -60,7 +61,7 @@ const Modal = ({
const closeModal = () => {
setIsClosing(true);
setTimeout(() => handleCancel(), 500);
- }
+ };
useEffect(() => {
document.addEventListener('keydown', escFunction, false);
@@ -79,15 +80,17 @@ const Modal = ({
closeModal()} />
{children}
- closeModal()}
handleSubmit={handleConfirm}
confirmDisabled={confirmDisabled}
hideCancel={hideCancel}
- />
+ /> : null}
+
+ {/* Clicking on backdrop closes the modal */}
closeModal()} />
);
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/Collection/RemoveCollectionFromWorkspace/index.js b/packages/bruno-app/src/components/Sidebar/Collections/Collection/RemoveCollectionFromWorkspace/index.js
new file mode 100644
index 00000000..94064dfa
--- /dev/null
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/RemoveCollectionFromWorkspace/index.js
@@ -0,0 +1,37 @@
+import React from 'react';
+import toast from 'react-hot-toast';
+import Modal from 'components/Modal';
+import { useSelector, useDispatch } from 'react-redux';
+import { recursivelyGetAllItemUids } from 'utils/collections';
+import { removeCollectionFromWorkspace } from 'providers/ReduxStore/slices/workspaces/actions';
+import { closeTabs } from 'providers/ReduxStore/slices/tabs';
+
+const RemoveCollectionFromWorkspace = ({onClose, collection}) => {
+ const dispatch = useDispatch();
+ const { activeWorkspaceUid } = useSelector((state) => state.workspaces);
+
+ const onConfirm = () =>{
+ dispatch(removeCollectionFromWorkspace(activeWorkspaceUid, collection.uid))
+ .then(() => {
+ dispatch(closeTabs({
+ tabUids: recursivelyGetAllItemUids(collection.items)
+ }));
+ toast.success("Collection removed from workspace");
+ })
+ .catch((err) => console.log(err) && toast.error("An error occured while removing the collection"));
+ };
+
+ return (
+
+ Are you sure you want to remove the collection {collection.name} from this workspace?
+
+ );
+};
+
+export default RemoveCollectionFromWorkspace;
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 22fe299e..bc3f48c3 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/Collection/index.js
@@ -8,6 +8,7 @@ import { useDispatch } from 'react-redux';
import NewRequest from 'components/Sidebar/NewRequest';
import NewFolder from 'components/Sidebar/NewFolder';
import CollectionItem from './CollectionItem';
+import RemoveCollectionFromWorkspace from './RemoveCollectionFromWorkspace';
import { doesCollectionHaveItemsMatchingSearchText } from 'utils/collections/search';
import { isItemAFolder, isItemARequest } from 'utils/collections';
@@ -19,6 +20,7 @@ const Collection = ({collection, searchText}) => {
const [showNewFolderModal, setShowNewFolderModal] = useState(false);
const [showNewRequestModal, setShowNewRequestModal] = useState(false);
const [showRenameCollectionModal, setShowRenameCollectionModal] = useState(false);
+ const [showRemoveCollectionFromWSModal, setShowRemoveCollectionFromWSModal] = useState(false);
const [showDeleteCollectionModal, setShowDeleteCollectionModal] = useState(false);
const [collectionIsCollapsed, setCollectionIsCollapsed] = useState(collection.collapsed);
const dispatch = useDispatch();
@@ -63,6 +65,7 @@ const Collection = ({collection, searchText}) => {
{showNewRequestModal &&
setShowNewRequestModal(false)}/>}
{showNewFolderModal && setShowNewFolderModal(false)}/>}
{showRenameCollectionModal && setShowRenameCollectionModal(false)}/>}
+ {showRemoveCollectionFromWSModal && setShowRemoveCollectionFromWSModal(false)}/>}
{showDeleteCollectionModal && setShowDeleteCollectionModal(false)}/>}
@@ -93,6 +96,12 @@ const Collection = ({collection, searchText}) => {
}}>
Rename
+
{
+ menuDropdownTippyRef.current.hide();
+ setShowRemoveCollectionFromWSModal(true);
+ }}>
+ Remove from Workspace
+
{
menuDropdownTippyRef.current.hide();
setShowDeleteCollectionModal(true);
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/CreateOrAddCollection/index.js b/packages/bruno-app/src/components/Sidebar/Collections/CreateOrAddCollection/index.js
new file mode 100644
index 00000000..5e6c8505
--- /dev/null
+++ b/packages/bruno-app/src/components/Sidebar/Collections/CreateOrAddCollection/index.js
@@ -0,0 +1,63 @@
+import React, { useState } from 'react';
+import toast from 'react-hot-toast';
+import { useSelector, useDispatch } from 'react-redux';
+import CreateCollection from 'components/Sidebar/CreateCollection';
+import SelectCollection from 'components/Sidebar/Collections/SelectCollection';
+import { createCollection } from 'providers/ReduxStore/slices/collections/actions';
+import { addCollectionToWorkspace } from 'providers/ReduxStore/slices/workspaces/actions';
+
+const CreateOrAddCollection = () => {
+ const dispatch = useDispatch();
+ const [createCollectionModalOpen, setCreateCollectionModalOpen] = useState(false);
+ const [addCollectionToWSModalOpen, setAddCollectionToWSModalOpen] = useState(false);
+ const { activeWorkspaceUid } = useSelector((state) => state.workspaces);
+
+ const handleCreateCollection = (values) => {
+ setCreateCollectionModalOpen(false);
+ dispatch(createCollection(values.collectionName))
+ .then(() => {
+ toast.success("Collection created");
+ })
+ .catch(() => toast.error("An error occured while creating the collection"));
+ };
+
+ const handleAddCollectionToWorkspace = (collectionUid) => {
+ setAddCollectionToWSModalOpen(false);
+ dispatch(addCollectionToWorkspace(activeWorkspaceUid, collectionUid))
+ .then(() => {
+ toast.success("Collection added to workspace");
+ })
+ .catch(() => toast.error("An error occured while adding collection to workspace"));
+ };
+
+ const CreateLink = () =>
setCreateCollectionModalOpen(true)}>Create;
+ const AddLink = () =>
setAddCollectionToWSModalOpen(true)}>Add;
+
+ return (
+
+ {createCollectionModalOpen ? (
+
setCreateCollectionModalOpen(false)}
+ handleConfirm={handleCreateCollection}
+ />
+ ) : null}
+
+ {addCollectionToWSModalOpen ? (
+ setAddCollectionToWSModalOpen(false)}
+ onSelect={handleAddCollectionToWorkspace}
+ />
+ ): null}
+
+
+
No collections found.
+
+
or
Collection to Workspace.
+
+
+
+ );
+};
+
+export default CreateOrAddCollection;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/StyledWrapper.js b/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/StyledWrapper.js
new file mode 100644
index 00000000..b37adfb1
--- /dev/null
+++ b/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/StyledWrapper.js
@@ -0,0 +1,18 @@
+import styled from 'styled-components';
+
+const StyledWrapper = styled.div`
+ div.collection {
+ padding: 4px 6px;
+ padding-left: 8px;
+ display: flex;
+ align-items: center;
+ border-radius: 3px;
+ cursor: pointer;
+
+ &:hover {
+ background-color: #f4f4f4;
+ }
+ }
+`;
+
+export default StyledWrapper;
\ No newline at end of file
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/index.js b/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/index.js
new file mode 100644
index 00000000..a96c770c
--- /dev/null
+++ b/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/index.js
@@ -0,0 +1,30 @@
+import React from "react";
+import Modal from "components/Modal/index";
+import { IconFiles } from '@tabler/icons';
+import { useSelector } from "react-redux";
+import StyledWrapper from './StyledWrapper';
+
+const SelectCollection = ({onClose, onSelect, title}) => {
+ const { collections } = useSelector((state) => state.collections);
+
+ return (
+
+
+
+
+
+ );
+}
+
+export default SelectCollection;
diff --git a/packages/bruno-app/src/components/Sidebar/Collections/index.js b/packages/bruno-app/src/components/Sidebar/Collections/index.js
index f56672a0..1ad6865c 100644
--- a/packages/bruno-app/src/components/Sidebar/Collections/index.js
+++ b/packages/bruno-app/src/components/Sidebar/Collections/index.js
@@ -1,14 +1,29 @@
-import React, { useEffect, useState } from 'react';
+import React, { useState } from 'react';
import { useSelector } from 'react-redux';
+import find from 'lodash/find';
+import filter from 'lodash/filter';
import Collection from './Collection';
+import CreateOrAddCollection from './CreateOrAddCollection';
const Collections = ({searchText}) => {
- const collections = useSelector((state) => state.collections.collections);
- console.log(collections);
+ const { collections } = useSelector((state) => state.collections);
+ const { workspaces, activeWorkspaceUid } = useSelector((state) => state.workspaces);
+ const activeWorkspace = find(workspaces, w => w.uid === activeWorkspaceUid);
+
+ if(!activeWorkspace) {
+ return null;
+ }
+
+ const { collectionUids } = activeWorkspace;
+ const collectionToDisplay = filter(collections, (c) => collectionUids.includes(c.uid));
+
+ if(!collectionToDisplay || !collectionToDisplay.length) {
+ return
;
+ }
return (
- {collections && collections.length ? collections.map((c) => {
+ {collectionToDisplay && collectionToDisplay.length ? collectionToDisplay.map((c) => {
return
{
- const [modalOpen, setModalOpen] = useState(false);
+ const [createCollectionModalOpen, setCreateCollectionModalOpen] = useState(false);
+ const [addCollectionToWSModalOpen, setAddCollectionToWSModalOpen] = useState(false);
+ const { activeWorkspaceUid } = useSelector((state) => state.workspaces);
const dispatch = useDispatch();
const menuDropdownTippyRef = useRef();
@@ -23,11 +27,10 @@ const TitleBar = () => {
);
});
- const handleCancel = () => setModalOpen(false);
const handleTitleClick = () => dispatch(showHomePage());
- const handleConfirm = (values) => {
- setModalOpen(false);
+ const handleCreateCollection = (values) => {
+ setCreateCollectionModalOpen(false);
dispatch(createCollection(values.collectionName))
.then(() => {
toast.success("Collection created");
@@ -35,14 +38,31 @@ const TitleBar = () => {
.catch(() => toast.error("An error occured while creating the collection"));
};
+ const handleAddCollectionToWorkspace = (collectionUid) => {
+ setAddCollectionToWSModalOpen(false);
+ dispatch(addCollectionToWorkspace(activeWorkspaceUid, collectionUid))
+ .then(() => {
+ toast.success("Collection added to workspace");
+ })
+ .catch(() => toast.error("An error occured while adding collection to workspace"));
+ };
+
return (
- {modalOpen ? (
+ {createCollectionModalOpen ? (
setCreateCollectionModalOpen(false)}
+ handleConfirm={handleCreateCollection}
/>
) : null}
+
+ {addCollectionToWSModalOpen ? (
+ setAddCollectionToWSModalOpen(false)}
+ onSelect={handleAddCollectionToWorkspace}
+ />
+ ): null}
@@ -59,7 +79,7 @@ const TitleBar = () => {
} placement='bottom-start'>
{
menuDropdownTippyRef.current.hide();
- setModalOpen(true);
+ setCreateCollectionModalOpen(true);
}}>
Create Collection
@@ -70,6 +90,7 @@ const TitleBar = () => {
{
menuDropdownTippyRef.current.hide();
+ setAddCollectionToWSModalOpen(true);
}}>
Add Collection to Workspace
diff --git a/packages/bruno-app/src/components/Welcome/index.js b/packages/bruno-app/src/components/Welcome/index.js
index 1c4094bb..1d1526d1 100644
--- a/packages/bruno-app/src/components/Welcome/index.js
+++ b/packages/bruno-app/src/components/Welcome/index.js
@@ -1,4 +1,5 @@
import React, { useState } from 'react';
+import toast from 'react-hot-toast';
import {
IconPlus,
IconUpload,
@@ -9,19 +10,22 @@ import {
IconSpeakerphone,
IconDeviceDesktop
} from '@tabler/icons';
-import { useDispatch } from 'react-redux';
+import { useSelector, useDispatch } from 'react-redux';
import { createCollection } from 'providers/ReduxStore/slices/collections/actions';
+import { addCollectionToWorkspace } from 'providers/ReduxStore/slices/workspaces/actions';
import Bruno from 'components/Bruno';
import CreateCollection from 'components/Sidebar/CreateCollection';
+import SelectCollection from 'components/Sidebar/Collections/SelectCollection';
import StyledWrapper from './StyledWrapper';
const Welcome = () => {
- const [modalOpen, setModalOpen] = useState(false);
const dispatch = useDispatch();
+ const [createCollectionModalOpen, setCreateCollectionModalOpen] = useState(false);
+ const [addCollectionToWSModalOpen, setAddCollectionToWSModalOpen] = useState(false);
+ const { activeWorkspaceUid } = useSelector((state) => state.workspaces);
- const handleCancel = () => setModalOpen(false);
- const handleConfirm = (values) => {
- setModalOpen(false);
+ const handleCreateCollection = (values) => {
+ setCreateCollectionModalOpen(false);
dispatch(createCollection(values.collectionName))
.then(() => {
toast.success("Collection created");
@@ -29,14 +33,32 @@ const Welcome = () => {
.catch(() => toast.error("An error occured while creating the collection"));
};
+ const handleAddCollectionToWorkspace = (collectionUid) => {
+ setAddCollectionToWSModalOpen(false);
+ dispatch(addCollectionToWorkspace(activeWorkspaceUid, collectionUid))
+ .then(() => {
+ toast.success("Collection added to workspace");
+ })
+ .catch(() => toast.error("An error occured while adding collection to workspace"));
+ };
+
return (
- {modalOpen ? (
+ {createCollectionModalOpen ? (
setCreateCollectionModalOpen(false)}
+ handleConfirm={handleCreateCollection}
/>
) : null}
+
+ {addCollectionToWSModalOpen ? (
+ setAddCollectionToWSModalOpen(false)}
+ onSelect={handleAddCollectionToWorkspace}
+ />
+ ): null}
+
@@ -44,12 +66,12 @@ const Welcome = () => {
Opensource API Client.
Collections
-
+
- setModalOpen(true)}>Create Collection
+ setCreateCollectionModalOpen(true)}>Create Collection
- Add Collection to Workspace
+ setAddCollectionToWSModalOpen(true)}>Add Collection to Workspace
Import Collection
@@ -60,9 +82,9 @@ const Welcome = () => {
Local Collections
-
+
- setModalOpen(true)}>Create Collection
+ setCreateCollectionModalOpen(true)}>Create Collection
Open Collection
@@ -70,7 +92,7 @@ const Welcome = () => {
Links
-
+
Chrome Extension
diff --git a/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/index.js b/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/index.js
index 7c23c919..185aba2f 100644
--- a/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/index.js
+++ b/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/index.js
@@ -24,8 +24,7 @@ const WorkspaceConfigurer = ({onClose}) => {
{openAddModal &&
setOpenAddModal(false)}/>}
- )
-
+ );
}
export default WorkspaceConfigurer;
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
index debe0c86..ee04785a 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js
@@ -5,6 +5,7 @@ import {
recursivelyGetAllItemUids,
transformCollectionToSaveToIdb
} from 'utils/collections';
+import { waitForNextTick } from 'utils/common';
import { saveCollectionToIdb, deleteCollectionInIdb } from 'utils/idb';
import {
@@ -13,9 +14,10 @@ import {
deleteCollection as _deleteCollection,
} from './index';
-import { closeTabs } from 'providers/ReduxStore/slices/tabs';
+import { closeTabs, addTab } from 'providers/ReduxStore/slices/tabs';
+import { addCollectionToWorkspace } from 'providers/ReduxStore/slices/workspaces/actions';
-export const createCollection = (collectionName) => (dispatch) => {
+export const createCollection = (collectionName) => (dispatch, getState) => {
const newCollection = {
uid: uuid(),
name: collectionName,
@@ -23,9 +25,40 @@ export const createCollection = (collectionName) => (dispatch) => {
environments: [],
};
+ const requestItem = {
+ uid: uuid(),
+ type: 'http-request',
+ name: 'Untitled',
+ request: {
+ method: 'GET',
+ url: '',
+ headers: [],
+ body: {
+ mode: 'none',
+ json: null,
+ text: null,
+ xml: null,
+ multipartForm: null,
+ formUrlEncoded: null
+ }
+ }
+ };
+
+ newCollection.items.push(requestItem)
+
+ const state = getState();
+ const { activeWorkspaceUid } = state.workspaces;
+
return new Promise((resolve, reject) => {
saveCollectionToIdb(window.__idb, newCollection)
.then(() => dispatch(_createCollection(newCollection)))
+ .then(waitForNextTick)
+ .then(() => dispatch(addCollectionToWorkspace(activeWorkspaceUid, newCollection.uid)))
+ .then(waitForNextTick)
+ .then(() => dispatch(addTab({
+ uid: requestItem.uid,
+ collectionUid: newCollection.uid
+ })))
.then(resolve)
.catch(reject);
});
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
index 6f4985fa..6e65dbcb 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
@@ -693,10 +693,7 @@ export const newHttpRequest = (params) => (dispatch, getState) => {
.then((val) => resolve(val))
.catch((err) => reject(err));
})
- .catch((err) => {
- reject(err);
- console.log(err)
- });
+ .catch(reject);
}
});
};
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js b/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js
index e4f04942..97cb54d6 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js
@@ -1,11 +1,15 @@
import find from 'lodash/find';
+import filter from 'lodash/filter';
import { uuid } from 'utils/common';
+import cloneDeep from 'lodash/cloneDeep';
import { getWorkspacesFromIdb, saveWorkspaceToIdb, deleteWorkspaceInIdb } from 'utils/idb/workspaces';
import {
loadWorkspaces,
addWorkspace as _addWorkspace,
renameWorkspace as _renameWorkspace,
- deleteWorkspace as _deleteWorkspace
+ deleteWorkspace as _deleteWorkspace,
+ addCollectionToWorkspace as _addCollectionToWorkspace,
+ removeCollectionFromWorkspace as _removeCollectionFromWorkspace
} from './index';
const seedWorkpace = () => {
@@ -75,7 +79,7 @@ export const renameWorkspace = (newName, uid) => (dispatch, getState) => {
name: newName
})))
.then(resolve)
- .catch((err) => console.log(err));
+ .catch(reject);
});
};
@@ -98,6 +102,76 @@ export const deleteWorkspace = (workspaceUid) => (dispatch, getState) => {
workspaceUid: workspaceUid
})))
.then(resolve)
- .catch((err) => console.log(err));
+ .catch(reject);
});
-};
\ No newline at end of file
+};
+
+export const addCollectionToWorkspace = (workspaceUid, collectionUid) => (dispatch, getState) => {
+ const state = getState();
+
+ return new Promise((resolve, reject) => {
+ const workspace = find(state.workspaces.workspaces, (w) => w.uid === workspaceUid);
+ const collection = find(state.collections.collections, (c) => c.uid === collectionUid);
+
+ if(!workspace) {
+ return reject(new Error('Workspace not found'));
+ }
+
+ if(!collection) {
+ return reject(new Error('Collection not found'));
+ }
+
+ const workspaceCopy = cloneDeep(workspace);
+ if(workspaceCopy.collectionUids && workspace.collectionUids.length) {
+ if(!workspaceCopy.collectionUids.includes(collectionUid)) {
+ workspaceCopy.collectionUids.push(collectionUid);
+ }
+ } else {
+ workspaceCopy.collectionUids = [collectionUid];
+ }
+
+ saveWorkspaceToIdb(window.__idb, workspaceCopy)
+ .then(() => dispatch(_addCollectionToWorkspace({
+ workspaceUid: workspaceUid,
+ collectionUid: collectionUid
+ })))
+ .then(resolve)
+ .catch(reject);
+ });
+};
+
+export const removeCollectionFromWorkspace = (workspaceUid, collectionUid) => (dispatch, getState) => {
+ const state = getState();
+
+ return new Promise((resolve, reject) => {
+ const workspace = find(state.workspaces.workspaces, (w) => w.uid === workspaceUid);
+ const collection = find(state.collections.collections, (c) => c.uid === collectionUid);
+
+ if(!workspace) {
+ return reject(new Error('Workspace not found'));
+ }
+
+ if(!collection) {
+ return reject(new Error('Collection not found'));
+ }
+
+ const workspaceCopy = cloneDeep(workspace);
+ if(workspaceCopy.collectionUids && workspace.collectionUids.length) {
+ workspaceCopy.collectionUids = filter(workspaceCopy.collectionUids, (uid) => uid !== collectionUid);
+ }
+
+ saveWorkspaceToIdb(window.__idb, workspaceCopy)
+ .then(() => dispatch(_removeCollectionFromWorkspace({
+ workspaceUid: workspaceUid,
+ collectionUid: collectionUid
+ })))
+ .then(resolve)
+ .catch(reject);
+ });
+};
+
+// TODO
+// Workspaces can have collection uids that no longer exist
+// or the user may have the collections access revoked (in teams)
+// This action will have to be called at the beginning to purge any zombi collectionUids in the workspaces
+export const removeZombieCollectionFromAllWorkspaces = (collectionUid) => (dispatch, getState) => {};
\ No newline at end of file
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/index.js
index 231d3edc..ad6befcc 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/index.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/index.js
@@ -1,9 +1,10 @@
import { createSlice } from '@reduxjs/toolkit';
-import each from 'lodash/each';
import find from 'lodash/find';
+import filter from 'lodash/filter';
const initialState = {
workspaces: [],
+ collectionUids: [],
activeWorkspaceUid: null
};
@@ -37,6 +38,28 @@ export const workspacesSlice = createSlice({
},
addWorkspace: (state, action) => {
state.workspaces.push(action.payload.workspace);
+ },
+ addCollectionToWorkspace: (state, action) => {
+ const { workspaceUid, collectionUid } = action.payload;
+ const workspace = find(state.workspaces, (w) => w.uid === workspaceUid);
+
+ if(workspace) {
+ if(workspace.collectionUids && workspace.collectionUids.length) {
+ if(!workspace.collectionUids.includes(collectionUid)) {
+ workspace.collectionUids.push(collectionUid);
+ }
+ } else {
+ workspace.collectionUids = [collectionUid];
+ }
+ }
+ },
+ removeCollectionFromWorkspace: (state, action) => {
+ const { workspaceUid, collectionUid } = action.payload;
+ const workspace = find(state.workspaces, (w) => w.uid === workspaceUid);
+
+ if(workspace && workspace.collectionUids && workspace.collectionUids.length) {
+ workspace.collectionUids = filter(workspace.collectionUids, (uid) => uid !== collectionUid);
+ }
}
}
});
@@ -46,7 +69,9 @@ export const {
selectWorkspace,
renameWorkspace,
deleteWorkspace,
- addWorkspace
+ addWorkspace,
+ addCollectionToWorkspace,
+ removeCollectionFromWorkspace
} = workspacesSlice.actions;
export default workspacesSlice.reducer;
diff --git a/packages/bruno-app/src/utils/common/index.js b/packages/bruno-app/src/utils/common/index.js
index 5ad2b7c5..d54475f0 100644
--- a/packages/bruno-app/src/utils/common/index.js
+++ b/packages/bruno-app/src/utils/common/index.js
@@ -18,3 +18,9 @@ export const simpleHash = str => {
}
return new Uint32Array([hash])[0].toString(36);
};
+
+export const waitForNextTick = () => {
+ return new Promise((resolve, reject) => {
+ setTimeout(() => resolve(), 0);
+ });
+};