feat: sync workspaces with idb

This commit is contained in:
Anoop M D 2022-10-13 05:23:54 +05:30
parent 008704c4e1
commit 819e8c2ccd
6 changed files with 130 additions and 33 deletions

View File

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

View File

@ -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 (

View File

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

View File

@ -1,11 +1,37 @@
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
})))
@ -13,3 +39,65 @@ export const loadWorkspacesFromIdb = () => (dispatch) => {
.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));
});
};

View File

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

View File

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