forked from extern/bruno
feat: request json body support
This commit is contained in:
parent
23910d3bb2
commit
7c2e909488
14
renderer/components/CodeEditor/StyledWrapper.js
Normal file
14
renderer/components/CodeEditor/StyledWrapper.js
Normal file
@ -0,0 +1,14 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const StyledWrapper = styled.div`
|
||||
div.CodeMirror {
|
||||
border: solid 1px var(--color-codemirror-border);
|
||||
}
|
||||
|
||||
textarea.cm-editor {
|
||||
position: relative;
|
||||
}
|
||||
`;
|
||||
|
||||
export default StyledWrapper;
|
||||
|
121
renderer/components/CodeEditor/index.js
Normal file
121
renderer/components/CodeEditor/index.js
Normal file
@ -0,0 +1,121 @@
|
||||
/**
|
||||
* Copyright (c) 2021 GraphQL Contributors.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
let CodeMirror;
|
||||
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
|
||||
|
||||
if (!SERVER_RENDERED) {
|
||||
CodeMirror = require('codemirror');
|
||||
}
|
||||
|
||||
export default class QueryEditor extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
// Keep a cached version of the value, this cache will be updated when the
|
||||
// editor is updated, which can later be used to protect the editor from
|
||||
// unnecessary updates during the update lifecycle.
|
||||
this.cachedValue = props.value || '';
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const editor = (this.editor = CodeMirror(this._node, {
|
||||
value: this.props.value || '',
|
||||
lineNumbers: true,
|
||||
lineWrapping: true,
|
||||
tabSize: 2,
|
||||
mode: 'application/ld+json',
|
||||
keyMap: 'sublime',
|
||||
autoCloseBrackets: true,
|
||||
matchBrackets: true,
|
||||
showCursorWhenSelecting: true,
|
||||
foldGutter: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
|
||||
readOnly: this.props.readOnly ? 'nocursor' : false,
|
||||
extraKeys: {
|
||||
'Cmd-Enter': () => {
|
||||
if (this.props.onChange) {
|
||||
// empty
|
||||
}
|
||||
},
|
||||
'Ctrl-Enter': () => {
|
||||
if (this.props.onChange) {
|
||||
// empty
|
||||
}
|
||||
},
|
||||
'Cmd-S': () => {
|
||||
if (this.props.onRunQuery) {
|
||||
// empty
|
||||
}
|
||||
},
|
||||
|
||||
'Ctrl-S': () => {
|
||||
if (this.props.onRunQuery) {
|
||||
// empty
|
||||
}
|
||||
}
|
||||
},
|
||||
}));
|
||||
if (editor) {
|
||||
editor.on('change', this._onEdit);
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
// Ensure the changes caused by this update are not interpretted as
|
||||
// user-input changes which could otherwise result in an infinite
|
||||
// event loop.
|
||||
this.ignoreChangeEvent = true;
|
||||
if (this.props.schema !== prevProps.schema && this.editor) {
|
||||
this.editor.options.lint.schema = this.props.schema;
|
||||
this.editor.options.hintOptions.schema = this.props.schema;
|
||||
this.editor.options.info.schema = this.props.schema;
|
||||
this.editor.options.jump.schema = this.props.schema;
|
||||
CodeMirror.signal(this.editor, 'change', this.editor);
|
||||
}
|
||||
if (
|
||||
this.props.value !== prevProps.value &&
|
||||
this.props.value !== this.cachedValue &&
|
||||
this.editor
|
||||
) {
|
||||
this.cachedValue = this.props.value;
|
||||
this.editor.setValue(this.props.value);
|
||||
}
|
||||
this.ignoreChangeEvent = false;
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
if (this.editor) {
|
||||
this.editor.off('change', this._onEdit);
|
||||
this.editor = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<StyledWrapper
|
||||
className="h-full"
|
||||
aria-label="Code Editor"
|
||||
ref={node => {
|
||||
this._node = node;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
_onEdit = () => {
|
||||
if (!this.ignoreChangeEvent && this.editor) {
|
||||
this.cachedValue = this.editor.getValue();
|
||||
if (this.props.onEdit) {
|
||||
this.props.onEdit(this.cachedValue);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -8,7 +8,7 @@ import StyledWrapper from './StyledWrapper';
|
||||
const HttpRequestPane = ({item, collection, leftPaneWidth}) => {
|
||||
return (
|
||||
<StyledWrapper className="h-full">
|
||||
<Tabs className='react-tabs mt-1 flex flex-grow flex-col h-full' forceRenderTabPanel>
|
||||
<Tabs className='react-tabs mt-1 flex flex-grow flex-col h-full'>
|
||||
<TabList>
|
||||
<Tab tabIndex="-1">Params</Tab>
|
||||
<Tab tabIndex="-1">Body</Tab>
|
||||
@ -19,7 +19,7 @@ const HttpRequestPane = ({item, collection, leftPaneWidth}) => {
|
||||
<QueryParams />
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<RequestBody />
|
||||
<RequestBody item={item} collection={collection}/>
|
||||
</TabPanel>
|
||||
<TabPanel>
|
||||
<RequestHeaders item={item} collection={collection}/>
|
||||
|
@ -1,11 +1,35 @@
|
||||
import React from 'react';
|
||||
import get from 'lodash/get';
|
||||
import CodeEditor from 'components/CodeEditor';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { requestChanged } from 'providers/ReduxStore/slices/tabs';
|
||||
import { updateRequestBody } from 'providers/ReduxStore/slices/collections';
|
||||
import RequestBodyMode from './RequestBodyMode';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const RequestBody = () => {
|
||||
const RequestBody = ({item, collection}) => {
|
||||
const dispatch = useDispatch();
|
||||
const bodyContent = item.draft ? get(item, 'draft.request.body.content') : get(item, 'request.body.content');
|
||||
|
||||
const onEdit = (value) => {
|
||||
dispatch(requestChanged({
|
||||
itemUid: item.uid,
|
||||
collectionUid: collection.uid
|
||||
}));
|
||||
dispatch(updateRequestBody({
|
||||
mode: 'json',
|
||||
content: value,
|
||||
itemUid: item.uid,
|
||||
collectionUid: collection.uid,
|
||||
}));
|
||||
};
|
||||
|
||||
return(
|
||||
<StyledWrapper className="mt-3">
|
||||
<RequestBodyMode />
|
||||
<div className="mt-4">
|
||||
<CodeEditor value={bodyContent || ''} onEdit={onEdit}/>
|
||||
</div>
|
||||
</StyledWrapper>
|
||||
);
|
||||
};
|
||||
|
@ -187,6 +187,23 @@ export const collectionsSlice = createSlice({
|
||||
item.draft.request.headers = filter(item.draft.request.headers, (h) => h.uid !== action.payload.headerUid);
|
||||
}
|
||||
}
|
||||
},
|
||||
updateRequestBody: (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 = cloneItem(item);
|
||||
}
|
||||
item.draft.request.body = {
|
||||
mode: action.payload.mode,
|
||||
content: action.payload.content
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -205,7 +222,8 @@ export const {
|
||||
requestUrlChanged,
|
||||
addRequestHeader,
|
||||
updateRequestHeader,
|
||||
deleteRequestHeader
|
||||
deleteRequestHeader,
|
||||
updateRequestBody
|
||||
} = collectionsSlice.actions;
|
||||
|
||||
export const loadCollectionsFromIdb = () => (dispatch) => {
|
||||
|
@ -40,6 +40,10 @@ const sendHttpRequest = async (request) => {
|
||||
headers: headers
|
||||
};
|
||||
|
||||
if(request.body && request.body.mode === 'json' && request.body.content) {
|
||||
options.data = request.body.content;
|
||||
}
|
||||
|
||||
ipcRenderer
|
||||
.invoke('send-http-request', options)
|
||||
.then(resolve)
|
||||
|
Loading…
Reference in New Issue
Block a user