redactor: moved all reducer collection actions needing idb access to actions file

This commit is contained in:
Anoop M D 2022-10-15 02:08:35 +05:30
parent a84080b482
commit a78bdf87fe
9 changed files with 257 additions and 236 deletions

View File

@ -4,7 +4,8 @@ import CodeEditor from 'components/CodeEditor';
import FormUrlEncodedParams from 'components/RequestPane/FormUrlEncodedParams'; import FormUrlEncodedParams from 'components/RequestPane/FormUrlEncodedParams';
import MultipartFormParams from 'components/RequestPane/MultipartFormParams'; import MultipartFormParams from 'components/RequestPane/MultipartFormParams';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { updateRequestBody, sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections'; import { updateRequestBody } from 'providers/ReduxStore/slices/collections';
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
const RequestBody = ({item, collection}) => { const RequestBody = ({item, collection}) => {

View File

@ -4,7 +4,7 @@ import * as Yup from 'yup';
import Modal from 'components/Modal'; import Modal from 'components/Modal';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { isItemAFolder } from 'utils/tabs'; import { isItemAFolder } from 'utils/tabs';
import { cloneItem } from 'providers/ReduxStore/slices/collections'; import { cloneItem } from 'providers/ReduxStore/slices/collections/actions';
const CloneCollectionItem = ({collection, item, onClose}) => { const CloneCollectionItem = ({collection, item, onClose}) => {
const dispatch = useDispatch(); const dispatch = useDispatch();

View File

@ -3,7 +3,7 @@ import Modal from 'components/Modal';
import { isItemAFolder } from 'utils/tabs'; import { isItemAFolder } from 'utils/tabs';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { closeTabs } from 'providers/ReduxStore/slices/tabs'; import { closeTabs } from 'providers/ReduxStore/slices/tabs';
import { deleteItem } from 'providers/ReduxStore/slices/collections'; import { deleteItem } from 'providers/ReduxStore/slices/collections/actions';
import { recursivelyGetAllItemUids } from 'utils/collections'; import { recursivelyGetAllItemUids } from 'utils/collections';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';

View File

@ -4,7 +4,7 @@ import * as Yup from 'yup';
import Modal from 'components/Modal'; import Modal from 'components/Modal';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { isItemAFolder } from 'utils/tabs'; import { isItemAFolder } from 'utils/tabs';
import { renameItem } from 'providers/ReduxStore/slices/collections'; import { renameItem } from 'providers/ReduxStore/slices/collections/actions';
const RenameCollectionItem = ({collection, item, onClose}) => { const RenameCollectionItem = ({collection, item, onClose}) => {
const dispatch = useDispatch(); const dispatch = useDispatch();

View File

@ -3,7 +3,7 @@ import {useFormik} from 'formik';
import * as Yup from 'yup'; import * as Yup from 'yup';
import Modal from 'components/Modal'; import Modal from 'components/Modal';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { newFolder } from 'providers/ReduxStore/slices/collections'; import { newFolder } from 'providers/ReduxStore/slices/collections/actions';
const NewFolder = ({collection, item, onClose}) => { const NewFolder = ({collection, item, onClose}) => {
const dispatch = useDispatch(); const dispatch = useDispatch();

View File

@ -4,7 +4,8 @@ import * as Yup from 'yup';
import { uuid } from 'utils/common';; import { uuid } from 'utils/common';;
import Modal from 'components/Modal'; import Modal from 'components/Modal';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { newHttpRequest, newEphermalHttpRequest } from 'providers/ReduxStore/slices/collections'; import { newEphermalHttpRequest } from 'providers/ReduxStore/slices/collections';
import { newHttpRequest } from 'providers/ReduxStore/slices/collections/actions';
import { addTab } from 'providers/ReduxStore/slices/tabs'; import { addTab } from 'providers/ReduxStore/slices/tabs';
import HttpMethodSelector from 'components/RequestPane/QueryUrl/HttpMethodSelector'; import HttpMethodSelector from 'components/RequestPane/QueryUrl/HttpMethodSelector';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';

View File

@ -3,8 +3,7 @@ import find from 'lodash/find';
import Mousetrap from 'mousetrap'; import Mousetrap from 'mousetrap';
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import SaveRequest from 'components/RequestPane/SaveRequest'; import SaveRequest from 'components/RequestPane/SaveRequest';
import { saveRequest } from 'providers/ReduxStore/slices/collections'; import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
import { sendRequest } from 'providers/ReduxStore/slices/collections/actions';
import { findCollectionByUid, findItemInCollection } from 'utils/collections'; import { findCollectionByUid, findItemInCollection } from 'utils/collections';
export const HotkeysContext = React.createContext(); export const HotkeysContext = React.createContext();

View File

@ -2,9 +2,13 @@ import axios from 'axios';
import { uuid } from 'utils/common'; import { uuid } from 'utils/common';
import cloneDeep from 'lodash/cloneDeep'; import cloneDeep from 'lodash/cloneDeep';
import { import {
findItemInCollection,
findCollectionByUid, findCollectionByUid,
recursivelyGetAllItemUids, recursivelyGetAllItemUids,
transformCollectionToSaveToIdb transformCollectionToSaveToIdb,
deleteItemInCollection,
findParentItemInCollection,
isItemAFolder
} from 'utils/collections'; } from 'utils/collections';
import { waitForNextTick } from 'utils/common'; import { waitForNextTick } from 'utils/common';
import cancelTokens, { saveCancelToken, deleteCancelToken } from 'utils/network/cancelTokens'; import cancelTokens, { saveCancelToken, deleteCancelToken } from 'utils/network/cancelTokens';
@ -15,6 +19,11 @@ import {
requestSent, requestSent,
requestCancelled, requestCancelled,
responseReceived, responseReceived,
newItem as _newItem,
renameItem as _renameItem,
cloneItem as _cloneItem,
deleteItem as _deleteItem,
saveRequest as _saveRequest,
createCollection as _createCollection, createCollection as _createCollection,
renameCollection as _renameCollection, renameCollection as _renameCollection,
deleteCollection as _deleteCollection, deleteCollection as _deleteCollection,
@ -115,6 +124,29 @@ export const deleteCollection = (collectionUid) => (dispatch, getState) => {
}); });
}; };
export const saveRequest = (itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
if(!collection) {
return reject(new Error('Collection not found'));
}
const collectionCopy = cloneDeep(collection);
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_saveRequest({
itemUid: itemUid,
collectionUid: collectionUid
}));
})
.then(() => resolve())
.catch((error) => reject(error));
});
};
export const sendRequest = (item, collectionUid) => (dispatch) => { export const sendRequest = (item, collectionUid) => (dispatch) => {
const axiosRequest = axios.CancelToken.source(); const axiosRequest = axios.CancelToken.source();
const cancelTokenUid = uuid(); const cancelTokenUid = uuid();
@ -149,3 +181,203 @@ export const cancelRequest = (cancelTokenUid, item, collection) => (dispatch) =>
})) }))
} }
}; };
export const newFolder = (folderName, collectionUid, itemUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
if(!collection) {
return reject(new Error('Collection not found'));
}
const collectionCopy = cloneDeep(collection);
const item = {
uid: uuid(),
name: folderName,
type: 'folder',
items: []
};
if(!itemUid) {
collectionCopy.items.push(item);
} else {
const currentItem = findItemInCollection(collectionCopy, itemUid);
if(currentItem && currentItem.type === 'folder') {
currentItem.items = currentItem.items || [];
currentItem.items.push(item);
}
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_newItem({
item: item,
currentItemUid: itemUid,
collectionUid: collectionUid
}));
})
.then(() => resolve())
.catch((error) => reject(error));
});
};
export const renameItem = (newName, itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
if(!collection) {
return reject(new Error('Collection not found'));
}
const collectionCopy = cloneDeep(collection);
const item = findItemInCollection(collectionCopy, itemUid);
if(item) {
item.name = newName;
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy, {
ignoreDraft: true
});
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_renameItem({
newName: newName,
itemUid: itemUid,
collectionUid: collectionUid
}));
})
.then(() => resolve())
.catch((error) => reject(error));
});
};
export const cloneItem = (newName, itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
if(!collection) {
return reject(new Error('Collection not found'));
}
const collectionCopy = cloneDeep(collection);
const item = findItemInCollection(collectionCopy, itemUid);
if(!item) {
return;
}
if(isItemAFolder(item)) {
throw new Error('Cloning folders is not supported yet');
}
// todo: clone query params
const clonedItem = cloneDeep(item);
clonedItem.name = newName;
clonedItem.uid = uuid();
each(clonedItem.headers, h => h.uid = uuid());
const parentItem = findParentItemInCollection(collectionCopy, itemUid);
if(!parentItem) {
collectionCopy.items.push(clonedItem);
} else {
parentItem.items.push(clonedItem);
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_cloneItem({
parentItemUid: parentItem ? parentItem.uid : null,
clonedItem: clonedItem,
collectionUid: collectionUid
}));
})
.then(() => resolve())
.catch((error) => reject(error));
});
};
export const deleteItem = (itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
if(collection) {
const collectionCopy = cloneDeep(collection);
deleteItemInCollection(itemUid, collectionCopy);
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_deleteItem({
itemUid: itemUid,
collectionUid: collectionUid
}));
})
.then(() => resolve())
.catch((error) => reject(error));
}
});
};
export const newHttpRequest = (params) => (dispatch, getState) => {
const {
requestName,
requestType,
requestUrl,
requestMethod,
collectionUid,
itemUid
} = params;
return new Promise((resolve, reject) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
if(!collection) {
return reject(new Error('Collection not found'));
}
const collectionCopy = cloneDeep(collection);
const item = {
uid: uuid(),
type: requestType,
name: requestName,
request: {
method: requestMethod,
url: requestUrl,
headers: [],
body: {
mode: 'none',
json: null,
text: null,
xml: null,
multipartForm: null,
formUrlEncoded: null
}
}
};
if(!itemUid) {
collectionCopy.items.push(item);
} else {
const currentItem = findItemInCollection(collectionCopy, itemUid);
if(currentItem && currentItem.type === 'folder') {
currentItem.items = currentItem.items || [];
currentItem.items.push(item);
}
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_newItem({
item: item,
currentItemUid: itemUid,
collectionUid: collectionUid
}));
})
.then(() => resolve())
.catch(reject);
});
};

