mirror of
https://github.com/usebruno/bruno.git
synced 2024-11-21 23:43:15 +01:00
feat: support for sending url encoded params (resolves #11)
This commit is contained in:
parent
7f0f496bb4
commit
bd153bf849
8
package-lock.json
generated
8
package-lock.json
generated
@ -7190,6 +7190,14 @@
|
||||
"postcss-selector-parser": "^6.0.6"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.11.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz",
|
||||
"integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==",
|
||||
"requires": {
|
||||
"side-channel": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"querystring-es3": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
|
||||
|
@ -46,6 +46,7 @@
|
||||
"mousetrap": "^1.6.5",
|
||||
"nanoid": "^3.1.30",
|
||||
"next": "12.0.4",
|
||||
"qs": "^6.11.0",
|
||||
"react": "17.0.2",
|
||||
"react-dom": "17.0.2",
|
||||
"react-redux": "^7.2.6",
|
||||
|
@ -0,0 +1,45 @@
|
||||
import styled from 'styled-components';
|
||||
|
||||
const Wrapper = styled.div`
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-weight: 600;
|
||||
|
||||
thead, td {
|
||||
border: 1px solid #efefef;
|
||||
}
|
||||
|
||||
thead {
|
||||
color: #616161;
|
||||
font-size: 0.8125rem;
|
||||
user-select: none;
|
||||
}
|
||||
td {
|
||||
padding: 6px 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.btn-add-param {
|
||||
font-size: 0.8125rem;
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
width: 100%;
|
||||
border: solid 1px transparent;
|
||||
outline: none !important;
|
||||
|
||||
&:focus{
|
||||
outline: none !important;
|
||||
border: solid 1px transparent;
|
||||
}
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
}
|
||||
`;
|
||||
|
||||
export default Wrapper;
|
119
renderer/components/RequestPane/FormUrlEncodedParams/index.js
Normal file
119
renderer/components/RequestPane/FormUrlEncodedParams/index.js
Normal file
@ -0,0 +1,119 @@
|
||||
import React from 'react';
|
||||
import get from 'lodash/get';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import { IconTrash } from '@tabler/icons';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { addFormUrlEncodedParam, updateFormUrlEncodedParam, deleteFormUrlEncodedParam } from 'providers/ReduxStore/slices/collections';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
|
||||
const FormUrlEncodedParams = ({item, collection}) => {
|
||||
const dispatch = useDispatch();
|
||||
const params = item.draft ? get(item, 'draft.request.body.formUrlEncoded') : get(item, 'request.body.formUrlEncoded');
|
||||
|
||||
const addParam = () => {
|
||||
dispatch(addFormUrlEncodedParam({
|
||||
itemUid: item.uid,
|
||||
collectionUid: collection.uid,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleParamChange = (e, _param, type) => {
|
||||
const param = cloneDeep(_param);
|
||||
switch(type) {
|
||||
case 'name' : {
|
||||
param.name = e.target.value;
|
||||
break;
|
||||
}
|
||||
case 'value' : {
|
||||
param.value = e.target.value;
|
||||
break;
|
||||
}
|
||||
case 'description' : {
|
||||
param.description = e.target.value;
|
||||
break;
|
||||
}
|
||||
case 'enabled' : {
|
||||
param.enabled = e.target.checked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dispatch(updateFormUrlEncodedParam({
|
||||
param: param,
|
||||
itemUid: item.uid,
|
||||
collectionUid: collection.uid
|
||||
}));
|
||||
};
|
||||
|
||||
const handleRemoveParams = (param) => {
|
||||
dispatch(deleteFormUrlEncodedParam({
|
||||
paramUid: param.uid,
|
||||
itemUid: item.uid,
|
||||
collectionUid: collection.uid
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<StyledWrapper className="w-full">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<td>Key</td>
|
||||
<td>Value</td>
|
||||
<td>Description</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{params && params.length ? params.map((param, index) => {
|
||||
return (
|
||||
<tr key={param.uid}>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false"
|
||||
value={param.name}
|
||||
className="mousetrap"
|
||||
onChange={(e) => handleParamChange(e, param, 'name')}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false"
|
||||
value={param.value}
|
||||
className="mousetrap"
|
||||
onChange={(e) => handleParamChange(e, param, 'value')}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<input
|
||||
type="text"
|
||||
autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck="false"
|
||||
value={param.description}
|
||||
className="mousetrap"
|
||||
onChange={(e) => handleParamChange(e, param, 'description')}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div className="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={param.enabled}
|
||||
className="mr-3 mousetrap"
|
||||
onChange={(e) => handleParamChange(e, param, 'enabled')}
|
||||
/>
|
||||
<button onClick={() => handleRemoveParams(param)}>
|
||||
<IconTrash strokeWidth={1.5} size={20}/>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
}) : null}
|
||||
</tbody>
|
||||
</table>
|
||||
<button className="btn-add-param text-link pr-2 py-3 mt-2 select-none" onClick={addParam}>+ Add Param</button>
|
||||
</StyledWrapper>
|
||||
)
|
||||
};
|
||||
export default FormUrlEncodedParams;
|
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import get from 'lodash/get';
|
||||
import CodeEditor from 'components/CodeEditor';
|
||||
import FormUrlEncodedParams from 'components/RequestPane/FormUrlEncodedParams';
|
||||
import { useDispatch } from 'react-redux';
|
||||
import { updateRequestBody, sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections';
|
||||
import StyledWrapper from './StyledWrapper';
|
||||
@ -47,6 +48,10 @@ const RequestBody = ({item, collection}) => {
|
||||
);
|
||||
}
|
||||
|
||||
if(bodyMode === 'formUrlEncoded') {
|
||||
return <FormUrlEncodedParams item={item} collection={collection}/>;
|
||||
}
|
||||
|
||||
return(
|
||||
<StyledWrapper className="w-full">
|
||||
No Body
|
||||
|
@ -343,6 +343,61 @@ export const collectionsSlice = createSlice({
|
||||
}
|
||||
}
|
||||
},
|
||||
addFormUrlEncodedParam: (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.formUrlEncoded = item.draft.request.body.formUrlEncoded || [];
|
||||
item.draft.request.body.formUrlEncoded.push({
|
||||
uid: uuid(),
|
||||
name: '',
|
||||
value: '',
|
||||
description: '',
|
||||
enabled: true
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
updateFormUrlEncodedParam: (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);
|
||||
}
|
||||
const param = find(item.draft.request.body.formUrlEncoded, (p) => p.uid === action.payload.param.uid);
|
||||
if(param) {
|
||||
param.name = action.payload.param.name;
|
||||
param.value = action.payload.param.value;
|
||||
param.description = action.payload.param.description;
|
||||
param.enabled = action.payload.param.enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
deleteFormUrlEncodedParam: (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.formUrlEncoded = filter(item.draft.request.body.formUrlEncoded, (p) => p.uid !== action.payload.paramUid);
|
||||
}
|
||||
}
|
||||
},
|
||||
updateRequestBodyMode: (state, action) => {
|
||||
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
|
||||
|
||||
@ -429,6 +484,9 @@ export const {
|
||||
addRequestHeader,
|
||||
updateRequestHeader,
|
||||
deleteRequestHeader,
|
||||
addFormUrlEncodedParam,
|
||||
updateFormUrlEncodedParam,
|
||||
deleteFormUrlEncodedParam,
|
||||
updateRequestBodyMode,
|
||||
updateRequestBody,
|
||||
updateRequestMethod
|
||||
|
@ -128,6 +128,18 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
||||
});
|
||||
};
|
||||
|
||||
const copyFormUrlEncodedParams = (params = []) => {
|
||||
return map(params, (param) => {
|
||||
return {
|
||||
uid: param.uid,
|
||||
name: param.name,
|
||||
value: param.value,
|
||||
description: param.description,
|
||||
enabled: param.enabled
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const copyItems = (sourceItems, destItems) => {
|
||||
each(sourceItems, (si) => {
|
||||
const di = {
|
||||
@ -151,7 +163,7 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
||||
text: si.draft.request.body.text,
|
||||
xml: si.draft.request.body.xml,
|
||||
multipartForm: si.draft.request.body.multipartForm,
|
||||
xmformUrlEncodedl: si.draft.request.body.formUrlEncoded
|
||||
formUrlEncoded: copyFormUrlEncodedParams(si.draft.request.body.formUrlEncoded)
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -168,7 +180,7 @@ export const transformCollectionToSaveToIdb = (collection, options = {}) => {
|
||||
text: si.request.body.text,
|
||||
xml: si.request.body.xml,
|
||||
multipartForm: si.request.body.multipartForm,
|
||||
xmformUrlEncodedl: si.request.body.formUrlEncoded
|
||||
formUrlEncoded: copyFormUrlEncodedParams(si.request.body.formUrlEncoded)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -1,4 +1,6 @@
|
||||
import each from 'lodash/each';
|
||||
import filter from 'lodash/filter';
|
||||
import qs from 'qs';
|
||||
import { rawRequest, gql } from 'graphql-request';
|
||||
|
||||
const sendNetworkRequest = async (item) => {
|
||||
@ -58,8 +60,16 @@ const sendHttpRequest = async (request) => {
|
||||
options.data = request.body.xml;
|
||||
}
|
||||
|
||||
if(request.body.mode === 'formUrlEncoded') {
|
||||
options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
|
||||
const params = {};
|
||||
const enabledParams = filter(request.body.formUrlEncoded, p => p.enabled);
|
||||
each(enabledParams, (p) => params[p.name] = p.value);
|
||||
options.data = qs.stringify(params);
|
||||
}
|
||||
|
||||
console.log('>>> Sending Request');
|
||||
console.log(request);
|
||||
console.log(options);
|
||||
|
||||
ipcRenderer
|
||||
.invoke('send-http-request', options)
|
||||
|
Loading…
Reference in New Issue
Block a user