mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-25 01:14:23 +01:00
feat: Add Folder to Collection
This commit is contained in:
parent
84e675dec4
commit
33ff9e603b
@ -1,15 +1,22 @@
|
||||
import React, { useRef, forwardRef } from 'react';
|
||||
import range from 'lodash/range';
|
||||
import get from 'lodash/get';
|
||||
import actions from 'providers/Store/actions'
|
||||
import { useStore } from 'providers/Store';
|
||||
import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||
import classnames from 'classnames';
|
||||
import Dropdown from '../../../../Dropdown';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const CollectionItem = ({item, collectionId, actions, dispatch, activeRequestTabId}) => {
|
||||
const dropdownTippyRef = useRef();
|
||||
const CollectionItem = ({item, collectionId}) => {
|
||||
const [store, storeDispatch] = useStore();
|
||||
|
||||
const {
|
||||
activeRequestTabId
|
||||
} = store;
|
||||
|
||||
const dropdownTippyRef = useRef();
|
||||
const MenuIcon = forwardRef((props, ref) => {
|
||||
return (
|
||||
<div ref={ref}>
|
||||
@ -32,7 +39,7 @@ const CollectionItem = ({item, collectionId, actions, dispatch, activeRequestTab
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
storeDispatch({
|
||||
type: actions.SIDEBAR_COLLECTION_ITEM_CLICK,
|
||||
itemId: item.id,
|
||||
collectionId: collectionId
|
||||
@ -40,7 +47,7 @@ const CollectionItem = ({item, collectionId, actions, dispatch, activeRequestTab
|
||||
};
|
||||
|
||||
const addRequest = () => {
|
||||
dispatch({
|
||||
storeDispatch({
|
||||
type: actions.ADD_REQUEST,
|
||||
itemId: item.id,
|
||||
collectionId: collectionId
|
||||
@ -48,7 +55,6 @@ const CollectionItem = ({item, collectionId, actions, dispatch, activeRequestTab
|
||||
};
|
||||
|
||||
let indents = range(item.depth);
|
||||
|
||||
const onDropdownCreate = (ref) => dropdownTippyRef.current = ref;
|
||||
|
||||
return (
|
||||
@ -121,9 +127,6 @@ const CollectionItem = ({item, collectionId, actions, dispatch, activeRequestTab
|
||||
key={i.id}
|
||||
item={i}
|
||||
collectionId={collectionId}
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
activeRequestTabId={activeRequestTabId}
|
||||
/>
|
||||
}) : null}
|
||||
</div>
|
||||
|
@ -29,6 +29,12 @@ const Wrapper = styled.div`
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
||||
div.tippy-box {
|
||||
position: relative;
|
||||
top: -0.625rem;
|
||||
font-weight: 400;
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
|
@ -1,14 +1,20 @@
|
||||
import React, { forwardRef, useRef } from 'react';
|
||||
import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||
import CollectionItem from './CollectionItem';
|
||||
import Dropdown from '../../../Dropdown';
|
||||
import get from 'lodash/get';
|
||||
import classnames from 'classnames';
|
||||
import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import actions from 'providers/Store/actions'
|
||||
import { useStore } from 'providers/Store';
|
||||
import CollectionItem from './CollectionItem';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const Collection = ({collection, actions, dispatch, activeRequestTabId}) => {
|
||||
const envDropdownTippyRef = useRef();
|
||||
const Collection = ({collection}) => {
|
||||
const [store, storeDispatch] = useStore();
|
||||
|
||||
const {
|
||||
activeRequestTabId
|
||||
} = store;
|
||||
|
||||
const menuDropdownTippyRef = useRef();
|
||||
const onMenuDropdownCreate = (ref) => menuDropdownTippyRef.current = ref;
|
||||
@ -25,22 +31,31 @@ const Collection = ({collection, actions, dispatch, activeRequestTabId}) => {
|
||||
});
|
||||
|
||||
const handleClick = (event) => {
|
||||
let envTippyEl = get(envDropdownTippyRef, 'current.reference');
|
||||
let envTippyEl = get(menuDropdownTippyRef, 'current.reference');
|
||||
if(envTippyEl && envTippyEl.contains && envTippyEl.contains(event.target)) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
storeDispatch({
|
||||
type: actions.SIDEBAR_COLLECTION_CLICK,
|
||||
id: collection.id
|
||||
collectionUid: collection.uid
|
||||
});
|
||||
};
|
||||
|
||||
const addFolder = () => {
|
||||
storeDispatch({
|
||||
type: actions.SIDEBAR_COLLECTION_ADD_FOLDER,
|
||||
collectionUid: collection.uid
|
||||
});
|
||||
};
|
||||
|
||||
const collectionItems = get(collection, 'current.items');
|
||||
|
||||
return (
|
||||
<StyledWrapper className="flex flex-col">
|
||||
<div className="flex py-1 collection-name items-center" onClick={handleClick}>
|
||||
<IconChevronRight size={16} strokeWidth={2} className={iconClassName} style={{width:16, color: 'rgb(160 160 160)'}}/>
|
||||
<span className="ml-1">{collection.name}</span>
|
||||
<span className="ml-1">{collection.current.name}</span>
|
||||
<div className="collection-actions">
|
||||
<Dropdown onCreate={onMenuDropdownCreate} icon={<MenuIcon />} placement='bottom-start'>
|
||||
<div>
|
||||
@ -53,6 +68,7 @@ const Collection = ({collection, actions, dispatch, activeRequestTabId}) => {
|
||||
<div>
|
||||
<div className="dropdown-item" onClick={(e) => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
addFolder();
|
||||
}}>
|
||||
Add Folder
|
||||
</div>
|
||||
@ -64,13 +80,13 @@ const Collection = ({collection, actions, dispatch, activeRequestTabId}) => {
|
||||
<div>
|
||||
{collection.collapsed ? (
|
||||
<div>
|
||||
{collection.items && collection.items.length ? collection.items.map((i) => {
|
||||
{collectionItems && collectionItems.length ? collectionItems.map((i) => {
|
||||
return <CollectionItem
|
||||
key={i.name}
|
||||
key={i.uid}
|
||||
item={i}
|
||||
collectionId={collection.id}
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
dispatch={storeDispatch}
|
||||
activeRequestTabId={activeRequestTabId}
|
||||
/>
|
||||
}) : null}
|
||||
|
@ -7,7 +7,7 @@ const Collections = ({collections, actions, dispatch, activeRequestTabId}) => {
|
||||
{collections && collections.length ? collections.map((c) => {
|
||||
return <Collection
|
||||
collection={c}
|
||||
key={c.id}
|
||||
key={c.uid}
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
activeRequestTabId={activeRequestTabId}
|
||||
|
@ -47,11 +47,13 @@ const TitleBar = ({dispatch, actions}) => {
|
||||
uid: collectionUid,
|
||||
base: null,
|
||||
current: {
|
||||
id: collectionUid,
|
||||
uid: collectionUid,
|
||||
name: values.collectionName,
|
||||
items: []
|
||||
},
|
||||
requestSync: true
|
||||
userId: null,
|
||||
hasChangedSinceLastSync: false,
|
||||
disableSync: true
|
||||
};
|
||||
|
||||
saveCollectionToIdb(store.idbConnection, newCollection)
|
||||
|
@ -1,5 +1,7 @@
|
||||
const SIDEBAR_COLLECTION_CLICK = "SIDEBAR_COLLECTION_CLICK";
|
||||
const SIDEBAR_COLLECTION_ITEM_CLICK = "SIDEBAR_COLLECTION_ITEM_CLICK";
|
||||
const SIDEBAR_COLLECTION_ADD_FOLDER = "SIDEBAR_COLLECTION_ADD_FOLDER";
|
||||
const LOAD_COLLECTIONS_FROM_IDB = "LOAD_COLLECTIONS_FROM_IDB";
|
||||
const COLLECTION_CREATE = "COLLECTION_CREATE";
|
||||
const REQUEST_TAB_CLICK = "REQUEST_TAB_CLICK";
|
||||
const REQUEST_TAB_CLOSE = "REQUEST_TAB_CLOSE";
|
||||
@ -16,6 +18,8 @@ const IDB_CONNECTION_READY = "IDB_CONNECTION_READY";
|
||||
export default {
|
||||
SIDEBAR_COLLECTION_CLICK,
|
||||
SIDEBAR_COLLECTION_ITEM_CLICK,
|
||||
SIDEBAR_COLLECTION_ADD_FOLDER,
|
||||
LOAD_COLLECTIONS_FROM_IDB,
|
||||
COLLECTION_CREATE,
|
||||
REQUEST_TAB_CLICK,
|
||||
REQUEST_TAB_CLOSE,
|
||||
|
@ -13,7 +13,7 @@ export const saveCollectionToIdb = (connection, collection) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getCollectionsFromIdb = (connection, domain) => {
|
||||
export const getCollectionsFromIdb = (connection) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
connection
|
||||
.then((db) => {
|
||||
|
@ -3,6 +3,8 @@ import reducer from './reducer';
|
||||
import useIdb from './useIdb';
|
||||
import { sendRequest } from '../../network';
|
||||
import { nanoid } from 'nanoid';
|
||||
import actions from './actions';
|
||||
import {getCollectionsFromIdb} from './idb';
|
||||
|
||||
export const StoreContext = createContext();
|
||||
|
||||
@ -112,7 +114,7 @@ const collection2 = {
|
||||
|
||||
const initialState = {
|
||||
idbConnection: null,
|
||||
collections: [collection, collection2],
|
||||
collections: [],
|
||||
activeRequestTabId: null,
|
||||
requestQueuedToSend: null,
|
||||
requestTabs: []
|
||||
@ -120,6 +122,10 @@ const initialState = {
|
||||
|
||||
export const StoreProvider = props => {
|
||||
const [state, dispatch] = useReducer(reducer, initialState);
|
||||
|
||||
const {
|
||||
idbConnection
|
||||
} = state;
|
||||
|
||||
useEffect(() => {
|
||||
if(state.requestQueuedToSend) {
|
||||
@ -132,6 +138,19 @@ export const StoreProvider = props => {
|
||||
}
|
||||
}, [state.requestQueuedToSend]);
|
||||
|
||||
useEffect(() => {
|
||||
if(idbConnection) {
|
||||
getCollectionsFromIdb(idbConnection)
|
||||
.then((collections) => {
|
||||
dispatch({
|
||||
type: actions.LOAD_COLLECTIONS_FROM_IDB,
|
||||
collections: collections
|
||||
});
|
||||
})
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
}, [idbConnection]);
|
||||
|
||||
useIdb(dispatch);
|
||||
|
||||
return <StoreContext.Provider value={[state, dispatch]} {...props} />;
|
||||
|
@ -21,6 +21,13 @@ const reducer = (state, action) => {
|
||||
});
|
||||
}
|
||||
|
||||
case actions.LOAD_COLLECTIONS_FROM_IDB: {
|
||||
return produce(state, (draft) => {
|
||||
console.log(action.collections);
|
||||
draft.collections = action.collections;
|
||||
});
|
||||
}
|
||||
|
||||
case actions.SIDEBAR_COLLECTION_CLICK: {
|
||||
return produce(state, (draft) => {
|
||||
const collection = find(draft.collections, (c) => c.id === action.id);
|
||||
@ -61,6 +68,22 @@ const reducer = (state, action) => {
|
||||
});
|
||||
}
|
||||
|
||||
case actions.SIDEBAR_COLLECTION_ADD_FOLDER: {
|
||||
return produce(state, (draft) => {
|
||||
const collection = find(draft.collections, (c) => c.uid === action.collectionUid);
|
||||
console.log(collection.current.items);
|
||||
|
||||
if(collection) {
|
||||
collection.current.items.push({
|
||||
"uid": nanoid(),
|
||||
"name": "New Folder",
|
||||
"depth": 1,
|
||||
"items": []
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
case actions.COLLECTION_CREATE: {
|
||||
return produce(state, (draft) => {
|
||||
// todo: collection names must be unique across a user account
|
||||
|
Loading…
Reference in New Issue
Block a user