feat: collections are stored as objects in workspaces

This commit is contained in:
Anoop M D 2022-10-15 13:50:58 +05:30
parent d546709b26
commit 91981a48e4
8 changed files with 68 additions and 21 deletions

View File

@ -16,11 +16,13 @@ const SelectCollection = ({onClose, onSelect, title}) => {
handleCancel={onClose}
>
<ul className="mb-2" >
{collections && collections.length && collections.map((c) => (
{(collections && collections.length) ? collections.map((c) => (
<div className="collection" key={c.uid} onClick={() => onSelect(c.uid)}>
<IconFiles size={18} strokeWidth={1.5}/> <span className="ml-2">{c.name}</span>
</div>
))}
)) : (
<div>No collections found</div>
)}
</ul>
</Modal>
</StyledWrapper>

View File

@ -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 <CreateOrAddCollection />;

View File

@ -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';

View File

@ -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) => {};
// 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) => {};

View File

@ -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);
}
}
}

View File

@ -0,0 +1,5 @@
import find from 'lodash/find';
export const findCollectionInWorkspace = (workspace, collectionUid) => {
return find(workspace.collections, (c) => c.uid === collectionUid);
};

View File

@ -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 = {

View File

@ -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')
)
]);
});
});