View File

@ -9,16 +9,13 @@ import splitOnFirst from 'split-on-first';
import { import {
findCollectionByUid, findCollectionByUid,
findItemInCollection, findItemInCollection,
findParentItemInCollection,
transformCollectionToSaveToIdb,
addDepth, addDepth,
collapseCollection, collapseCollection,
deleteItemInCollection, deleteItemInCollection,
isItemARequest, isItemARequest
isItemAFolder
} from 'utils/collections'; } from 'utils/collections';
import { parseQueryParams, stringifyQueryParams } from 'utils/url'; import { parseQueryParams, stringifyQueryParams } from 'utils/url';
import { getCollectionsFromIdb, saveCollectionToIdb } from 'utils/idb'; import { getCollectionsFromIdb } from 'utils/idb';
// todo: errors should be tracked in each slice and displayed as toasts // todo: errors should be tracked in each slice and displayed as toasts
@ -30,7 +27,7 @@ export const collectionsSlice = createSlice({
name: 'collections', name: 'collections',
initialState, initialState,
reducers: { reducers: {
_loadCollections: (state, action) => { loadCollections: (state, action) => {
each(action.payload.collections, (c) => collapseCollection(c)); each(action.payload.collections, (c) => collapseCollection(c));
each(action.payload.collections, (c) => addDepth(c.items)); each(action.payload.collections, (c) => addDepth(c.items));
state.collections = action.payload.collections; state.collections = action.payload.collections;
@ -48,7 +45,7 @@ export const collectionsSlice = createSlice({
deleteCollection: (state, action) => { deleteCollection: (state, action) => {
state.collections = filter(state.collections, c => c.uid !== action.payload.collectionUid); state.collections = filter(state.collections, c => c.uid !== action.payload.collectionUid);
}, },
_newItem: (state, action) => { newItem: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid); const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
if(collection) { if(collection) {
@ -65,14 +62,14 @@ export const collectionsSlice = createSlice({
addDepth(collection.items); addDepth(collection.items);
} }
}, },
_deleteItem: (state, action) => { deleteItem: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid); const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
if(collection) { if(collection) {
deleteItemInCollection(action.payload.itemUid, collection); deleteItemInCollection(action.payload.itemUid, collection);
} }
}, },
_renameItem: (state, action) => { renameItem: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid); const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
if(collection) { if(collection) {
@ -83,7 +80,7 @@ export const collectionsSlice = createSlice({
} }
} }
}, },
_cloneItem: (state, action) => { cloneItem: (state, action) => {
const collectionUid = action.payload.collectionUid; const collectionUid = action.payload.collectionUid;
const clonedItem = action.payload.clonedItem; const clonedItem = action.payload.clonedItem;
const parentItemUid = action.payload.parentItemUid; const parentItemUid = action.payload.parentItemUid;
@ -134,7 +131,7 @@ export const collectionsSlice = createSlice({
} }
} }
}, },
_saveRequest: (state, action) => { saveRequest: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid); const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
if(collection) { if(collection) {
@ -544,15 +541,15 @@ export const {
createCollection, createCollection,
renameCollection, renameCollection,
deleteCollection, deleteCollection,
_loadCollections, loadCollections,
_newItem, newItem,
_deleteItem, deleteItem,
_renameItem, renameItem,
_cloneItem, cloneItem,
requestSent, requestSent,
requestCancelled, requestCancelled,
responseReceived, responseReceived,
_saveRequest, saveRequest,
newEphermalHttpRequest, newEphermalHttpRequest,
collectionClicked, collectionClicked,
collectionFolderClicked, collectionFolderClicked,
@ -576,219 +573,10 @@ export const {
export const loadCollectionsFromIdb = () => (dispatch) => { export const loadCollectionsFromIdb = () => (dispatch) => {
getCollectionsFromIdb(window.__idb) getCollectionsFromIdb(window.__idb)
.then((collections) => dispatch(_loadCollections({ .then((collections) => dispatch(loadCollections({
collections: collections collections: collections
}))) })))
.catch((err) => console.log(err)); .catch((err) => console.log(err));
}; };
export const saveRequest = (itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
if(collection) {
const collectionCopy = cloneDeep(collection);
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_saveRequest({
itemUid: itemUid,
collectionUid: collectionUid
}));
})
.then(() => resolve())
.catch((error) => reject(error));
}
});
};
export const newFolder = (folderName, collectionUid, itemUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
if(collection) {
const collectionCopy = cloneDeep(collection);
const item = {
uid: uuid(),
name: folderName,
type: 'folder',
items: []
};
if(!itemUid) {
collectionCopy.items.push(item);
} else {
const currentItem = findItemInCollection(collectionCopy, itemUid);
if(currentItem && currentItem.type === 'folder') {
currentItem.items = currentItem.items || [];
currentItem.items.push(item);
}
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_newItem({
item: item,
currentItemUid: itemUid,
collectionUid: collectionUid
}));
})
.catch((err) => console.log(err));
}
};
export const newHttpRequest = (params) => (dispatch, getState) => {
const {
requestName,
requestType,
requestUrl,
requestMethod,
collectionUid,
itemUid
} = params;
return new Promise((resolve, reject) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
if(collection) {
const collectionCopy = cloneDeep(collection);
const item = {
uid: uuid(),
type: requestType,
name: requestName,
request: {
method: requestMethod,
url: requestUrl,
headers: [],
body: {
mode: 'none',
json: null,
text: null,
xml: null,
multipartForm: null,
formUrlEncoded: null
}
}
};
if(!itemUid) {
collectionCopy.items.push(item);
} else {
const currentItem = findItemInCollection(collectionCopy, itemUid);
if(currentItem && currentItem.type === 'folder') {
currentItem.items = currentItem.items || [];
currentItem.items.push(item);
}
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
Promise.resolve(dispatch(_newItem({
item: item,
currentItemUid: itemUid,
collectionUid: collectionUid
})))
.then((val) => resolve(val))
.catch((err) => reject(err));
})
.catch(reject);
}
});
};
export const deleteItem = (itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
return new Promise((resolve, reject) => {
if(collection) {
const collectionCopy = cloneDeep(collection);
deleteItemInCollection(itemUid, collectionCopy);
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_deleteItem({
itemUid: itemUid,
collectionUid: collectionUid
}));
})
.then(() => resolve())
.catch((error) => reject(error));
}
});
};
export const renameItem = (newName, itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
if(collection) {
const collectionCopy = cloneDeep(collection);
const item = findItemInCollection(collectionCopy, itemUid);
if(item) {
item.name = newName;
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy, {
ignoreDraft: true
});
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_renameItem({
newName: newName,
itemUid: itemUid,
collectionUid: collectionUid
}));
})
.catch((err) => console.log(err));
}
};
export const cloneItem = (newName, itemUid, collectionUid) => (dispatch, getState) => {
const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid);
if(collection) {
const collectionCopy = cloneDeep(collection);
const item = findItemInCollection(collectionCopy, itemUid);
if(!item) {
return;
}
if(isItemAFolder(item)) {
throw new Error('Cloning folders is not supported yet');
}
// todo: clone query params
const clonedItem = cloneDeep(item);
clonedItem.name = newName;
clonedItem.uid = uuid();
each(clonedItem.headers, h => h.uid = uuid());
const parentItem = findParentItemInCollection(collectionCopy, itemUid);
if(!parentItem) {
collectionCopy.items.push(clonedItem);
} else {
parentItem.items.push(clonedItem);
}
const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => {
dispatch(_cloneItem({
parentItemUid: parentItem ? parentItem.uid : null,
clonedItem: clonedItem,
collectionUid: collectionUid
}));
})
.catch((err) => console.log(err));
}
};
export default collectionsSlice.reducer; export default collectionsSlice.reducer;