forked from extern/bruno
refactor: redux migration - request tabs
This commit is contained in:
parent
c8e679b7e0
commit
914927bbfd
@ -3,24 +3,22 @@ import find from 'lodash/find';
|
|||||||
import filter from 'lodash/filter';
|
import filter from 'lodash/filter';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { IconHome2 } from '@tabler/icons';
|
import { IconHome2 } from '@tabler/icons';
|
||||||
import { useStore } from 'providers/Store';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import actions from 'providers/Store/actions';
|
import { focusTab, closeTab } from 'providers/ReduxStore/slices/tabs';
|
||||||
|
import { findItemInCollection } from 'utils/collections';
|
||||||
import CollectionToolBar from './CollectionToolBar';
|
import CollectionToolBar from './CollectionToolBar';
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const RequestTabs = () => {
|
const RequestTabs = () => {
|
||||||
const [store, storeDispatch] = useStore();
|
const tabs = useSelector((state) => state.tabs.tabs);
|
||||||
|
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
||||||
const {
|
const collections = useSelector((state) => state.collections.collections);
|
||||||
collections,
|
const dispatch = useDispatch();
|
||||||
requestTabs,
|
|
||||||
activeRequestTabUid
|
|
||||||
} = store;
|
|
||||||
|
|
||||||
const getTabClassname = (tab, index) => {
|
const getTabClassname = (tab, index) => {
|
||||||
return classnames("request-tab select-none", {
|
return classnames("request-tab select-none", {
|
||||||
'active': tab.uid === activeRequestTabUid,
|
'active': tab.uid === activeTabUid,
|
||||||
'last-tab': requestTabs && requestTabs.length && (index === requestTabs.length - 1)
|
'last-tab': tabs && tabs.length && (index === tabs.length - 1)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -41,33 +39,27 @@ const RequestTabs = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleClick = (tab) => {
|
const handleClick = (tab) => {
|
||||||
storeDispatch({
|
dispatch(focusTab({
|
||||||
type: actions.REQUEST_TAB_CLICK,
|
uid: tab.uid
|
||||||
requestTab: tab
|
}));
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCloseClick = (event, tab) => {
|
const handleCloseClick = (event, tab) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
storeDispatch({
|
dispatch(closeTab(tab.uid))
|
||||||
type: actions.REQUEST_TAB_CLOSE,
|
|
||||||
requestTab: tab
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const createNewTab = () => {
|
const createNewTab = () => {
|
||||||
storeDispatch({
|
// todo
|
||||||
type: actions.ADD_NEW_HTTP_REQUEST
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!activeRequestTabUid) {
|
if(!activeTabUid) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeRequestTab = find(requestTabs, (t) => t.uid === activeRequestTabUid);
|
const activeTab = find(tabs, (t) => t.uid === activeTabUid);
|
||||||
if(!activeRequestTab) {
|
if(!activeTab) {
|
||||||
return (
|
return (
|
||||||
<StyledWrapper>
|
<StyledWrapper>
|
||||||
Something went wrong!
|
Something went wrong!
|
||||||
@ -75,8 +67,19 @@ const RequestTabs = () => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeCollection = find(collections, (c) => c.uid === activeRequestTab.collectionUid);
|
const activeCollection = find(collections, (c) => c.uid === activeTab.collectionUid);
|
||||||
const collectionRequestTabs = filter(requestTabs, (t) => t.collectionUid === activeRequestTab.collectionUid);
|
const collectionRequestTabs = filter(tabs, (t) => t.collectionUid === activeTab.collectionUid);
|
||||||
|
const item = findItemInCollection(activeCollection, activeTab.uid);
|
||||||
|
|
||||||
|
const getRequestName = (tab) => {
|
||||||
|
const item = findItemInCollection(activeCollection, tab.uid);
|
||||||
|
return item.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getRequestMethod = (tab) => {
|
||||||
|
const item = findItemInCollection(activeCollection, tab.uid);
|
||||||
|
return item.request.name;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledWrapper>
|
<StyledWrapper>
|
||||||
@ -90,15 +93,15 @@ const RequestTabs = () => {
|
|||||||
<IconHome2 size={18} strokeWidth={1.5}/>
|
<IconHome2 size={18} strokeWidth={1.5}/>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
{collectionRequestTabs && collectionRequestTabs.length ? collectionRequestTabs.map((rt, index) => {
|
{collectionRequestTabs && collectionRequestTabs.length ? collectionRequestTabs.map((tab, index) => {
|
||||||
return <li key={rt.uid} className={getTabClassname(rt, index)} role="tab" onClick={() => handleClick(rt)}>
|
return <li key={tab.uid} className={getTabClassname(tab, index)} role="tab" onClick={() => handleClick(tab)}>
|
||||||
<div className="flex items-center justify-between tab-container px-1">
|
<div className="flex items-center justify-between tab-container px-1">
|
||||||
<div className="flex items-center tab-label pl-2">
|
<div className="flex items-center tab-label pl-2">
|
||||||
<span className="tab-method" style={{color: getMethodColor(rt.method)}}>{rt.method}</span>
|
<span className="tab-method" style={{color: getMethodColor(getRequestMethod(tab))}}>{getRequestMethod(tab)}</span>
|
||||||
<span className="text-gray-700 ml-1 tab-name">{rt.name}</span>
|
<span className="text-gray-700 ml-1 tab-name">{getRequestName(tab)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex px-2 close-icon-container" onClick={(e) => handleCloseClick(e, rt)}>
|
<div className="flex px-2 close-icon-container" onClick={(e) => handleCloseClick(e, tab)}>
|
||||||
{!rt.hasChanges ? (
|
{!tab.hasChanges ? (
|
||||||
<svg focusable="false"xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" className="close-icon">
|
<svg focusable="false"xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512" className="close-icon">
|
||||||
<path fill="currentColor" d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"></path>
|
<path fill="currentColor" d="M207.6 256l107.72-107.72c6.23-6.23 6.23-16.34 0-22.58l-25.03-25.03c-6.23-6.23-16.34-6.23-22.58 0L160 208.4 52.28 100.68c-6.23-6.23-16.34-6.23-22.58 0L4.68 125.7c-6.23 6.23-6.23 16.34 0 22.58L112.4 256 4.68 363.72c-6.23 6.23-6.23 16.34 0 22.58l25.03 25.03c6.23 6.23 16.34 6.23 22.58 0L160 303.6l107.72 107.72c6.23 6.23 16.34 6.23 22.58 0l25.03-25.03c6.23-6.23 6.23-16.34 0-22.58L207.6 256z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -1,21 +1,20 @@
|
|||||||
import React, { useRef, forwardRef } from 'react';
|
import React, { useRef, forwardRef } from 'react';
|
||||||
import range from 'lodash/range';
|
import range from 'lodash/range';
|
||||||
import get from 'lodash/get';
|
import get from 'lodash/get';
|
||||||
import actions from 'providers/Store/actions'
|
|
||||||
import { useStore } from 'providers/Store';
|
|
||||||
import { IconChevronRight, IconDots } from '@tabler/icons';
|
import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
|
import { addTab, focusTab } from 'providers/ReduxStore/slices/tabs';
|
||||||
|
import { isItemARequest, itemIsOpenedInTabs } from 'utils/tabs';
|
||||||
import Dropdown from 'components/Dropdown';
|
import Dropdown from 'components/Dropdown';
|
||||||
import RequestMethod from './RequestMethod';
|
import RequestMethod from './RequestMethod';
|
||||||
|
|
||||||
import StyledWrapper from './StyledWrapper';
|
import StyledWrapper from './StyledWrapper';
|
||||||
|
|
||||||
const CollectionItem = ({item, collectionUid}) => {
|
const CollectionItem = ({item, collection}) => {
|
||||||
const [store, storeDispatch] = useStore();
|
const tabs = useSelector((state) => state.tabs.tabs);
|
||||||
|
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
||||||
const {
|
const dispatch = useDispatch();
|
||||||
activeRequestTabUid
|
|
||||||
} = store;
|
|
||||||
|
|
||||||
const dropdownTippyRef = useRef();
|
const dropdownTippyRef = useRef();
|
||||||
const MenuIcon = forwardRef((props, ref) => {
|
const MenuIcon = forwardRef((props, ref) => {
|
||||||
@ -31,7 +30,7 @@ const CollectionItem = ({item, collectionUid}) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const itemRowClassName = classnames('flex collection-item-name items-center', {
|
const itemRowClassName = classnames('flex collection-item-name items-center', {
|
||||||
'item-focused-in-tab': item.uid == activeRequestTabUid
|
'item-focused-in-tab': item.uid == activeTabUid
|
||||||
});
|
});
|
||||||
|
|
||||||
const handleClick = (event) => {
|
const handleClick = (event) => {
|
||||||
@ -40,19 +39,20 @@ const CollectionItem = ({item, collectionUid}) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
storeDispatch({
|
if(isItemARequest(item)) {
|
||||||
type: actions.SIDEBAR_COLLECTION_ITEM_CLICK,
|
if(itemIsOpenedInTabs(item, tabs)) {
|
||||||
itemUid: item.uid,
|
dispatch(focusTab({
|
||||||
collectionUid: collectionUid
|
uid: item.uid
|
||||||
});
|
}));
|
||||||
};
|
} else {
|
||||||
|
dispatch(addTab({
|
||||||
const addRequest = () => {
|
uid: item.uid,
|
||||||
storeDispatch({
|
collectionUid: collection.uid
|
||||||
type: actions.ADD_REQUEST,
|
}));
|
||||||
itemUid: item.uid,
|
}
|
||||||
collectionUid: collectionUid
|
} else {
|
||||||
});
|
// todo for folder: must expand folder : item.collapsed = !item.collapsed;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let indents = range(item.depth);
|
let indents = range(item.depth);
|
||||||
@ -100,7 +100,6 @@ const CollectionItem = ({item, collectionUid}) => {
|
|||||||
<Dropdown onCreate={onDropdownCreate} icon={<MenuIcon />} placement='bottom-start'>
|
<Dropdown onCreate={onDropdownCreate} icon={<MenuIcon />} placement='bottom-start'>
|
||||||
<div className="dropdown-item" onClick={(e) => {
|
<div className="dropdown-item" onClick={(e) => {
|
||||||
dropdownTippyRef.current.hide();
|
dropdownTippyRef.current.hide();
|
||||||
addRequest();
|
|
||||||
}}>
|
}}>
|
||||||
New Request
|
New Request
|
||||||
</div>
|
</div>
|
||||||
@ -130,7 +129,7 @@ const CollectionItem = ({item, collectionUid}) => {
|
|||||||
return <CollectionItem
|
return <CollectionItem
|
||||||
key={i.uid}
|
key={i.uid}
|
||||||
item={i}
|
item={i}
|
||||||
collectionUid={collectionUid}
|
collection={collection}
|
||||||
/>
|
/>
|
||||||
}) : null}
|
}) : null}
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,7 +90,7 @@ const Collection = ({collection}) => {
|
|||||||
return <CollectionItem
|
return <CollectionItem
|
||||||
key={i.uid}
|
key={i.uid}
|
||||||
item={i}
|
item={i}
|
||||||
collectionUid={collection.uid}
|
collection={collection}
|
||||||
/>
|
/>
|
||||||
}) : null}
|
}) : null}
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
import { configureStore } from '@reduxjs/toolkit';
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
import appReducer from './slices/app';
|
import appReducer from './slices/app';
|
||||||
import collectionsReducer from './slices/collections';
|
import collectionsReducer from './slices/collections';
|
||||||
|
import tabsReducer from './slices/tabs';
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: {
|
reducer: {
|
||||||
app: appReducer,
|
app: appReducer,
|
||||||
collections: collectionsReducer
|
collections: collectionsReducer,
|
||||||
|
tabs: tabsReducer
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ const initialState = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const collectionsSlice = createSlice({
|
export const collectionsSlice = createSlice({
|
||||||
name: 'app',
|
name: 'collections',
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
_loadCollections: (state, action) => {
|
_loadCollections: (state, action) => {
|
||||||
|
45
renderer/providers/ReduxStore/slices/tabs.js
Normal file
45
renderer/providers/ReduxStore/slices/tabs.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import filter from 'lodash/filter';
|
||||||
|
import last from 'lodash/last';
|
||||||
|
import { createSlice } from '@reduxjs/toolkit'
|
||||||
|
|
||||||
|
// todo: errors should be tracked in each slice and displayed as toasts
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
tabs: [],
|
||||||
|
activeTabUid: null
|
||||||
|
};
|
||||||
|
|
||||||
|
export const tabsSlice = createSlice({
|
||||||
|
name: 'tabs',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
addTab: (state, action) => {
|
||||||
|
state.tabs.push({
|
||||||
|
uid: action.payload.uid,
|
||||||
|
collectionUid: action.payload.collectionUid
|
||||||
|
});
|
||||||
|
state.activeTabUid = action.payload.uid;
|
||||||
|
},
|
||||||
|
focusTab: (state, action) => {
|
||||||
|
state.activeTabUid = action.payload.uid;
|
||||||
|
},
|
||||||
|
closeTab: (state, action) => {
|
||||||
|
state.tabs = filter(state.tabs, (t) => t.uid !== action.payload);
|
||||||
|
|
||||||
|
if(state.tabs && state.tabs.length) {
|
||||||
|
// todo: closing tab needs to focus on the right adjacent tab
|
||||||
|
state.activeTabUid = last(state.tabs).uid;
|
||||||
|
} else {
|
||||||
|
state.activeTabUid = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {
|
||||||
|
addTab,
|
||||||
|
focusTab,
|
||||||
|
closeTab
|
||||||
|
} = tabsSlice.actions;
|
||||||
|
|
||||||
|
export default tabsSlice.reducer;
|
@ -1,16 +1,11 @@
|
|||||||
const SIDEBAR_COLLECTION_ITEM_CLICK = "SIDEBAR_COLLECTION_ITEM_CLICK";
|
|
||||||
const SIDEBAR_COLLECTION_NEW_FOLDER = "SIDEBAR_COLLECTION_NEW_FOLDER";
|
const SIDEBAR_COLLECTION_NEW_FOLDER = "SIDEBAR_COLLECTION_NEW_FOLDER";
|
||||||
const SIDEBAR_COLLECTION_NEW_REQUEST = "SIDEBAR_COLLECTION_NEW_REQUEST";
|
const SIDEBAR_COLLECTION_NEW_REQUEST = "SIDEBAR_COLLECTION_NEW_REQUEST";
|
||||||
const LOAD_COLLECTIONS_FROM_IDB = "LOAD_COLLECTIONS_FROM_IDB";
|
const LOAD_COLLECTIONS_FROM_IDB = "LOAD_COLLECTIONS_FROM_IDB";
|
||||||
const REQUEST_TAB_CLICK = "REQUEST_TAB_CLICK";
|
|
||||||
const REQUEST_TAB_CLOSE = "REQUEST_TAB_CLOSE";
|
|
||||||
const REQUEST_URL_CHANGED = "REQUEST_URL_CHANGED";
|
const REQUEST_URL_CHANGED = "REQUEST_URL_CHANGED";
|
||||||
const REQUEST_GQL_QUERY_CHANGED = "REQUEST_GQL_QUERY_CHANGED";
|
const REQUEST_GQL_QUERY_CHANGED = "REQUEST_GQL_QUERY_CHANGED";
|
||||||
const RESPONSE_RECEIVED = "RESPONSE_RECEIVED";
|
const RESPONSE_RECEIVED = "RESPONSE_RECEIVED";
|
||||||
const SEND_REQUEST = "SEND_REQUEST";
|
const SEND_REQUEST = "SEND_REQUEST";
|
||||||
const SENDING_REQUEST = "SENDING_REQUEST";
|
const SENDING_REQUEST = "SENDING_REQUEST";
|
||||||
const ADD_REQUEST = "ADD_REQUEST";
|
|
||||||
const ADD_NEW_HTTP_REQUEST = "ADD_NEW_HTTP_REQUEST";
|
|
||||||
const ADD_NEW_GQL_REQUEST = "ADD_NEW_GQL_REQUEST";
|
const ADD_NEW_GQL_REQUEST = "ADD_NEW_GQL_REQUEST";
|
||||||
const IDB_CONNECTION_READY = "IDB_CONNECTION_READY";
|
const IDB_CONNECTION_READY = "IDB_CONNECTION_READY";
|
||||||
const IDB_COLLECTIONS_SYNC_STARTED = "IDB_COLLECTIONS_SYNC_STARTED";
|
const IDB_COLLECTIONS_SYNC_STARTED = "IDB_COLLECTIONS_SYNC_STARTED";
|
||||||
@ -18,19 +13,14 @@ const IDB_COLLECTIONS_SYNC_ERROR = "IDB_COLLECTIONS_SYNC_ERROR";
|
|||||||
const HOTKEY_SAVE = "HOTKEY_SAVE";
|
const HOTKEY_SAVE = "HOTKEY_SAVE";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
SIDEBAR_COLLECTION_ITEM_CLICK,
|
|
||||||
SIDEBAR_COLLECTION_NEW_FOLDER,
|
SIDEBAR_COLLECTION_NEW_FOLDER,
|
||||||
SIDEBAR_COLLECTION_NEW_REQUEST,
|
SIDEBAR_COLLECTION_NEW_REQUEST,
|
||||||
LOAD_COLLECTIONS_FROM_IDB,
|
LOAD_COLLECTIONS_FROM_IDB,
|
||||||
REQUEST_TAB_CLICK,
|
|
||||||
REQUEST_TAB_CLOSE,
|
|
||||||
REQUEST_URL_CHANGED,
|
REQUEST_URL_CHANGED,
|
||||||
REQUEST_GQL_QUERY_CHANGED,
|
REQUEST_GQL_QUERY_CHANGED,
|
||||||
RESPONSE_RECEIVED,
|
RESPONSE_RECEIVED,
|
||||||
SEND_REQUEST,
|
SEND_REQUEST,
|
||||||
SENDING_REQUEST,
|
SENDING_REQUEST,
|
||||||
ADD_REQUEST,
|
|
||||||
ADD_NEW_HTTP_REQUEST,
|
|
||||||
ADD_NEW_GQL_REQUEST,
|
ADD_NEW_GQL_REQUEST,
|
||||||
IDB_CONNECTION_READY,
|
IDB_CONNECTION_READY,
|
||||||
IDB_COLLECTIONS_SYNC_STARTED,
|
IDB_COLLECTIONS_SYNC_STARTED,
|
||||||
|
@ -2,14 +2,10 @@ import produce from 'immer';
|
|||||||
import {nanoid} from 'nanoid';
|
import {nanoid} from 'nanoid';
|
||||||
import union from 'lodash/union';
|
import union from 'lodash/union';
|
||||||
import find from 'lodash/find';
|
import find from 'lodash/find';
|
||||||
import filter from 'lodash/filter';
|
|
||||||
import last from 'lodash/last';
|
|
||||||
import actions from './actions';
|
import actions from './actions';
|
||||||
import {
|
import {
|
||||||
flattenItems,
|
flattenItems,
|
||||||
findItem,
|
findItem,
|
||||||
isItemARequest,
|
|
||||||
itemIsOpenedInTabs,
|
|
||||||
cloneItem,
|
cloneItem,
|
||||||
updateRequestTabAsChanged,
|
updateRequestTabAsChanged,
|
||||||
findCollectionByUid
|
findCollectionByUid
|
||||||
@ -41,36 +37,6 @@ const reducer = (state, action) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
case actions.SIDEBAR_COLLECTION_ITEM_CLICK: {
|
|
||||||
return produce(state, (draft) => {
|
|
||||||
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
|
||||||
|
|
||||||
if(collection) {
|
|
||||||
let flattenedItems = flattenItems(collection.items);
|
|
||||||
let item = findItem(flattenedItems, action.itemUid);
|
|
||||||
|
|
||||||
if(item) {
|
|
||||||
item.collapsed = !item.collapsed;
|
|
||||||
|
|
||||||
if(isItemARequest(item)) {
|
|
||||||
if(itemIsOpenedInTabs(item, draft.requestTabs)) {
|
|
||||||
draft.activeRequestTabUid = item.uid;
|
|
||||||
} else {
|
|
||||||
draft.requestTabs.push({
|
|
||||||
uid: item.uid,
|
|
||||||
name: item.name,
|
|
||||||
method: item.request.method,
|
|
||||||
collectionUid: collection.uid,
|
|
||||||
hasChanges: false
|
|
||||||
});
|
|
||||||
draft.activeRequestTabUid = item.uid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case actions.SIDEBAR_COLLECTION_NEW_REQUEST: {
|
case actions.SIDEBAR_COLLECTION_NEW_REQUEST: {
|
||||||
return produce(state, (draft) => {
|
return produce(state, (draft) => {
|
||||||
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
||||||
@ -122,12 +88,6 @@ const reducer = (state, action) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
case actions.REQUEST_TAB_CLICK: {
|
|
||||||
return produce(state, (draft) => {
|
|
||||||
draft.activeRequestTabUid = action.requestTab.uid;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case actions.REQUEST_URL_CHANGED: {
|
case actions.REQUEST_URL_CHANGED: {
|
||||||
return produce(state, (draft) => {
|
return produce(state, (draft) => {
|
||||||
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
||||||
@ -162,24 +122,6 @@ const reducer = (state, action) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
case actions.ADD_NEW_HTTP_REQUEST: {
|
|
||||||
return produce(state, (draft) => {
|
|
||||||
const uid = nanoid();
|
|
||||||
draft.requestTabs.push({
|
|
||||||
uid: uid,
|
|
||||||
name: 'New Tab',
|
|
||||||
type: 'http-request',
|
|
||||||
request: {
|
|
||||||
method: 'GET',
|
|
||||||
url: 'https://api.spacex.land/graphql/',
|
|
||||||
body: {}
|
|
||||||
},
|
|
||||||
collectionUid: null
|
|
||||||
});
|
|
||||||
draft.activeRequestTabUid = uid;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case actions.ADD_NEW_GQL_REQUEST: {
|
case actions.ADD_NEW_GQL_REQUEST: {
|
||||||
return produce(state, (draft) => {
|
return produce(state, (draft) => {
|
||||||
const uid = nanoid();
|
const uid = nanoid();
|
||||||
@ -257,62 +199,6 @@ const reducer = (state, action) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
case actions.REQUEST_TAB_CLOSE: {
|
|
||||||
return produce(state, (draft) => {
|
|
||||||
draft.requestTabs = filter(draft.requestTabs, (rt) => rt.id !== action.requestTab.id);
|
|
||||||
|
|
||||||
if(draft.requestTabs && draft.requestTabs.length) {
|
|
||||||
// todo: closing tab needs to focus on the right adjacent tab
|
|
||||||
draft.activeRequestTabUid = last(draft.requestTabs).uid;
|
|
||||||
} else {
|
|
||||||
draft.activeRequestTabUid = null;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case actions.ADD_REQUEST: {
|
|
||||||
return produce(state, (draft) => {
|
|
||||||
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
|
||||||
|
|
||||||
if(collection) {
|
|
||||||
let flattenedItems = flattenItems(collection.items);
|
|
||||||
let item = findItem(flattenedItems, action.itemId);
|
|
||||||
|
|
||||||
if(item) {
|
|
||||||
if(!isItemARequest(item)) {
|
|
||||||
let newRequest = {
|
|
||||||
"uid": nanoid(),
|
|
||||||
"depth": 2,
|
|
||||||
"name": "Capsules 2",
|
|
||||||
"type": "graphql-request",
|
|
||||||
"request": {
|
|
||||||
"url": "https://api.spacex.land/graphql/",
|
|
||||||
"method": "POST",
|
|
||||||
"headers": [],
|
|
||||||
"body": {
|
|
||||||
"mimeType": "application/graphql",
|
|
||||||
"graphql": {
|
|
||||||
"query": "{\n launchesPast(limit: 10) {\n mission_name\n launch_date_local\n launch_site {\n site_name_long\n }\n links {\n article_link\n video_link\n }\n rocket {\n rocket_name\n first_stage {\n cores {\n flight\n core {\n reuse_count\n status\n }\n }\n }\n second_stage {\n payloads {\n payload_type\n payload_mass_kg\n payload_mass_lbs\n }\n }\n }\n ships {\n name\n home_port\n image\n }\n }\n}",
|
|
||||||
"variables": ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"response": null
|
|
||||||
};
|
|
||||||
draft.activeRequestTabUid = newRequest.uid;
|
|
||||||
item.items.push(newRequest);
|
|
||||||
draft.requestTabs.push({
|
|
||||||
uid: newRequest.uid,
|
|
||||||
name: newRequest.name,
|
|
||||||
method: newRequest.request.method,
|
|
||||||
collectionUid: collection.id
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
case actions.HOTKEY_SAVE: {
|
case actions.HOTKEY_SAVE: {
|
||||||
return produce(state, (draft) => {
|
return produce(state, (draft) => {
|
||||||
if(!draft.activeRequestTabUid) {
|
if(!draft.activeRequestTabUid) {
|
||||||
|
@ -1,5 +1,34 @@
|
|||||||
|
import each from 'lodash/each';
|
||||||
import find from 'lodash/find';
|
import find from 'lodash/find';
|
||||||
|
|
||||||
|
export const flattenItems = (items = []) => {
|
||||||
|
const flattenedItems = [];
|
||||||
|
|
||||||
|
const flatten = (itms, flattened) => {
|
||||||
|
each(itms, (i) => {
|
||||||
|
flattened.push(i);
|
||||||
|
|
||||||
|
if(i.items && i.items.length) {
|
||||||
|
flatten(i.items, flattened);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
flatten(items, flattenedItems);
|
||||||
|
|
||||||
|
return flattenedItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const findItem = (items = [], itemUid) => {
|
||||||
|
return find(items, (i) => i.uid === itemUid);
|
||||||
|
};
|
||||||
|
|
||||||
export const findCollectionByUid = (collections, collectionUid) => {
|
export const findCollectionByUid = (collections, collectionUid) => {
|
||||||
return find(collections, (c) => c.uid === collectionUid);
|
return find(collections, (c) => c.uid === collectionUid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const findItemInCollection = (collection, itemUid) => {
|
||||||
|
let flattenedItems = flattenItems(collection.items);
|
||||||
|
|
||||||
|
return findItem(flattenedItems, itemUid);
|
||||||
|
}
|
9
renderer/utils/tabs/index.js
Normal file
9
renderer/utils/tabs/index.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import find from 'lodash/find';
|
||||||
|
|
||||||
|
export const isItemARequest = (item) => {
|
||||||
|
return item.hasOwnProperty('request');
|
||||||
|
};
|
||||||
|
|
||||||
|
export const itemIsOpenedInTabs = (item, tabs) => {
|
||||||
|
return find(tabs, (t) => t.uid === item.uid);
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user