diff --git a/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/index.js b/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/index.js index a96c770cf..787511287 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/SelectCollection/index.js @@ -16,11 +16,13 @@ const SelectCollection = ({onClose, onSelect, title}) => { handleCancel={onClose} > diff --git a/packages/bruno-app/src/components/Sidebar/Collections/index.js b/packages/bruno-app/src/components/Sidebar/Collections/index.js index 1ad6865c5..73d43aa20 100644 --- a/packages/bruno-app/src/components/Sidebar/Collections/index.js +++ b/packages/bruno-app/src/components/Sidebar/Collections/index.js @@ -4,6 +4,7 @@ import find from 'lodash/find'; import filter from 'lodash/filter'; import Collection from './Collection'; import CreateOrAddCollection from './CreateOrAddCollection'; +import { findCollectionInWorkspace } from 'utils/workspaces'; const Collections = ({searchText}) => { const { collections } = useSelector((state) => state.collections); @@ -14,8 +15,7 @@ const Collections = ({searchText}) => { return null; } - const { collectionUids } = activeWorkspace; - const collectionToDisplay = filter(collections, (c) => collectionUids.includes(c.uid)); + const collectionToDisplay = filter(collections, (c) => findCollectionInWorkspace(activeWorkspace, c.uid)); if(!collectionToDisplay || !collectionToDisplay.length) { return ; 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 a495027bc..e4d62292c 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/actions.js @@ -1,4 +1,5 @@ import axios from 'axios'; +import each from 'lodash/each'; import toast from 'react-hot-toast'; import { uuid } from 'utils/common'; import cloneDeep from 'lodash/cloneDeep'; 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 cf079b062..415e7ebbb 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js @@ -3,6 +3,7 @@ import filter from 'lodash/filter'; import { uuid } from 'utils/common'; import cloneDeep from 'lodash/cloneDeep'; import { workspaceSchema } from '@usebruno/schema'; +import { findCollectionInWorkspace } from 'utils/workspaces'; import { getWorkspacesFromIdb, saveWorkspaceToIdb, deleteWorkspaceInIdb } from 'utils/idb/workspaces'; import { loadWorkspaces, @@ -18,7 +19,7 @@ const seedWorkpace = () => { const workspace = { uid: uid, name: 'My workspace', - collectionUids: [] + collections: [] }; return new Promise((resolve, reject) => { @@ -52,7 +53,7 @@ export const addWorkspace = (workspaceName) => (dispatch) => { const newWorkspace = { uid: uuid(), name: workspaceName, - collectionUids: [] + collections: [] }; return new Promise((resolve, reject) => { @@ -131,12 +132,16 @@ export const addCollectionToWorkspace = (workspaceUid, collectionUid) => (dispat } const workspaceCopy = cloneDeep(workspace); - if(workspaceCopy.collectionUids && workspace.collectionUids.length) { - if(!workspaceCopy.collectionUids.includes(collectionUid)) { - workspaceCopy.collectionUids.push(collectionUid); + if(workspaceCopy.collections && workspace.collections.length) { + if(!findCollectionInWorkspace(workspace, collectionUid)) { + workspaceCopy.collections.push([{ + uid: collectionUid + }]); } } else { - workspaceCopy.collectionUids = [collectionUid]; + workspaceCopy.collections = [{ + uid: collectionUid + }]; } workspaceSchema @@ -167,8 +172,8 @@ export const removeCollectionFromWorkspace = (workspaceUid, collectionUid) => (d } const workspaceCopy = cloneDeep(workspace); - if(workspaceCopy.collectionUids && workspace.collectionUids.length) { - workspaceCopy.collectionUids = filter(workspaceCopy.collectionUids, (uid) => uid !== collectionUid); + if(workspaceCopy.collections && workspace.collections.length) { + workspaceCopy.collections = filter(workspaceCopy.collections, (c) => c.uid !== collectionUid); } saveWorkspaceToIdb(window.__idb, workspaceCopy) @@ -184,5 +189,5 @@ export const removeCollectionFromWorkspace = (workspaceUid, collectionUid) => (d // 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 +// This action will have to be called at the beginning to purge any zombi collection references in the workspaces +export const removeZombieCollectionFromAllWorkspaces = (workspaceUid) => (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 4d15d2d9e..2bff97657 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/index.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/index.js @@ -1,6 +1,7 @@ import { createSlice } from '@reduxjs/toolkit'; import find from 'lodash/find'; import filter from 'lodash/filter'; +import { findCollectionInWorkspace } from 'utils/workspaces'; const initialState = { workspaces: [], @@ -43,12 +44,16 @@ export const workspacesSlice = createSlice({ 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); + if(workspace.collections && workspace.collections.length) { + if(!findCollectionInWorkspace(workspace, collectionUid)) { + workspace.collections.push([{ + uid: collectionUid + }]); } } else { - workspace.collectionUids = [collectionUid]; + workspace.collections = [{ + uid: collectionUid + }]; } } }, @@ -56,8 +61,8 @@ export const workspacesSlice = createSlice({ 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); + if(workspace && workspace.collections && workspace.collections.length) { + workspace.collections = filter(workspace.collections, (c) => c.uid !== collectionUid); } } } diff --git a/packages/bruno-app/src/utils/workspaces/index.js b/packages/bruno-app/src/utils/workspaces/index.js new file mode 100644 index 000000000..3690fb0ef --- /dev/null +++ b/packages/bruno-app/src/utils/workspaces/index.js @@ -0,0 +1,5 @@ +import find from 'lodash/find'; + +export const findCollectionInWorkspace = (workspace, collectionUid) => { + return find(workspace.collections, (c) => c.uid === collectionUid); +}; \ No newline at end of file diff --git a/packages/bruno-schema/src/workspaces/index.js b/packages/bruno-schema/src/workspaces/index.js index 795ff6d70..cd289b87b 100644 --- a/packages/bruno-schema/src/workspaces/index.js +++ b/packages/bruno-schema/src/workspaces/index.js @@ -1,13 +1,17 @@ const Yup = require('yup'); const { uidSchema } = require("../common"); +const collectionsSchema = Yup.object({ + uid: uidSchema, +}).noUnknown(true).strict(); + const workspaceSchema = Yup.object({ uid: uidSchema, name: Yup.string() .min(1, 'name must be atleast 1 characters') .max(50, 'name must be 50 characters or less') .required('name is required'), - collectionUids: Yup.array().of(uidSchema) + collections: Yup.array().of(collectionsSchema) }).noUnknown(true).strict(); module.exports = { diff --git a/packages/bruno-schema/src/workspaces/index.spec.js b/packages/bruno-schema/src/workspaces/index.spec.js index fcd0b89aa..c2577c10f 100644 --- a/packages/bruno-schema/src/workspaces/index.spec.js +++ b/packages/bruno-schema/src/workspaces/index.spec.js @@ -83,4 +83,29 @@ describe('Workspace Schema Validation', () => { ) ]); }); + + it('workspace schema must validate successfully with collections', async () => { + const workspace = { + uid: uuid(), + name: 'My workspace' , + collections: [{uid: uuid()}] + }; + + const isValid = await workspaceSchema.validate(workspace); + expect(isValid).toBeTruthy(); + }); + + it('workspace schema throw an error when collections has an unknown property', async () => { + const workspace = { + uid: uuid(), + name: 'My workspace' , + collections: [{uid: uuid(), foo: 'bar'}] + }; + + return Promise.all([ + expect(workspaceSchema.validate(workspace)).rejects.toEqual( + validationErrorWithMessages('collections[0] field has unspecified keys: foo') + ) + ]); + }); });