From 819e8c2ccde83200ef57df16a599efb855d60700 Mon Sep 17 00:00:00 2001 From: Anoop M D Date: Thu, 13 Oct 2022 05:23:54 +0530 Subject: [PATCH] feat: sync workspaces with idb --- .../WorkspaceConfigurer/AddWorkspace/index.js | 11 ++- .../DeleteWorkspace/index.js | 11 ++- .../EditWorkspace/index.js | 11 ++- .../ReduxStore/slices/workspaces/actions.js | 92 ++++++++++++++++++- .../ReduxStore/slices/workspaces/index.js | 32 +++---- .../bruno-app/src/utils/idb/workspaces.js | 6 +- 6 files changed, 130 insertions(+), 33 deletions(-) diff --git a/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/AddWorkspace/index.js b/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/AddWorkspace/index.js index da3f242c4..463402340 100644 --- a/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/AddWorkspace/index.js +++ b/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/AddWorkspace/index.js @@ -2,9 +2,10 @@ import React, { useEffect, useRef } from 'react'; import Portal from "components/Portal/index"; import Modal from "components/Modal/index"; import { useFormik } from 'formik'; -import { addWorkspace } from 'providers/ReduxStore/slices/workspaces'; +import { addWorkspace } from 'providers/ReduxStore/slices/workspaces/actions'; import * as Yup from 'yup'; import { useDispatch } from 'react-redux'; +import toast from 'react-hot-toast'; const AddWorkspace = ({onClose}) => { const dispatch = useDispatch(); @@ -21,8 +22,12 @@ const AddWorkspace = ({onClose}) => { .required('name is required') }), onSubmit: (values) => { - dispatch(addWorkspace({name: values.name})); - onClose(); + dispatch(addWorkspace(values.name)) + .then(() => { + toast.success("Workspace created!"); + onClose(); + }) + .catch(() => toast.error("An error occured while creating the workspace")); } }); diff --git a/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/index.js b/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/index.js index 79c94fb51..20f03f871 100644 --- a/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/index.js +++ b/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/DeleteWorkspace/index.js @@ -1,15 +1,20 @@ import React from 'react'; import Portal from "components/Portal/index"; import Modal from "components/Modal/index"; -import { deleteWorkspace } from 'providers/ReduxStore/slices/workspaces'; +import { deleteWorkspace } from 'providers/ReduxStore/slices/workspaces/actions'; import { useDispatch } from 'react-redux'; +import toast from 'react-hot-toast'; import StyledWrapper from './StyledWrapper'; const DeleteWorkspace = ({onClose, workspace}) => { const dispatch = useDispatch(); const onConfirm = () =>{ - dispatch(deleteWorkspace({workspaceUid: workspace.uid})) - onClose(); + dispatch(deleteWorkspace(workspace.uid)) + .then(() => { + toast.success("Workspace deleted!"); + onClose(); + }) + .catch(() => toast.error("An error occured while deleting the workspace")); }; return ( diff --git a/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/EditWorkspace/index.js b/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/EditWorkspace/index.js index b5880da5a..1428d1395 100644 --- a/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/EditWorkspace/index.js +++ b/packages/bruno-app/src/components/Workspaces/WorkspaceConfigurer/EditWorkspace/index.js @@ -2,9 +2,10 @@ import React, { useEffect, useRef } from 'react'; import Portal from "components/Portal/index"; import Modal from "components/Modal/index"; import { useFormik } from 'formik'; -import { renameWorkspace } from 'providers/ReduxStore/slices/workspaces'; +import { renameWorkspace } from 'providers/ReduxStore/slices/workspaces/actions'; import * as Yup from 'yup'; import { useDispatch } from 'react-redux'; +import toast from 'react-hot-toast'; const EditWorkspace = ({onClose, workspace}) => { const dispatch = useDispatch(); @@ -21,8 +22,12 @@ const EditWorkspace = ({onClose, workspace}) => { .required('name is required') }), onSubmit: (values) => { - dispatch(renameWorkspace({name: values.name, uid: workspace.uid})); - onClose(); + dispatch(renameWorkspace(values.name, workspace.uid)) + .then(() => { + toast.success("Workspace renamed!"); + onClose(); + }) + .catch(() => toast.error("An error occured while renaming the workspace")); } }); 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 78d64985e..e4f049426 100644 --- a/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js +++ b/packages/bruno-app/src/providers/ReduxStore/slices/workspaces/actions.js @@ -1,15 +1,103 @@ -import { getWorkspacesFromIdb } from 'utils/idb/workspaces'; +import find from 'lodash/find'; +import { uuid } from 'utils/common'; +import { getWorkspacesFromIdb, saveWorkspaceToIdb, deleteWorkspaceInIdb } from 'utils/idb/workspaces'; import { - loadWorkspaces + loadWorkspaces, + addWorkspace as _addWorkspace, + renameWorkspace as _renameWorkspace, + deleteWorkspace as _deleteWorkspace } from './index'; +const seedWorkpace = () => { + const uid = uuid(); + const workspace = { + uid: uid, + name: 'My workspace' + }; + + return new Promise((resolve, reject) => { + saveWorkspaceToIdb(window.__idb, workspace) + .then(() => resolve([workspace])) + .catch(reject); + }); +}; + export const loadWorkspacesFromIdb = () => (dispatch) => { return new Promise((resolve, reject) => { getWorkspacesFromIdb(window.__idb) + .then((workspaces) => { + if(!workspaces || !workspaces.length) { + return seedWorkpace(); + } + + return workspaces; + }) .then((workspaces) => dispatch(loadWorkspaces({ workspaces: workspaces }))) .then(resolve) .catch(reject); }); +}; + +export const addWorkspace = (workspaceName) => (dispatch) => { + const newWorkspace = { + uid: uuid(), + name: workspaceName + }; + + return new Promise((resolve, reject) => { + saveWorkspaceToIdb(window.__idb, newWorkspace) + .then(() => dispatch(_addWorkspace({ + workspace: newWorkspace + }))) + .then(resolve) + .catch(reject); + }); +}; + +export const renameWorkspace = (newName, uid) => (dispatch, getState) => { + const state = getState(); + + return new Promise((resolve, reject) => { + const workspace = find(state.workspaces.workspaces, (w) => w.uid === uid); + + if(!workspace) { + return reject(new Error('Workspace not found')); + } + + saveWorkspaceToIdb(window.__idb, { + uid: workspace.uid, + name: newName, + }) + .then(() => dispatch(_renameWorkspace({ + uid: uid, + name: newName + }))) + .then(resolve) + .catch((err) => console.log(err)); + }); +}; + +export const deleteWorkspace = (workspaceUid) => (dispatch, getState) => { + const state = getState(); + + return new Promise((resolve, reject) => { + if(state.workspaces.activeWorkspaceUid === workspaceUid) { + throw new Error("User cannot delete current workspace"); + } + + const workspace = find(state.workspaces.workspaces, (w) => w.uid === workspaceUid); + + if(!workspace) { + return reject(new Error('Workspace not found')); + } + + deleteWorkspaceInIdb(window.__idb, workspaceUid) + .then(() => dispatch(_deleteWorkspace({ + workspaceUid: workspaceUid + }))) + .then(resolve) + .catch((err) => console.log(err)); + }); }; \ 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 fb9917707..231d3edc9 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,6 @@ import { createSlice } from '@reduxjs/toolkit'; -import { each } from 'lodash'; -import { uuid } from 'utils/common'; +import each from 'lodash/each'; +import find from 'lodash/find'; const initialState = { workspaces: [], @@ -12,28 +12,22 @@ export const workspacesSlice = createSlice({ initialState, reducers: { loadWorkspaces: (state, action) => { - const workspaces = action.payload.workspaces; + state.workspaces = action.payload.workspaces; - if(!workspaces || !workspaces.length) { - const uid = uuid(); - state.workspaces.push({ - uid: uid, - name: 'My workspace' - }); - state.activeWorkspaceUid = uid; - return; + if(state.workspaces && state.workspaces.length) { + state.activeWorkspaceUid = state.workspaces[0].uid; } - - each(workspaces, w => state.workspaces.push(w)); }, selectWorkspace: (state, action) => { state.activeWorkspaceUid = action.payload.uid; }, renameWorkspace: (state, action) => { const { name, uid } = action.payload; - const { workspaces } = state; - const workspaceIndex = workspaces.findIndex(workspace => workspace.uid == uid); - workspaces[workspaceIndex].name = name; + const workspace = find(state.workspaces, (w) => w.uid === uid); + + if(workspace) { + workspace.name = name; + } }, deleteWorkspace: (state, action) => { if(state.activeWorkspaceUid === action.payload.workspaceUid) { @@ -42,11 +36,7 @@ export const workspacesSlice = createSlice({ state.workspaces = state.workspaces.filter((workspace) => workspace.uid !== action.payload.workspaceUid); }, addWorkspace: (state, action) => { - const newWorkspace = { - uid: uuid(), - name: action.payload.name - } - state.workspaces.push(newWorkspace); + state.workspaces.push(action.payload.workspace); } } }); diff --git a/packages/bruno-app/src/utils/idb/workspaces.js b/packages/bruno-app/src/utils/idb/workspaces.js index e172d5029..72c96d2d1 100644 --- a/packages/bruno-app/src/utils/idb/workspaces.js +++ b/packages/bruno-app/src/utils/idb/workspaces.js @@ -15,8 +15,12 @@ export const saveWorkspaceToIdb = (connection, workspace) => { workspaceStore.put(workspace); } - resolve(); + return new Promise((res, rej) => { + tx.oncomplete = () => res(); + tx.onerror = () => rej(tx.error); + }); }) + .then(resolve) .catch((err) => reject(err)); }); };