feat: create request inside a folder

This commit is contained in:
Anoop M D 2022-03-19 15:23:20 +05:30
parent afb545e14b
commit 4245ef7d13
5 changed files with 55 additions and 22 deletions

View File

@ -1,15 +1,17 @@
import React, { useState, useRef, forwardRef } from 'react'; import React, { useState, useRef, forwardRef } from 'react';
import range from 'lodash/range';
import get from 'lodash/get'; import get from 'lodash/get';
import { IconChevronRight, IconDots } from '@tabler/icons'; import range from 'lodash/range';
import classnames from 'classnames'; import classnames from 'classnames';
import { IconChevronRight, IconDots } from '@tabler/icons';
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs'; import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs';
import { isItemARequest, isItemAFolder, itemIsOpenedInTabs } from 'utils/tabs'; import { collectionFolderClicked } from 'providers/ReduxStore/slices/collections';
import Dropdown from 'components/Dropdown'; import Dropdown from 'components/Dropdown';
import NewRequest from 'components/Sidebar/NewRequest';
import RequestMethod from './RequestMethod'; import RequestMethod from './RequestMethod';
import RenameCollectionItem from './RenameCollectionItem'; import RenameCollectionItem from './RenameCollectionItem';
import DeleteCollectionItem from './DeleteCollectionItem'; import DeleteCollectionItem from './DeleteCollectionItem';
import { isItemARequest, isItemAFolder, itemIsOpenedInTabs } from 'utils/tabs';
import StyledWrapper from './StyledWrapper'; import StyledWrapper from './StyledWrapper';
@ -20,6 +22,7 @@ const CollectionItem = ({item, collection}) => {
const [renameItemModalOpen, setRenameItemModalOpen] = useState(false); const [renameItemModalOpen, setRenameItemModalOpen] = useState(false);
const [deleteItemModalOpen, setDeleteItemModalOpen] = useState(false); const [deleteItemModalOpen, setDeleteItemModalOpen] = useState(false);
const [newRequestModalOpen, setNewRequestModalOpen] = useState(false);
const dropdownTippyRef = useRef(); const dropdownTippyRef = useRef();
const MenuIcon = forwardRef((props, ref) => { const MenuIcon = forwardRef((props, ref) => {
@ -44,6 +47,10 @@ const CollectionItem = ({item, collection}) => {
return; return;
} }
if(event && event.target && event.target.className === 'dropdown-item') {
return;
}
if(isItemARequest(item)) { if(isItemARequest(item)) {
if(itemIsOpenedInTabs(item, tabs)) { if(itemIsOpenedInTabs(item, tabs)) {
dispatch(focusTab({ dispatch(focusTab({
@ -56,19 +63,22 @@ const CollectionItem = ({item, collection}) => {
})); }));
} }
} else { } else {
// todo for folder: must expand folder : item.collapsed = !item.collapsed; dispatch(collectionFolderClicked({
itemUid: item.uid,
collectionUid: collection.uid
}));
} }
}; };
let indents = range(item.depth); let indents = range(item.depth);
const onDropdownCreate = (ref) => dropdownTippyRef.current = ref; const onDropdownCreate = (ref) => dropdownTippyRef.current = ref;
const isRequest = isItemARequest(item);
const isFolder = isItemAFolder(item); const isFolder = isItemAFolder(item);
return ( return (
<StyledWrapper className="flex flex-col"> <StyledWrapper className="flex flex-col">
{renameItemModalOpen && <RenameCollectionItem item={item} collection={collection} onClose={() => setRenameItemModalOpen(false)}/>} {renameItemModalOpen && <RenameCollectionItem item={item} collection={collection} onClose={() => setRenameItemModalOpen(false)}/>}
{deleteItemModalOpen && <DeleteCollectionItem item={item} collection={collection} onClose={() => setDeleteItemModalOpen(false)}/>} {deleteItemModalOpen && <DeleteCollectionItem item={item} collection={collection} onClose={() => setDeleteItemModalOpen(false)}/>}
{newRequestModalOpen && <NewRequest item={item} collection={collection} onClose={() => setNewRequestModalOpen(false)}/>}
<div <div
className={itemRowClassName} className={itemRowClassName}
onClick={handleClick} onClick={handleClick}
@ -111,6 +121,7 @@ const CollectionItem = ({item, collection}) => {
<> <>
<div className="dropdown-item" onClick={(e) => { <div className="dropdown-item" onClick={(e) => {
dropdownTippyRef.current.hide(); dropdownTippyRef.current.hide();
setNewRequestModalOpen(true);
}}> }}>
New Request New Request
</div> </div>

View File

@ -44,17 +44,10 @@ const Collection = ({collection}) => {
}; };
const hideNewFolderModal = () => setShowNewFolderModal(false); const hideNewFolderModal = () => setShowNewFolderModal(false);
const hideNewRequestModal = () => setShowNewRequestModal(false);
return ( return (
<StyledWrapper className="flex flex-col"> <StyledWrapper className="flex flex-col">
{showNewRequestModal && ( {showNewRequestModal && <NewRequest collection={collection} onClose={() => setShowNewRequestModal(false)}/>}
<NewRequest
collectionUid={collection.uid}
handleCancel={hideNewRequestModal}
handleClose={hideNewRequestModal}
/>
)}
{showNewFolderModal && ( {showNewFolderModal && (
<NewFolder <NewFolder
collectionUid={collection.uid} collectionUid={collection.uid}

View File

@ -6,7 +6,7 @@ import { useDispatch } from 'react-redux';
import { newHttpRequest } from 'providers/ReduxStore/slices/collections'; import { newHttpRequest } from 'providers/ReduxStore/slices/collections';
import { addTab } from 'providers/ReduxStore/slices/tabs'; import { addTab } from 'providers/ReduxStore/slices/tabs';
const NewRequest = ({collectionUid, handleCancel, handleClose}) => { const NewRequest = ({collection, item, onClose}) => {
const dispatch = useDispatch(); const dispatch = useDispatch();
const inputRef = useRef(); const inputRef = useRef();
const formik = useFormik({ const formik = useFormik({
@ -21,14 +21,14 @@ const NewRequest = ({collectionUid, handleCancel, handleClose}) => {
.required('name is required') .required('name is required')
}), }),
onSubmit: (values) => { onSubmit: (values) => {
dispatch(newHttpRequest(values.requestName, collectionUid)) dispatch(newHttpRequest(values.requestName, collection.uid, item ? item.uid : null))
.then((action) => { .then((action) => {
dispatch(addTab({ dispatch(addTab({
uid: action.payload.item.uid, uid: action.payload.item.uid,
collectionUid: collectionUid collectionUid: collection.uid
})); }));
}); });
handleClose(); onClose();
} }
}); });
@ -46,7 +46,7 @@ const NewRequest = ({collectionUid, handleCancel, handleClose}) => {
title='New Request' title='New Request'
confirmText='Create' confirmText='Create'
handleConfirm={onSubmit} handleConfirm={onSubmit}
handleCancel={handleCancel} handleCancel={onClose}
> >
<form className="grafnode-form" onSubmit={formik.handleSubmit}> <form className="grafnode-form" onSubmit={formik.handleSubmit}>
<div> <div>

View File

@ -80,7 +80,16 @@ export const collectionsSlice = createSlice({
const collection = findCollectionByUid(state.collections, action.payload.collectionUid); const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
if(collection) { if(collection) {
collection.items.push(action.payload.item); if(!action.payload.currentItemUid) {
collection.items.push(action.payload.item);
} else {
const item = findItemInCollection(collection, action.payload.currentItemUid);
if(item) {
item.items = item.items || [];
item.items.push(action.payload.item);
}
}
addDepth(collection.items); addDepth(collection.items);
} }
}, },
@ -109,6 +118,17 @@ export const collectionsSlice = createSlice({
collection.collapsed = !collection.collapsed; collection.collapsed = !collection.collapsed;
} }
}, },
collectionFolderClicked: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
if(collection) {
const item = findItemInCollection(collection, action.payload.itemUid);
if(item && item.type === 'folder') {
item.collapsed = !item.collapsed;
}
}
},
requestUrlChanged: (state, action) => { requestUrlChanged: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid); const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
@ -137,6 +157,7 @@ export const {
_deleteItem, _deleteItem,
_renameItem, _renameItem,
collectionClicked, collectionClicked,
collectionFolderClicked,
requestUrlChanged, requestUrlChanged,
} = collectionsSlice.actions; } = collectionsSlice.actions;
@ -220,7 +241,7 @@ export const newFolder = (folderName, collectionUid) => (dispatch, getState) =>
} }
}; };
export const newHttpRequest = (requestName, collectionUid) => (dispatch, getState) => { export const newHttpRequest = (requestName, collectionUid, itemUid) => (dispatch, getState) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const state = getState(); const state = getState();
const collection = findCollectionByUid(state.collections.collections, collectionUid); const collection = findCollectionByUid(state.collections.collections, collectionUid);
@ -239,13 +260,22 @@ export const newHttpRequest = (requestName, collectionUid) => (dispatch, getStat
body: null body: null
} }
}; };
collectionCopy.items.push(item); 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); const collectionToSave = transformCollectionToSaveToIdb(collectionCopy);
saveCollectionToIdb(window.__idb, collectionToSave) saveCollectionToIdb(window.__idb, collectionToSave)
.then(() => { .then(() => {
Promise.resolve(dispatch(_newRequest({ Promise.resolve(dispatch(_newRequest({
item: item, item: item,
currentItemUid: itemUid,
collectionUid: collectionUid collectionUid: collectionUid
}))) })))
.then((val) => resolve(val)) .then((val) => resolve(val))

View File

@ -30,7 +30,6 @@ html, body {
font-kerning: none; font-kerning: none;
text-rendering: optimizeSpeed; text-rendering: optimizeSpeed;
letter-spacing: normal; letter-spacing: normal;
/* font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, "Apple Color Emoji", Arial, sans-serif, "Segoe UI Emoji", "Segoe UI Symbol"; */
font-family: Inter, sans-serif !important; font-family: Inter, sans-serif !important;
} }