forked from extern/bruno
refactor: redux migration - sending requests
This commit is contained in:
parent
914927bbfd
commit
038eb47dda
@ -2,16 +2,14 @@ import React, { useState, useEffect } from 'react';
|
||||
import find from 'lodash/find';
|
||||
import { useStore } from 'providers/Store';
|
||||
import actions from 'providers/Store/actions';
|
||||
import { useSelector, useDispatch } from 'react-redux';
|
||||
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
|
||||
} from '../../utils';
|
||||
import { sendRequest } from '../../network';
|
||||
import { findItemInCollection } from 'utils/collections';
|
||||
import { sendRequest } from 'providers/ReduxStore/slices/collections';
|
||||
import useGraphqlSchema from '../../hooks/useGraphqlSchema';
|
||||
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
@ -20,14 +18,12 @@ const RequestTabPanel = () => {
|
||||
if(typeof window == 'undefined') {
|
||||
return <div></div>;
|
||||
}
|
||||
const tabs = useSelector((state) => state.tabs.tabs);
|
||||
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
||||
const collections = useSelector((state) => state.collections.collections);
|
||||
const dispatch = useDispatch();
|
||||
const [store, storeDispatch] = useStore();
|
||||
|
||||
const {
|
||||
collections,
|
||||
requestTabs,
|
||||
activeRequestTabUid
|
||||
} = store;
|
||||
|
||||
let asideWidth = 270;
|
||||
let {
|
||||
schema
|
||||
@ -72,13 +68,13 @@ const RequestTabPanel = () => {
|
||||
});
|
||||
};
|
||||
|
||||
if(!activeRequestTabUid) {
|
||||
if(!activeTabUid) {
|
||||
return (
|
||||
<Welcome dispatch={storeDispatch} actions={actions}/>
|
||||
);
|
||||
}
|
||||
|
||||
const focusedTab = find(requestTabs, (rt) => rt.uid === activeRequestTabUid);
|
||||
const focusedTab = find(tabs, (t) => t.uid === activeTabUid);
|
||||
|
||||
if(!focusedTab || !focusedTab.uid || !focusedTab.collectionUid) {
|
||||
return (
|
||||
@ -93,8 +89,7 @@ const RequestTabPanel = () => {
|
||||
);
|
||||
}
|
||||
|
||||
let flattenedItems = flattenItems(collection.items);
|
||||
let item = findItem(flattenedItems, activeRequestTabUid);
|
||||
const item = findItemInCollection(collection, activeTabUid);
|
||||
|
||||
const onUrlChange = (value) => {
|
||||
storeDispatch({
|
||||
@ -114,7 +109,7 @@ const RequestTabPanel = () => {
|
||||
};
|
||||
|
||||
const sendNetworkRequest = async () => {
|
||||
sendRequest(item, collection.uid, storeDispatch);
|
||||
dispatch(sendRequest(item, collection.uid));
|
||||
};
|
||||
|
||||
return (
|
||||
|
@ -12,4 +12,4 @@
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
}
|
||||
|
@ -1,88 +0,0 @@
|
||||
import actions from '../providers/Store/actions';
|
||||
import { rawRequest, gql } from 'graphql-request';
|
||||
|
||||
const sendRequest = async (item, collectionUid, dispatch) => {
|
||||
if(item.type === 'http-request') {
|
||||
dispatch({
|
||||
type: actions.SENDING_REQUEST,
|
||||
collectionUid: collectionUid,
|
||||
itemUid: item.uid
|
||||
});
|
||||
|
||||
const timeStart = Date.now();
|
||||
sendHttpRequest(item.request)
|
||||
.then((response) => {
|
||||
console.log(response);
|
||||
const timeEnd = Date.now();
|
||||
dispatch({
|
||||
type: actions.RESPONSE_RECEIVED,
|
||||
response: {
|
||||
state: 'success',
|
||||
data: response.data,
|
||||
headers: Object.entries(response.headers),
|
||||
size: response.headers["content-length"],
|
||||
status: response.status,
|
||||
duration: timeEnd - timeStart
|
||||
},
|
||||
collectionUid: collectionUid,
|
||||
itemUid: item.uid
|
||||
});
|
||||
})
|
||||
.catch((err) => console.error(err));
|
||||
}
|
||||
};
|
||||
|
||||
const sendHttpRequest = async (request) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { ipcRenderer } = window.require("electron");
|
||||
|
||||
console.log(request);
|
||||
|
||||
let options = {
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
};
|
||||
|
||||
ipcRenderer
|
||||
.invoke('send-http-request', options)
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
const sendGraphqlRequest = async (request, collectionId, dispatch) => {
|
||||
dispatch({
|
||||
type: actions.SENDING_REQUEST,
|
||||
request: request,
|
||||
collectionId: collectionId
|
||||
});
|
||||
|
||||
const query = gql`${request.request.body.graphql.query}`;
|
||||
|
||||
const timeStart = Date.now();
|
||||
const { data, errors, extensions, headers, status } = await rawRequest(request.request.url, query);
|
||||
const timeEnd = Date.now();
|
||||
|
||||
if(data && !errors) {
|
||||
// todo: alternate way to calculate length when content length is not present
|
||||
const size = headers.map["content-length"];
|
||||
|
||||
dispatch({
|
||||
type: actions.RESPONSE_RECEIVED,
|
||||
response: {
|
||||
data: data,
|
||||
headers: Object.entries(headers.map),
|
||||
size: size,
|
||||
status: status,
|
||||
duration: timeEnd - timeStart
|
||||
},
|
||||
request: request,
|
||||
collectionId: collectionId
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
sendRequest,
|
||||
sendGraphqlRequest
|
||||
};
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||
import RequestTabs from 'components/RequestTabs';
|
||||
import RequestTabPanel from 'components/RequestTabPanel';
|
||||
import Sidebar from 'components/Sidebar';
|
||||
import { useStore } from 'providers/Store';
|
||||
import { useSelector } from 'react-redux';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
||||
@ -30,10 +30,7 @@ if(!SERVER_RENDERED) {
|
||||
|
||||
|
||||
export default function Main() {
|
||||
const [store, storeDispatch] = useStore();
|
||||
const {
|
||||
activeRequestTabUid
|
||||
} = store;
|
||||
const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
|
||||
|
||||
if (SERVER_RENDERED) {
|
||||
return null;
|
||||
@ -45,7 +42,7 @@ export default function Main() {
|
||||
<Sidebar />
|
||||
<section className='flex flex-grow flex-col'>
|
||||
<RequestTabs />
|
||||
<RequestTabPanel key={activeRequestTabUid}/>
|
||||
<RequestTabPanel key={activeTabUid}/>
|
||||
</section>
|
||||
</StyledWrapper>
|
||||
</div>
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { nanoid } from 'nanoid';
|
||||
import { createSlice } from '@reduxjs/toolkit'
|
||||
import { getCollectionsFromIdb, saveCollectionToIdb } from 'utils/idb';
|
||||
import { findCollectionByUid } from 'utils/collections';
|
||||
import { sendNetworkRequest } from 'utils/network';
|
||||
import { findCollectionByUid, findItemInCollection } from 'utils/collections';
|
||||
|
||||
// todo: errors should be tracked in each slice and displayed as toasts
|
||||
|
||||
@ -19,6 +20,27 @@ export const collectionsSlice = createSlice({
|
||||
_createCollection: (state, action) => {
|
||||
state.collections.push(action.payload);
|
||||
},
|
||||
_requestSent: (state, action) => {
|
||||
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||
|
||||
if(collection) {
|
||||
const item = findItemInCollection(collection, action.payload.itemUid);
|
||||
if(item) {
|
||||
item.response = item.response || {};
|
||||
item.response.state = 'sending';
|
||||
}
|
||||
}
|
||||
},
|
||||
_responseReceived: (state, action) => {
|
||||
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||
|
||||
if(collection) {
|
||||
const item = findItemInCollection(collection, action.payload.itemUid);
|
||||
if(item) {
|
||||
item.response = action.payload.response;
|
||||
}
|
||||
}
|
||||
},
|
||||
collectionClicked: (state, action) => {
|
||||
const collection = findCollectionByUid(state.collections, action.payload);
|
||||
|
||||
@ -32,6 +54,8 @@ export const collectionsSlice = createSlice({
|
||||
export const {
|
||||
_loadCollections,
|
||||
_createCollection,
|
||||
_requestSent,
|
||||
_responseReceived,
|
||||
collectionClicked
|
||||
} = collectionsSlice.actions;
|
||||
|
||||
@ -55,4 +79,18 @@ export const createCollection = (collectionName) => (dispatch) => {
|
||||
.catch((err) => console.log(err));
|
||||
};
|
||||
|
||||
export const sendRequest = (item, collectionUid) => (dispatch) => {
|
||||
dispatch(_requestSent({
|
||||
itemUid: item.uid,
|
||||
collectionUid: collectionUid
|
||||
}));
|
||||
sendNetworkRequest(item)
|
||||
.then((response) => dispatch(_responseReceived({
|
||||
itemUid: item.uid,
|
||||
collectionUid: collectionUid,
|
||||
response: response
|
||||
})))
|
||||
.catch((err) => console.log(err));
|
||||
};
|
||||
|
||||
export default collectionsSlice.reducer;
|
||||
|
@ -3,9 +3,6 @@ const SIDEBAR_COLLECTION_NEW_REQUEST = "SIDEBAR_COLLECTION_NEW_REQUEST";
|
||||
const LOAD_COLLECTIONS_FROM_IDB = "LOAD_COLLECTIONS_FROM_IDB";
|
||||
const REQUEST_URL_CHANGED = "REQUEST_URL_CHANGED";
|
||||
const REQUEST_GQL_QUERY_CHANGED = "REQUEST_GQL_QUERY_CHANGED";
|
||||
const RESPONSE_RECEIVED = "RESPONSE_RECEIVED";
|
||||
const SEND_REQUEST = "SEND_REQUEST";
|
||||
const SENDING_REQUEST = "SENDING_REQUEST";
|
||||
const ADD_NEW_GQL_REQUEST = "ADD_NEW_GQL_REQUEST";
|
||||
const IDB_CONNECTION_READY = "IDB_CONNECTION_READY";
|
||||
const IDB_COLLECTIONS_SYNC_STARTED = "IDB_COLLECTIONS_SYNC_STARTED";
|
||||
@ -18,9 +15,6 @@ export default {
|
||||
LOAD_COLLECTIONS_FROM_IDB,
|
||||
REQUEST_URL_CHANGED,
|
||||
REQUEST_GQL_QUERY_CHANGED,
|
||||
RESPONSE_RECEIVED,
|
||||
SEND_REQUEST,
|
||||
SENDING_REQUEST,
|
||||
ADD_NEW_GQL_REQUEST,
|
||||
IDB_CONNECTION_READY,
|
||||
IDB_COLLECTIONS_SYNC_STARTED,
|
||||
|
@ -4,8 +4,6 @@ import reducer from './reducer';
|
||||
import useIdb from './useIdb';
|
||||
import useLoadCollectionsFromIdb from './useLoadCollectionsFromIdb';
|
||||
import useSyncCollectionsToIdb from './useSyncCollectionsToIdb';
|
||||
import { sendRequest } from '../../network';
|
||||
|
||||
export const StoreContext = createContext();
|
||||
|
||||
const collection = {
|
||||
@ -116,7 +114,6 @@ const initialState = {
|
||||
idbConnection: null,
|
||||
collections: [],
|
||||
activeRequestTabUid: null,
|
||||
requestQueuedToSend: null,
|
||||
requestTabs: [],
|
||||
collectionsToSyncToIdb: []
|
||||
};
|
||||
@ -130,17 +127,6 @@ export const StoreProvider = props => {
|
||||
collectionsToSyncToIdb
|
||||
} = state;
|
||||
|
||||
useEffect(() => {
|
||||
if(state.requestQueuedToSend) {
|
||||
const {
|
||||
request,
|
||||
collectionUid
|
||||
} = state.requestQueuedToSend;
|
||||
|
||||
sendRequest(request, collectionUid, dispatch)
|
||||
}
|
||||
}, [state.requestQueuedToSend]);
|
||||
|
||||
useIdb(dispatch);
|
||||
useLoadCollectionsFromIdb(idbConnection, dispatch);
|
||||
useSyncCollectionsToIdb(collectionsToSyncToIdb, collections, idbConnection, dispatch);
|
||||
|
@ -144,61 +144,6 @@ const reducer = (state, action) => {
|
||||
});
|
||||
}
|
||||
|
||||
case actions.SEND_REQUEST: {
|
||||
return produce(state, (draft) => {
|
||||
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
||||
|
||||
if(collection) {
|
||||
let flattenedItems = flattenItems(collection.items);
|
||||
let item = findItem(flattenedItems, action.requestTab.uid);
|
||||
|
||||
if(item) {
|
||||
item.response = item.response || {};
|
||||
item.response.state = 'queued';
|
||||
draft.requestQueuedToSend = {
|
||||
collectionUid: action.collectionUid,
|
||||
request: item
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
case actions.SENDING_REQUEST: {
|
||||
return produce(state, (draft) => {
|
||||
const collection = findCollectionByUid(draft.collections, action.collectionUid);
|
||||
console.log('collection');
|
||||
console.log(collection);
|
||||
|
||||
if(collection) {
|
||||
let flattenedItems = flattenItems(collection.items);
|
||||
let item = findItem(flattenedItems, action.itemUid);
|
||||
console.log('citemllection');
|
||||
console.log(item);
|
||||
|
||||
if(item) {
|
||||
item.response = item.response || {};
|
||||
item.response.state = 'sending';
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
case actions.RESPONSE_RECEIVED: {
|
||||
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.response = action.response;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
case actions.HOTKEY_SAVE: {
|
||||
return produce(state, (draft) => {
|
||||
if(!draft.activeRequestTabUid) {
|
||||
|
@ -1,32 +0,0 @@
|
||||
import each from 'lodash/each';
|
||||
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 isItemARequest = (item) => {
|
||||
return item.hasOwnProperty('request');
|
||||
};
|
||||
|
||||
export const itemIsOpenedInTabs = (item, tabs) => {
|
||||
return find(tabs, (t) => t.uid === item.uid);
|
||||
};
|
57
renderer/utils/network/index.js
Normal file
57
renderer/utils/network/index.js
Normal file
@ -0,0 +1,57 @@
|
||||
import { rawRequest, gql } from 'graphql-request';
|
||||
|
||||
const sendNetworkRequest = async (item) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(item.type === 'http-request') {
|
||||
const timeStart = Date.now();
|
||||
sendHttpRequest(item.request)
|
||||
.then((response) => {
|
||||
const timeEnd = Date.now();
|
||||
resolve({
|
||||
state: 'success',
|
||||
data: response.data,
|
||||
headers: Object.entries(response.headers),
|
||||
size: response.headers["content-length"],
|
||||
status: response.status,
|
||||
duration: timeEnd - timeStart
|
||||
});
|
||||
})
|
||||
.catch((err) => reject(err));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const sendHttpRequest = async (request) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { ipcRenderer } = window.require("electron");
|
||||
|
||||
console.log(request);
|
||||
|
||||
let options = {
|
||||
method: request.method,
|
||||
url: request.url,
|
||||
};
|
||||
|
||||
ipcRenderer
|
||||
.invoke('send-http-request', options)
|
||||
.then(resolve)
|
||||
.catch(reject);
|
||||
});
|
||||
};
|
||||
|
||||
const sendGraphqlRequest = async (request,) => {
|
||||
const query = gql`${request.request.body.graphql.query}`;
|
||||
|
||||
const { data, errors, extensions, headers, status } = await rawRequest(request.request.url, query);
|
||||
|
||||
return {
|
||||
data,
|
||||
headers,
|
||||
data,
|
||||
errors
|
||||
}
|
||||
};
|
||||
|
||||
export {
|
||||
sendNetworkRequest
|
||||
};
|
Loading…
Reference in New Issue
Block a user