diff --git a/renderer/components/CodeEditor/index.js b/renderer/components/CodeEditor/index.js index 07a577ba..721e7590 100644 --- a/renderer/components/CodeEditor/index.js +++ b/renderer/components/CodeEditor/index.js @@ -31,7 +31,7 @@ export default class QueryEditor extends React.Component { lineNumbers: true, lineWrapping: true, tabSize: 2, - mode: 'application/ld+json', + mode: this.props.mode || 'application/ld+json', keyMap: 'sublime', autoCloseBrackets: true, matchBrackets: true, @@ -89,6 +89,7 @@ export default class QueryEditor extends React.Component { ) { this.cachedValue = this.props.value; this.editor.setValue(this.props.value); + this.editor.setOption("mode", this.props.mode); } this.ignoreChangeEvent = false; } diff --git a/renderer/components/RequestPane/HttpRequestPane/index.js b/renderer/components/RequestPane/HttpRequestPane/index.js index af27bbef..d5ea6337 100644 --- a/renderer/components/RequestPane/HttpRequestPane/index.js +++ b/renderer/components/RequestPane/HttpRequestPane/index.js @@ -67,7 +67,7 @@ const HttpRequestPane = ({item, collection, leftPaneWidth}) => { {/*
selectTab('auth')}>Auth
*/} {focusedTab.requestPaneTab === 'body' ? (
- +
) : null } diff --git a/renderer/components/RequestPane/RequestBody/RequestBodyMode/index.js b/renderer/components/RequestPane/RequestBody/RequestBodyMode/index.js index dd340e88..663fbd99 100644 --- a/renderer/components/RequestPane/RequestBody/RequestBodyMode/index.js +++ b/renderer/components/RequestPane/RequestBody/RequestBodyMode/index.js @@ -1,20 +1,35 @@ import React, { useRef, forwardRef } from 'react'; +import get from 'lodash/get'; import { IconCaretDown } from '@tabler/icons'; import Dropdown from 'components/Dropdown'; +import { useDispatch } from 'react-redux'; +import { updateRequestBodyMode } from 'providers/ReduxStore/slices/collections'; +import { humanizeRequestBodyMode } from 'utils/collections'; import StyledWrapper from './StyledWrapper'; -const RequestBodyMode = () => { +const RequestBodyMode = ({item, collection}) => { + const dispatch = useDispatch(); const dropdownTippyRef = useRef(); const onDropdownCreate = (ref) => dropdownTippyRef.current = ref; + const bodyMode = item.draft ? get(item, 'draft.request.body.mode') : get(item, 'request.body.mode'); + const Icon = forwardRef((props, ref) => { return (
- JSON + {humanizeRequestBodyMode(bodyMode)}
); }); + const onModeChange = (value) => { + dispatch(updateRequestBodyMode({ + itemUid: item.uid, + collectionUid: collection.uid, + mode: value + })); + }; + return(
@@ -24,11 +39,13 @@ const RequestBodyMode = () => {
{ dropdownTippyRef.current.hide(); + onModeChange('multipartForm'); }}> Multipart Form
{ dropdownTippyRef.current.hide(); + onModeChange('formUrlEncoded'); }}> Form Url Encoded
@@ -37,16 +54,19 @@ const RequestBodyMode = () => {
{ dropdownTippyRef.current.hide(); + onModeChange('json'); }}> JSON
{ dropdownTippyRef.current.hide(); + onModeChange('xml'); }}> XML
{ dropdownTippyRef.current.hide(); + onModeChange('text'); }}> TEXT
@@ -55,6 +75,7 @@ const RequestBodyMode = () => {
{ dropdownTippyRef.current.hide(); + onModeChange('none'); }}> No Body
diff --git a/renderer/components/RequestPane/RequestBody/index.js b/renderer/components/RequestPane/RequestBody/index.js index 75a79d78..16073db0 100644 --- a/renderer/components/RequestPane/RequestBody/index.js +++ b/renderer/components/RequestPane/RequestBody/index.js @@ -7,11 +7,11 @@ import StyledWrapper from './StyledWrapper'; const RequestBody = ({item, collection}) => { const dispatch = useDispatch(); - const bodyContent = item.draft ? get(item, 'draft.request.body.content') : get(item, 'request.body.content'); + const body = item.draft ? get(item, 'draft.request.body') : get(item, 'request.body'); + const bodyMode = item.draft ? get(item, 'draft.request.body.mode') : get(item, 'request.body.mode'); const onEdit = (value) => { dispatch(updateRequestBody({ - mode: 'json', content: value, itemUid: item.uid, collectionUid: collection.uid, @@ -19,11 +19,37 @@ const RequestBody = ({item, collection}) => { }; const onRun = () => dispatch(sendRequest(item, collection.uid));; - const onSave = () => dispatch(saveRequest(item.uid, collection.uid));; + const onSave = () => dispatch(saveRequest(item.uid, collection.uid)); + + if(['json', 'xml', 'text'].includes(bodyMode)) { + let codeMirrorMode = { + json: 'application/ld+json', + text: 'application/text', + xml: 'application/xml' + }; + + let bodyContent = { + json: body.json, + text: body.text, + xml: body.xml + }; + + return( + + + + ); + } return( - + No Body ); }; diff --git a/renderer/pageComponents/Index/index.js b/renderer/pageComponents/Index/index.js index db273389..1f86a1cd 100644 --- a/renderer/pageComponents/Index/index.js +++ b/renderer/pageComponents/Index/index.js @@ -9,7 +9,7 @@ import StyledWrapper from './StyledWrapper'; const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true; if(!SERVER_RENDERED) { require('codemirror/mode/javascript/javascript'); - require('codemirror/mode/javascript/javascript'); + require('codemirror/mode/xml/xml'); require('codemirror/addon/edit/matchbrackets'); require('codemirror/addon/fold/brace-fold'); require('codemirror/addon/fold/foldgutter'); diff --git a/renderer/providers/ReduxStore/slices/collections.js b/renderer/providers/ReduxStore/slices/collections.js index dc1bb4de..afe75bc3 100644 --- a/renderer/providers/ReduxStore/slices/collections.js +++ b/renderer/providers/ReduxStore/slices/collections.js @@ -343,6 +343,20 @@ export const collectionsSlice = createSlice({ } } }, + updateRequestBodyMode: (state, action) => { + const collection = findCollectionByUid(state.collections, action.payload.collectionUid); + + if(collection) { + const item = findItemInCollection(collection, action.payload.itemUid); + + if(item && isItemARequest(item)) { + if(!item.draft) { + item.draft = cloneDeep(item); + } + item.draft.request.body.mode = action.payload.mode; + } + } + }, updateRequestBody: (state, action) => { const collection = findCollectionByUid(state.collections, action.payload.collectionUid); @@ -353,9 +367,27 @@ export const collectionsSlice = createSlice({ if(!item.draft) { item.draft = cloneDeep(item); } - item.draft.request.body = { - mode: action.payload.mode, - content: action.payload.content + switch(item.draft.request.body.mode) { + case 'json': { + item.draft.request.body.json = action.payload.content; + break; + } + case 'text': { + item.draft.request.body.text = action.payload.content; + break; + } + case 'xml': { + item.draft.request.body.xml = action.payload.content; + break; + } + case 'formUrlEncoded': { + item.draft.request.body.formUrlEncoded = action.payload.content; + break; + } + case 'multipartForm': { + item.draft.request.body.multipartForm = action.payload.content; + break; + } } } } @@ -397,6 +429,7 @@ export const { addRequestHeader, updateRequestHeader, deleteRequestHeader, + updateRequestBodyMode, updateRequestBody, updateRequestMethod } = collectionsSlice.actions; @@ -520,7 +553,11 @@ export const newHttpRequest = (params) => (dispatch, getState) => { headers: [], body: { mode: 'none', - content: '' + json: null, + text: null, + xml: null, + multipartForm: null, + formUrlEncoded: null } } }; diff --git a/renderer/utils/collections/index.js b/renderer/utils/collections/index.js index f42e8e81..550a9eee 100644 --- a/renderer/utils/collections/index.js +++ b/renderer/utils/collections/index.js @@ -147,7 +147,11 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => { params: copyQueryParams(si.draft.request.params), body: { mode: si.draft.request.body.mode, - content: replaceTabsWithSpaces(si.draft.request.body.content) + json: si.draft.request.body.json, + text: si.draft.request.body.text, + xml: si.draft.request.body.xml, + multipartForm: si.draft.request.body.multipartForm, + xmformUrlEncodedl: si.draft.request.body.formUrlEncoded } }; } @@ -160,14 +164,18 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => { params: copyQueryParams(si.request.params), body: { mode: si.request.body.mode, - content: replaceTabsWithSpaces(si.request.body.content) + json: si.request.body.json, + text: si.request.body.text, + xml: si.request.body.xml, + multipartForm: si.request.body.multipartForm, + xmformUrlEncodedl: si.request.body.formUrlEncoded } } }; } if(di.request && di.request.body.mode === 'json') { - di.request.body.content = replaceTabsWithSpaces(di.request.body.content); + di.request.body.json = replaceTabsWithSpaces(di.request.body.json); } destItems.push(di); @@ -214,3 +222,31 @@ export const isItemARequest = (item) => { export const isItemAFolder = (item) => { return !item.hasOwnProperty('request') && item.type === 'folder'; }; + +export const humanizeRequestBodyMode = (mode) => { + let label = 'No Body'; + switch(mode) { + case 'json': { + label = 'JSON'; + break; + } + case 'text': { + label = 'TEXT'; + break; + } + case 'xml': { + label = 'XML'; + break; + } + case 'formUrlEncoded': { + label = 'Form Url Encoded'; + break; + } + case 'multipartForm': { + label = 'Multipart Form'; + break; + } + } + + return label; +}; diff --git a/renderer/utils/network/index.js b/renderer/utils/network/index.js index 937d78df..7f2d1610 100644 --- a/renderer/utils/network/index.js +++ b/renderer/utils/network/index.js @@ -39,9 +39,26 @@ const sendHttpRequest = async (request) => { headers: headers }; - if(request.body && request.body.mode === 'json' && request.body.content) { - options.data = JSON.parse(request.body.content); + if(request.body.mode === 'json') { + options.headers['Content-Type'] = 'application/json'; + try { + options.data = JSON.parse(request.body.json); + } catch (ex) { + options.data = request.body.json; + } } + + if(request.body.mode === 'text') { + options.headers['Content-Type'] = 'text/plain'; + options.data = request.body.text; + } + + if(request.body.mode === 'xml') { + options.headers['Content-Type'] = 'text/xml'; + options.data = request.body.xml; + } + + console.log('>>> Sending Request'); console.log(request); ipcRenderer