mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-24 17:03:47 +01:00
refactor: ids -> uids + NewRequest functionality
This commit is contained in:
parent
686894e0bd
commit
92692c766a
@ -21,7 +21,7 @@ const EnvironmentSelector = () => {
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<div className="flex items-center cursor-pointer environment-selector pr-3">
|
||||
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement='bottom-start'>
|
||||
<Dropdown onCreate={onDropdownCreate} icon={<Icon />} placement='bottom-end'>
|
||||
<div className="dropdown-item" onClick={() => {
|
||||
dropdownTippyRef.current.hide();
|
||||
}}>
|
||||
|
@ -1,10 +1,12 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import find from 'lodash/find';
|
||||
import QueryUrl from '../QueryUrl';
|
||||
import GraphQLRequestPane from '../GraphQLRequestPane';
|
||||
import HttpRequestPane from '../HttpRequestPane';
|
||||
import ResponsePane from '../ResponsePane';
|
||||
import Welcome from '../Welcome';
|
||||
import { useStore } from 'providers/Store';
|
||||
import actions from 'providers/Store/actions';
|
||||
import QueryUrl from 'components/QueryUrl';
|
||||
import GraphQLRequestPane from 'components/GraphQLRequestPane';
|
||||
import HttpRequestPane from 'components/HttpRequestPane';
|
||||
import ResponsePane from 'components/ResponsePane';
|
||||
import Welcome from 'components/Welcome';
|
||||
import {
|
||||
flattenItems,
|
||||
findItem
|
||||
@ -13,10 +15,17 @@ import useGraphqlSchema from '../../hooks/useGraphqlSchema';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const RequestTabPanel = ({dispatch, actions, collections, activeRequestTabId, requestTabs}) => {
|
||||
const RequestTabPanel = () => {
|
||||
if(typeof window == 'undefined') {
|
||||
return <div></div>;
|
||||
}
|
||||
const [store, storeDispatch] = useStore();
|
||||
|
||||
const {
|
||||
collections,
|
||||
requestTabs,
|
||||
activeRequestTabUid
|
||||
} = store;
|
||||
|
||||
let asideWidth = 270;
|
||||
let {
|
||||
@ -54,32 +63,32 @@ const RequestTabPanel = ({dispatch, actions, collections, activeRequestTabId, re
|
||||
}, [dragging, leftPaneWidth]);
|
||||
|
||||
const onUrlChange = (value) => {
|
||||
dispatch({
|
||||
storeDispatch({
|
||||
type: actions.REQUEST_URL_CHANGED,
|
||||
url: value,
|
||||
requestTab: focusedTab,
|
||||
collectionId: collection ? collection.id : null
|
||||
collectionUid: collection ? collection.uid : null
|
||||
});
|
||||
};
|
||||
|
||||
const onGraphqlQueryChange = (value) => {
|
||||
dispatch({
|
||||
storeDispatch({
|
||||
type: actions.REQUEST_GQL_QUERY_CHANGED,
|
||||
query: value,
|
||||
requestTab: focusedTab,
|
||||
collectionId: collection ? collection.id : null
|
||||
collectionUid: collection ? collection.uid : null
|
||||
});
|
||||
};
|
||||
|
||||
if(!activeRequestTabId) {
|
||||
if(!activeRequestTabUid) {
|
||||
return (
|
||||
<Welcome dispatch={dispatch} actions={actions}/>
|
||||
<Welcome dispatch={storeDispatch} actions={actions}/>
|
||||
);
|
||||
}
|
||||
|
||||
const focusedTab = find(requestTabs, (rt) => rt.id === activeRequestTabId);
|
||||
const focusedTab = find(requestTabs, (rt) => rt.uid === activeRequestTabUid);
|
||||
|
||||
if(!focusedTab || !focusedTab.id) {
|
||||
if(!focusedTab || !focusedTab.uid) {
|
||||
return (
|
||||
<div className="pb-4 px-4">An error occured!</div>
|
||||
);
|
||||
@ -88,19 +97,19 @@ const RequestTabPanel = ({dispatch, actions, collections, activeRequestTabId, re
|
||||
let collection;
|
||||
let item;
|
||||
|
||||
if(focusedTab.collectionId) {
|
||||
collection = find(collections, (c) => c.id === focusedTab.collectionId);
|
||||
if(focusedTab.collectionUid) {
|
||||
collection = find(collections, (c) => c.uid === focusedTab.collectionUid);
|
||||
let flattenedItems = flattenItems(collection.items);
|
||||
item = findItem(flattenedItems, activeRequestTabId);
|
||||
item = findItem(flattenedItems, activeRequestTabUid);
|
||||
} else {
|
||||
item = focusedTab;
|
||||
}
|
||||
|
||||
const runQuery = async () => {
|
||||
dispatch({
|
||||
storeDispatch({
|
||||
type: actions.SEND_REQUEST,
|
||||
requestTab: focusedTab,
|
||||
collectionId: collection ? collection.id : null
|
||||
collectionUid: collection ? collection.uid : null
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -14,12 +14,12 @@ const RequestTabs = () => {
|
||||
const {
|
||||
collections,
|
||||
requestTabs,
|
||||
activeRequestTabId
|
||||
activeRequestTabUid
|
||||
} = store;
|
||||
|
||||
const getTabClassname = (tab, index) => {
|
||||
return classnames("request-tab select-none", {
|
||||
'active': tab.id === activeRequestTabId,
|
||||
'active': tab.uid === activeRequestTabUid,
|
||||
'last-tab': requestTabs && requestTabs.length && (index === requestTabs.length - 1)
|
||||
});
|
||||
};
|
||||
@ -62,21 +62,29 @@ const RequestTabs = () => {
|
||||
});
|
||||
};
|
||||
|
||||
if(!activeRequestTabId) {
|
||||
if(!activeRequestTabUid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const activeRequestTab = find(requestTabs, (t) => t.id === activeRequestTabId);
|
||||
const activeCollection = find(collections, (c) => c.id === activeRequestTab.collectionId);
|
||||
const collectionRequestTabs = filter(requestTabs, (t) => t.collectionId === activeRequestTab.collectionId);
|
||||
console.log(activeRequestTab);
|
||||
const activeRequestTab = find(requestTabs, (t) => t.uid === activeRequestTabUid);
|
||||
console.log(requestTabs);
|
||||
if(!activeRequestTab) {
|
||||
return (
|
||||
<StyledWrapper>
|
||||
Something went wrong!
|
||||
</StyledWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const activeCollection = find(collections, (c) => c.uid === activeRequestTab.collectionUid);
|
||||
const collectionRequestTabs = filter(requestTabs, (t) => t.collectionUid === activeRequestTab.collectionUid);
|
||||
|
||||
return (
|
||||
<StyledWrapper>
|
||||
{collectionRequestTabs && collectionRequestTabs.length ? (
|
||||
<>
|
||||
<CollectionToolBar collection={activeCollection}/>
|
||||
<div className="mt-1 flex items-center">
|
||||
<div className="flex items-center">
|
||||
<ul role="tablist">
|
||||
<li className="select-none new-tab mr-1" onClick={createNewTab}>
|
||||
<div className="flex items-center home-icon-container">
|
||||
@ -84,7 +92,7 @@ const RequestTabs = () => {
|
||||
</div>
|
||||
</li>
|
||||
{collectionRequestTabs && collectionRequestTabs.length ? collectionRequestTabs.map((rt, index) => {
|
||||
return <li key={rt.id} className={getTabClassname(rt, index)} role="tab" onClick={() => handleClick(rt)}>
|
||||
return <li key={rt.uid} className={getTabClassname(rt, index)} role="tab" onClick={() => handleClick(rt)}>
|
||||
<div className="flex items-center justify-between tab-container px-1">
|
||||
<div className="flex items-center tab-label pl-2">
|
||||
<span className="tab-method" style={{color: getMethodColor(rt.method)}}>{rt.method}</span>
|
||||
|
@ -46,7 +46,7 @@ const SaveRequestButton = ({folders}) => {
|
||||
<div className="folder-list">
|
||||
{showFolders && showFolders.length ? showFolders.map((folder) => (
|
||||
<div
|
||||
key={folder.id}
|
||||
key={folder.uid}
|
||||
className="folder-name"
|
||||
onClick={() => handleFolderClick(folder)}
|
||||
>
|
||||
|
@ -9,11 +9,11 @@ import Dropdown from 'components/Dropdown';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const CollectionItem = ({item, collectionId}) => {
|
||||
const CollectionItem = ({item, collectionUid}) => {
|
||||
const [store, storeDispatch] = useStore();
|
||||
|
||||
const {
|
||||
activeRequestTabId
|
||||
activeRequestTabUid
|
||||
} = store;
|
||||
|
||||
const dropdownTippyRef = useRef();
|
||||
@ -30,7 +30,7 @@ const CollectionItem = ({item, collectionId}) => {
|
||||
});
|
||||
|
||||
const itemRowClassName = classnames('flex collection-item-name items-center', {
|
||||
'item-focused-in-tab': item.id == activeRequestTabId
|
||||
'item-focused-in-tab': item.uid == activeRequestTabUid
|
||||
});
|
||||
|
||||
const handleClick = (event) => {
|
||||
@ -41,16 +41,16 @@ const CollectionItem = ({item, collectionId}) => {
|
||||
|
||||
storeDispatch({
|
||||
type: actions.SIDEBAR_COLLECTION_ITEM_CLICK,
|
||||
itemId: item.id,
|
||||
collectionId: collectionId
|
||||
itemUid: item.uid,
|
||||
collectionUid: collectionUid
|
||||
});
|
||||
};
|
||||
|
||||
const addRequest = () => {
|
||||
storeDispatch({
|
||||
type: actions.ADD_REQUEST,
|
||||
itemId: item.id,
|
||||
collectionId: collectionId
|
||||
itemUid: item.uid,
|
||||
collectionUid: collectionUid
|
||||
});
|
||||
};
|
||||
|
||||
@ -124,9 +124,9 @@ const CollectionItem = ({item, collectionId}) => {
|
||||
<div>
|
||||
{item.items && item.items.length ? item.items.map((i) => {
|
||||
return <CollectionItem
|
||||
key={i.id}
|
||||
key={i.uid}
|
||||
item={i}
|
||||
collectionId={collectionId}
|
||||
collectionUid={collectionUid}
|
||||
/>
|
||||
}) : null}
|
||||
</div>
|
||||
|
@ -5,6 +5,7 @@ import { IconChevronRight, IconDots } from '@tabler/icons';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import actions from 'providers/Store/actions'
|
||||
import { useStore } from 'providers/Store';
|
||||
import NewRequest from 'components/Sidebar/NewRequest';
|
||||
import NewFolder from 'components/Sidebar/NewFolder';
|
||||
import CollectionItem from './CollectionItem';
|
||||
|
||||
@ -12,12 +13,9 @@ import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const Collection = ({collection}) => {
|
||||
const [showNewFolderModal, setShowNewFolderModal] = useState(false);
|
||||
const [showNewRequestModal, setShowNewRequestModal] = useState(false);
|
||||
const [store, storeDispatch] = useStore();
|
||||
|
||||
const {
|
||||
activeRequestTabId
|
||||
} = store;
|
||||
|
||||
const menuDropdownTippyRef = useRef();
|
||||
const onMenuDropdownCreate = (ref) => menuDropdownTippyRef.current = ref;
|
||||
const MenuIcon = forwardRef((props, ref) => {
|
||||
@ -48,25 +46,33 @@ const Collection = ({collection}) => {
|
||||
});
|
||||
};
|
||||
|
||||
const hideAddFolderModal = () => setShowNewFolderModal(false);
|
||||
const collectionItems = get(collection, 'current.items');
|
||||
const hideNewFolderModal = () => setShowNewFolderModal(false);
|
||||
const hideNewRequestModal = () => setShowNewRequestModal(false);
|
||||
|
||||
return (
|
||||
<StyledWrapper className="flex flex-col">
|
||||
{showNewRequestModal && (
|
||||
<NewRequest
|
||||
collectionUid={collection.uid}
|
||||
handleCancel={hideNewRequestModal}
|
||||
handleClose={hideNewRequestModal}
|
||||
/>
|
||||
)}
|
||||
{showNewFolderModal && (
|
||||
<NewFolder
|
||||
collectionUid={collection.uid}
|
||||
handleCancel={hideAddFolderModal}
|
||||
handleClose={hideAddFolderModal}
|
||||
handleCancel={hideNewFolderModal}
|
||||
handleClose={hideNewFolderModal}
|
||||
/>
|
||||
)}
|
||||
<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.current.name}</span>
|
||||
<span className="ml-1">{collection.name}</span>
|
||||
<div className="collection-actions">
|
||||
<Dropdown onCreate={onMenuDropdownCreate} icon={<MenuIcon />} placement='bottom-start'>
|
||||
<div className="dropdown-item" onClick={(e) => {
|
||||
menuDropdownTippyRef.current.hide();
|
||||
setShowNewRequestModal(true)
|
||||
}}>
|
||||
New Request
|
||||
</div>
|
||||
@ -83,11 +89,11 @@ const Collection = ({collection}) => {
|
||||
<div>
|
||||
{collection.collapsed ? (
|
||||
<div>
|
||||
{collectionItems && collectionItems.length ? collectionItems.map((i) => {
|
||||
{collection.items && collection.items.length ? collection.items.map((i) => {
|
||||
return <CollectionItem
|
||||
key={i.uid}
|
||||
item={i}
|
||||
collectionId={collection.id}
|
||||
collectionUid={collection.uid}
|
||||
/>
|
||||
}) : null}
|
||||
</div>
|
||||
|
@ -1,16 +1,19 @@
|
||||
import React from 'react';
|
||||
import { useStore } from 'providers/Store';
|
||||
import Collection from './Collection';
|
||||
|
||||
const Collections = ({collections, actions, dispatch, activeRequestTabId}) => {
|
||||
const Collections = () => {
|
||||
const [store, storeDispatch] = useStore();
|
||||
const {
|
||||
collections
|
||||
} = store;
|
||||
|
||||
return (
|
||||
<div className="mt-4 flex flex-col">
|
||||
{collections && collections.length ? collections.map((c) => {
|
||||
return <Collection
|
||||
collection={c}
|
||||
key={c.uid}
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
activeRequestTabId={activeRequestTabId}
|
||||
/>
|
||||
}) : null}
|
||||
</div>
|
||||
|
@ -1,9 +1,10 @@
|
||||
import React from 'react';
|
||||
import {useFormik} from 'formik';
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import { useFormik } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
import Modal from '../../Modal';
|
||||
|
||||
const CreateCollection = ({handleConfirm, handleCancel, actions, dispatch}) => {
|
||||
const inputRef = useRef();
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
initialValues: {
|
||||
@ -20,6 +21,12 @@ const CreateCollection = ({handleConfirm, handleCancel, actions, dispatch}) => {
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if(inputRef && inputRef.current) {
|
||||
inputRef.current.focus();
|
||||
}
|
||||
}, [inputRef]);
|
||||
|
||||
const onSubmit = () => formik.handleSubmit();
|
||||
|
||||
return (
|
||||
@ -33,7 +40,10 @@ const CreateCollection = ({handleConfirm, handleCancel, actions, dispatch}) => {
|
||||
<div>
|
||||
<label htmlFor="collectionName" className="block font-semibold">Name</label>
|
||||
<input
|
||||
id="collection-name" type="text" name="collectionName"
|
||||
id="collection-name"
|
||||
type="text"
|
||||
name="collectionName"
|
||||
ref={inputRef}
|
||||
className="block textbox mt-2 w-full"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.collectionName || ''}
|
||||
|
@ -21,7 +21,7 @@ const NewFolder = ({collectionUid, handleCancel, handleClose}) => {
|
||||
}),
|
||||
onSubmit: (values) => {
|
||||
storeDispatch({
|
||||
type: actions.SIDEBAR_COLLECTION_ADD_FOLDER,
|
||||
type: actions.SIDEBAR_COLLECTION_NEW_FOLDER,
|
||||
collectionUid: collectionUid,
|
||||
folderName: values.folderName
|
||||
});
|
||||
|
67
renderer/components/Sidebar/NewRequest/index.js
Normal file
67
renderer/components/Sidebar/NewRequest/index.js
Normal file
@ -0,0 +1,67 @@
|
||||
import React, { useRef, useEffect } from 'react';
|
||||
import { useFormik } from 'formik';
|
||||
import * as Yup from 'yup';
|
||||
import Modal from 'components/Modal';
|
||||
import actions from 'providers/Store/actions'
|
||||
import { useStore } from 'providers/Store';
|
||||
|
||||
const NewRequest = ({collectionUid, handleCancel, handleClose}) => {
|
||||
const [store, storeDispatch] = useStore();
|
||||
const inputRef = useRef();
|
||||
const formik = useFormik({
|
||||
enableReinitialize: true,
|
||||
initialValues: {
|
||||
requestName: ''
|
||||
},
|
||||
validationSchema: Yup.object({
|
||||
requestName: Yup.string()
|
||||
.min(1, 'must be atleast 1 characters')
|
||||
.max(50, 'must be 50 characters or less')
|
||||
.required('name is required')
|
||||
}),
|
||||
onSubmit: (values) => {
|
||||
storeDispatch({
|
||||
type: actions.SIDEBAR_COLLECTION_NEW_REQUEST,
|
||||
collectionUid: collectionUid,
|
||||
requestName: values.requestName
|
||||
});
|
||||
handleClose();
|
||||
}
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
if(inputRef && inputRef.current) {
|
||||
inputRef.current.focus();
|
||||
}
|
||||
}, [inputRef]);
|
||||
|
||||
const onSubmit = () => formik.handleSubmit();
|
||||
|
||||
return (
|
||||
<Modal
|
||||
size="sm"
|
||||
title='New Request'
|
||||
confirmText='Create'
|
||||
handleConfirm={onSubmit}
|
||||
handleCancel={handleCancel}
|
||||
>
|
||||
<form className="grafnode-form" onSubmit={formik.handleSubmit}>
|
||||
<div>
|
||||
<label htmlFor="requestName" className="block font-semibold">Request Name</label>
|
||||
<input
|
||||
id="collection-name" type="text" name="requestName"
|
||||
ref={inputRef}
|
||||
className="block textbox mt-2 w-full"
|
||||
onChange={formik.handleChange}
|
||||
value={formik.values.requestName || ''}
|
||||
/>
|
||||
{formik.touched.requestName && formik.errors.requestName ? (
|
||||
<div className="text-red-500">{formik.errors.requestName}</div>
|
||||
) : null}
|
||||
</div>
|
||||
</form>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewRequest;
|
@ -2,13 +2,14 @@ import React, { useState, forwardRef, useRef } from 'react';
|
||||
import {nanoid} from 'nanoid';
|
||||
import Toast from 'components/Toast';
|
||||
import Dropdown from 'components/Dropdown';
|
||||
import actions from 'providers/Store/actions'
|
||||
import { saveCollectionToIdb } from 'providers/Store/idb';
|
||||
import { useStore } from 'providers/Store';
|
||||
import { IconDots } from '@tabler/icons';
|
||||
import CreateCollection from '../CreateCollection';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const TitleBar = ({dispatch, actions}) => {
|
||||
const TitleBar = () => {
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [store, storeDispatch] = useStore();
|
||||
const [showToast, setShowToast] = useState({show: false});
|
||||
@ -32,7 +33,6 @@ const TitleBar = ({dispatch, actions}) => {
|
||||
// type: actions.COLLECTION_CREATE
|
||||
// });
|
||||
setModalOpen(false);
|
||||
console.log(store.idbConnection);
|
||||
if(!store.idbConnection) {
|
||||
setShowToast({
|
||||
show: true,
|
||||
@ -42,18 +42,12 @@ const TitleBar = ({dispatch, actions}) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const collectionUid = nanoid();
|
||||
const newCollection = {
|
||||
uid: collectionUid,
|
||||
base: null,
|
||||
current: {
|
||||
uid: collectionUid,
|
||||
name: values.collectionName,
|
||||
items: []
|
||||
},
|
||||
userId: null,
|
||||
hasChangedSinceLastSync: false,
|
||||
disableSync: true
|
||||
uid: nanoid(),
|
||||
name: values.collectionName,
|
||||
items: [],
|
||||
environments: [],
|
||||
userId: null
|
||||
};
|
||||
|
||||
saveCollectionToIdb(store.idbConnection, newCollection)
|
||||
@ -76,7 +70,7 @@ const TitleBar = ({dispatch, actions}) => {
|
||||
handleCancel={handleCancel}
|
||||
handleConfirm={handleConfirm}
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
dispatch={storeDispatch}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
|
@ -5,18 +5,14 @@ import TitleBar from './TitleBar';
|
||||
import { IconSearch } from '@tabler/icons';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const Sidebar = ({collections, actions, dispatch, activeRequestTabId}) => {
|
||||
|
||||
const Sidebar = () => {
|
||||
return (
|
||||
<StyledWrapper>
|
||||
<div className="flex flex-row h-full">
|
||||
<MenuBar />
|
||||
|
||||
<div className="flex flex-col flex-grow">
|
||||
<TitleBar
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
/>
|
||||
<TitleBar />
|
||||
|
||||
<div className="mt-4 relative collection-filter px-2">
|
||||
<div className="absolute inset-y-0 left-0 pl-4 flex items-center pointer-events-none">
|
||||
@ -33,12 +29,7 @@ const Sidebar = ({collections, actions, dispatch, activeRequestTabId}) => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Collections
|
||||
collections={collections}
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
activeRequestTabId={activeRequestTabId}
|
||||
/>
|
||||
<Collections />
|
||||
</div>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
|
@ -2,8 +2,6 @@ import React from 'react';
|
||||
import RequestTabs from 'components/RequestTabs';
|
||||
import RequestTabPanel from 'components/RequestTabPanel';
|
||||
import Sidebar from 'components/Sidebar';
|
||||
import actions from 'providers/Store/actions';
|
||||
import { useStore } from 'providers/Store';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
||||
@ -31,36 +29,17 @@ if(!SERVER_RENDERED) {
|
||||
|
||||
|
||||
export default function Main() {
|
||||
const [state, dispatch] = useStore();
|
||||
|
||||
if (SERVER_RENDERED) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const {
|
||||
collections,
|
||||
requestTabs,
|
||||
activeRequestTabId
|
||||
} = state;
|
||||
|
||||
return (
|
||||
<div>
|
||||
<StyledWrapper>
|
||||
<Sidebar
|
||||
collections={collections}
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
activeRequestTabId={activeRequestTabId}
|
||||
/>
|
||||
<Sidebar />
|
||||
<section className='flex flex-grow flex-col'>
|
||||
<RequestTabs/>
|
||||
<RequestTabPanel
|
||||
actions={actions}
|
||||
dispatch={dispatch}
|
||||
collections={collections}
|
||||
requestTabs={requestTabs}
|
||||
activeRequestTabId={activeRequestTabId}
|
||||
/>
|
||||
<RequestTabs />
|
||||
<RequestTabPanel />
|
||||
</section>
|
||||
</StyledWrapper>
|
||||
</div>
|
||||
|
@ -1,6 +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 SIDEBAR_COLLECTION_NEW_FOLDER = "SIDEBAR_COLLECTION_NEW_FOLDER";
|
||||
const SIDEBAR_COLLECTION_NEW_REQUEST = "SIDEBAR_COLLECTION_NEW_REQUEST";
|
||||
const LOAD_COLLECTIONS_FROM_IDB = "LOAD_COLLECTIONS_FROM_IDB";
|
||||
const COLLECTION_CREATE = "COLLECTION_CREATE";
|
||||
const REQUEST_TAB_CLICK = "REQUEST_TAB_CLICK";
|
||||
@ -20,7 +21,8 @@ const IDB_COLLECTIONS_SYNC_ERROR = "IDB_COLLECTIONS_SYNC_ERROR";
|
||||
export default {
|
||||
SIDEBAR_COLLECTION_CLICK,
|
||||
SIDEBAR_COLLECTION_ITEM_CLICK,
|
||||
SIDEBAR_COLLECTION_ADD_FOLDER,
|
||||
SIDEBAR_COLLECTION_NEW_FOLDER,
|
||||
SIDEBAR_COLLECTION_NEW_REQUEST,
|
||||
LOAD_COLLECTIONS_FROM_IDB,
|
||||
COLLECTION_CREATE,
|
||||
REQUEST_TAB_CLICK,
|
||||
|
@ -116,7 +116,7 @@ const collection2 = {
|
||||
const initialState = {
|
||||
idbConnection: null,
|
||||
collections: [],
|
||||
activeRequestTabId: null,
|
||||
activeRequestTabUid: null,
|
||||
requestQueuedToSend: null,
|
||||
requestTabs: [],
|
||||
collectionsToSyncToIdb: []
|
||||
@ -135,10 +135,10 @@ export const StoreProvider = props => {
|
||||
if(state.requestQueuedToSend) {
|
||||
const {
|
||||
request,
|
||||
collectionId
|
||||
collectionUid
|
||||
} = state.requestQueuedToSend;
|
||||
|
||||
sendRequest(request, collectionId, dispatch)
|
||||
sendRequest(request, collectionUid, dispatch)
|
||||
}
|
||||
}, [state.requestQueuedToSend]);
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
import produce from 'immer';
|
||||
import {nanoid} from 'nanoid';
|
||||
import find from 'lodash/find';
|
||||
import union from 'lodash/union';
|
||||
import filter from 'lodash/filter';
|
||||
import last from 'lodash/last';
|
||||
@ -57,23 +56,23 @@ const reducer = (state, action) => {
|
||||
|
||||
if(collection) {
|
||||
let flattenedItems = flattenItems(collection.items);
|
||||
let item = findItem(flattenedItems, action.itemId);
|
||||
let item = findItem(flattenedItems, action.itemUid);
|
||||
|
||||
if(item) {
|
||||
item.collapsed = !item.collapsed;
|
||||
|
||||
if(isItemARequest(item)) {
|
||||
if(itemIsOpenedInTabs(item, draft.requestTabs)) {
|
||||
draft.activeRequestTabId = item.id;
|
||||
draft.activeRequestTabUid = item.uid;
|
||||
} else {
|
||||
draft.requestTabs.push({
|
||||
id: item.id,
|
||||
uid: item.uid,
|
||||
name: item.name,
|
||||
method: item.request.method,
|
||||
collectionId: collection.id,
|
||||
collectionUid: collection.uid,
|
||||
hasChanges: false
|
||||
});
|
||||
draft.activeRequestTabId = item.id;
|
||||
draft.activeRequestTabUid = item.uid;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,16 +80,50 @@ const reducer = (state, action) => {
|
||||
});
|
||||
}
|
||||
|
||||
case actions.SIDEBAR_COLLECTION_ADD_FOLDER: {
|
||||
case actions.SIDEBAR_COLLECTION_NEW_REQUEST: {
|
||||
return produce(state, (draft) => {
|
||||
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
||||
|
||||
if(collection) {
|
||||
collection.current.items.push({
|
||||
"uid": nanoid(),
|
||||
"name": action.folderName,
|
||||
"depth": 1,
|
||||
"items": []
|
||||
const uid = nanoid();
|
||||
const item = {
|
||||
uid: uid,
|
||||
name: action.requestName,
|
||||
request: {
|
||||
type: 'http',
|
||||
method: 'GET',
|
||||
url: 'https://reqbin.com/echo/get/json',
|
||||
headers: [],
|
||||
body: null
|
||||
},
|
||||
depth: 1
|
||||
};
|
||||
collection.items.push(item);
|
||||
|
||||
draft.requestTabs.push({
|
||||
uid: item.uid,
|
||||
name: item.name,
|
||||
method: item.request.method,
|
||||
collectionUid: collection.uid,
|
||||
hasChanges: false
|
||||
});
|
||||
draft.activeRequestTabUid = uid;
|
||||
draft.collectionsToSyncToIdb.push(collection.uid);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
case actions.SIDEBAR_COLLECTION_NEW_FOLDER: {
|
||||
return produce(state, (draft) => {
|
||||
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
||||
|
||||
if(collection) {
|
||||
collection.items.push({
|
||||
uid: nanoid(),
|
||||
name: action.folderName,
|
||||
items: [],
|
||||
// todo: this will be autoassigned
|
||||
depth: 1
|
||||
});
|
||||
draft.collectionsToSyncToIdb.push(collection.uid);
|
||||
}
|
||||
@ -102,7 +135,7 @@ const reducer = (state, action) => {
|
||||
// todo: collection names must be unique across a user account
|
||||
draft.collections = draft.collections || [];
|
||||
draft.collections.push({
|
||||
id: nanoid(),
|
||||
uid: nanoid(),
|
||||
name: action.name,
|
||||
items: []
|
||||
});
|
||||
@ -111,7 +144,7 @@ const reducer = (state, action) => {
|
||||
|
||||
case actions.REQUEST_TAB_CLICK: {
|
||||
return produce(state, (draft) => {
|
||||
draft.activeRequestTabId = action.requestTab.id;
|
||||
draft.activeRequestTabUid = action.requestTab.uid;
|
||||
});
|
||||
}
|
||||
|
||||
@ -153,7 +186,7 @@ const reducer = (state, action) => {
|
||||
return produce(state, (draft) => {
|
||||
const uid = nanoid();
|
||||
draft.requestTabs.push({
|
||||
id: uid,
|
||||
uid: uid,
|
||||
name: 'New Tab',
|
||||
method: 'GET',
|
||||
request: {
|
||||
@ -161,9 +194,9 @@ const reducer = (state, action) => {
|
||||
url: 'https://api.spacex.land/graphql/',
|
||||
body: {}
|
||||
},
|
||||
collectionId: null
|
||||
collectionUid: null
|
||||
});
|
||||
draft.activeRequestTabId = uid;
|
||||
draft.activeRequestTabUid = uid;
|
||||
});
|
||||
}
|
||||
|
||||
@ -171,7 +204,7 @@ const reducer = (state, action) => {
|
||||
return produce(state, (draft) => {
|
||||
const uid = nanoid();
|
||||
draft.requestTabs.push({
|
||||
id: uid,
|
||||
uid: uid,
|
||||
name: 'New Tab',
|
||||
method: 'GET',
|
||||
request: {
|
||||
@ -183,9 +216,9 @@ const reducer = (state, action) => {
|
||||
}
|
||||
}
|
||||
},
|
||||
collectionId: null
|
||||
collectionUid: null
|
||||
});
|
||||
draft.activeRequestTabId = uid;
|
||||
draft.activeRequestTabUid = uid;
|
||||
});
|
||||
}
|
||||
|
||||
@ -201,7 +234,7 @@ const reducer = (state, action) => {
|
||||
item.response = item.response || {};
|
||||
item.response.state = 'queued';
|
||||
draft.requestQueuedToSend = {
|
||||
collectionId: action.collectionId,
|
||||
collectionUid: action.collectionUid,
|
||||
request: item
|
||||
}
|
||||
}
|
||||
@ -246,9 +279,9 @@ const reducer = (state, action) => {
|
||||
|
||||
if(draft.requestTabs && draft.requestTabs.length) {
|
||||
// todo: closing tab needs to focus on the right adjacent tab
|
||||
draft.activeRequestTabId = last(draft.requestTabs).id;
|
||||
draft.activeRequestTabUid = last(draft.requestTabs).uid;
|
||||
} else {
|
||||
draft.activeRequestTabId = null;
|
||||
draft.activeRequestTabUid = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -264,7 +297,7 @@ const reducer = (state, action) => {
|
||||
if(item) {
|
||||
if(!isItemARequest(item)) {
|
||||
let newRequest = {
|
||||
"id": nanoid(),
|
||||
"uid": nanoid(),
|
||||
"depth": 2,
|
||||
"name": "Capsules 2",
|
||||
"request": {
|
||||
@ -282,13 +315,13 @@ const reducer = (state, action) => {
|
||||
},
|
||||
"response": null
|
||||
};
|
||||
draft.activeRequestTabId = newRequest.id;
|
||||
draft.activeRequestTabUid = newRequest.uid;
|
||||
item.items.push(newRequest);
|
||||
draft.requestTabs.push({
|
||||
id: newRequest.id,
|
||||
uid: newRequest.uid,
|
||||
name: newRequest.name,
|
||||
method: newRequest.request.method,
|
||||
collectionId: collection.id
|
||||
collectionUid: collection.id
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ export const flattenItems = (items = []) => {
|
||||
return flattenedItems;
|
||||
};
|
||||
|
||||
export const findItem = (items = [], itemId) => {
|
||||
return find(items, (i) => i.id === itemId);
|
||||
export const findItem = (items = [], itemUid) => {
|
||||
return find(items, (i) => i.uid === itemUid);
|
||||
};
|
||||
|
||||
export const isItemARequest = (item) => {
|
||||
@ -29,15 +29,15 @@ export const isItemARequest = (item) => {
|
||||
};
|
||||
|
||||
export const itemIsOpenedInTabs = (item, tabs) => {
|
||||
return find(tabs, (t) => t.id === item.id);
|
||||
return find(tabs, (t) => t.uid === item.uid);
|
||||
};
|
||||
|
||||
export const cloneItem = (item) => {
|
||||
return cloneDeep(item);
|
||||
};
|
||||
|
||||
export const updateRequestTabAsChanged = (requestTabs, itemId) => {
|
||||
let currentTab = find(requestTabs, (rt) => rt.id == itemId);
|
||||
export const updateRequestTabAsChanged = (requestTabs, itemUid) => {
|
||||
let currentTab = find(requestTabs, (rt) => rt.uid == itemUid);
|
||||
if(currentTab) {
|
||||
currentTab.hasChanges = true;
|
||||
}
|
||||
|
@ -19,8 +19,8 @@ export const flattenItems = (items = []) => {
|
||||
return flattenedItems;
|
||||
};
|
||||
|
||||
export const findItem = (items = [], itemId) => {
|
||||
return find(items, (i) => i.id === itemId);
|
||||
export const findItem = (items = [], itemUid) => {
|
||||
return find(items, (i) => i.uid === itemUid);
|
||||
};
|
||||
|
||||
export const isItemARequest = (item) => {
|
||||
@ -28,5 +28,5 @@ export const isItemARequest = (item) => {
|
||||
};
|
||||
|
||||
export const itemIsOpenedInTabs = (item, tabs) => {
|
||||
return find(tabs, (t) => t.id === item.id);
|
||||
return find(tabs, (t) => t.uid === item.uid);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user