diff --git a/renderer/components/RequestTabPanel/index.js b/renderer/components/RequestTabPanel/index.js index 41daa1a3..e56418c7 100644 --- a/renderer/components/RequestTabPanel/index.js +++ b/renderer/components/RequestTabPanel/index.js @@ -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
; } + 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 ( ); } - 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 ( diff --git a/renderer/jsconfig.json b/renderer/jsconfig.json index 6dfec606..e0d9c340 100644 --- a/renderer/jsconfig.json +++ b/renderer/jsconfig.json @@ -12,4 +12,4 @@ } }, "exclude": ["node_modules", "dist"] -} \ No newline at end of file +} diff --git a/renderer/network/index.js b/renderer/network/index.js deleted file mode 100644 index 7845be81..00000000 --- a/renderer/network/index.js +++ /dev/null @@ -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 -}; diff --git a/renderer/pageComponents/Main/index.js b/renderer/pageComponents/Main/index.js index 9488589d..7301952a 100644 --- a/renderer/pageComponents/Main/index.js +++ b/renderer/pageComponents/Main/index.js @@ -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() {
- +
diff --git a/renderer/providers/ReduxStore/slices/collections.js b/renderer/providers/ReduxStore/slices/collections.js index 7c0da366..f3df1fb8 100644 --- a/renderer/providers/ReduxStore/slices/collections.js +++ b/renderer/providers/ReduxStore/slices/collections.js @@ -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; diff --git a/renderer/providers/Store/actions.js b/renderer/providers/Store/actions.js index 4d63f4ba..ce880c57 100644 --- a/renderer/providers/Store/actions.js +++ b/renderer/providers/Store/actions.js @@ -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, diff --git a/renderer/providers/Store/index.js b/renderer/providers/Store/index.js index 8d3bd73d..3ae70be9 100644 --- a/renderer/providers/Store/index.js +++ b/renderer/providers/Store/index.js @@ -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); diff --git a/renderer/providers/Store/reducer.js b/renderer/providers/Store/reducer.js index ad69cdce..6b0a6589 100644 --- a/renderer/providers/Store/reducer.js +++ b/renderer/providers/Store/reducer.js @@ -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) { diff --git a/renderer/utils.js b/renderer/utils.js deleted file mode 100644 index fe420184..00000000 --- a/renderer/utils.js +++ /dev/null @@ -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); -}; diff --git a/renderer/utils/network/index.js b/renderer/utils/network/index.js new file mode 100644 index 00000000..0f5f1d9e --- /dev/null +++ b/renderer/utils/network/index.js @@ -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 +};