feat: support for graphql variables

This commit is contained in:
Anoop M D 2023-02-01 09:23:11 +05:30
parent adedd08e8a
commit d4f05fa843
6 changed files with 106 additions and 0 deletions

View File

@ -6,6 +6,7 @@ import { IconRefresh, IconLoader2, IconBook, IconDownload } from '@tabler/icons'
import { useSelector, useDispatch } from 'react-redux'; import { useSelector, useDispatch } from 'react-redux';
import { updateRequestPaneTab } from 'providers/ReduxStore/slices/tabs'; import { updateRequestPaneTab } from 'providers/ReduxStore/slices/tabs';
import QueryEditor from 'components/RequestPane/QueryEditor'; import QueryEditor from 'components/RequestPane/QueryEditor';
import GraphQLVariables from 'components/RequestPane/GraphQLVariables';
import RequestHeaders from 'components/RequestPane/RequestHeaders'; import RequestHeaders from 'components/RequestPane/RequestHeaders';
import { useTheme } from 'providers/Theme'; import { useTheme } from 'providers/Theme';
import { updateRequestGraphqlQuery } from 'providers/ReduxStore/slices/collections'; import { updateRequestGraphqlQuery } from 'providers/ReduxStore/slices/collections';
@ -19,6 +20,7 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
const tabs = useSelector((state) => state.tabs.tabs); const tabs = useSelector((state) => state.tabs.tabs);
const activeTabUid = useSelector((state) => state.tabs.activeTabUid); const activeTabUid = useSelector((state) => state.tabs.activeTabUid);
const query = item.draft ? get(item, 'draft.request.body.graphql.query') : get(item, 'request.body.graphql.query'); const query = item.draft ? get(item, 'draft.request.body.graphql.query') : get(item, 'request.body.graphql.query');
const variables = item.draft ? get(item, 'draft.request.body.graphql.variables') : get(item, 'request.body.graphql.variables');
const url = item.draft ? get(item, 'draft.request.url') : get(item, 'request.url'); const url = item.draft ? get(item, 'draft.request.url') : get(item, 'request.url');
const { const {
storedTheme storedTheme
@ -81,6 +83,9 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
onClickReference={handleGqlClickReference} onClickReference={handleGqlClickReference}
/>; />;
} }
case 'variables': {
return <GraphQLVariables item={item} variables={variables} collection={collection} />;
}
case 'headers': { case 'headers': {
return <RequestHeaders item={item} collection={collection} />; return <RequestHeaders item={item} collection={collection} />;
} }
@ -111,6 +116,9 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
<div className={getTabClassname('query')} role="tab" onClick={() => selectTab('query')}> <div className={getTabClassname('query')} role="tab" onClick={() => selectTab('query')}>
Query Query
</div> </div>
<div className={getTabClassname('variables')} role="tab" onClick={() => selectTab('variables')}>
Variables
</div>
<div className={getTabClassname('headers')} role="tab" onClick={() => selectTab('headers')}> <div className={getTabClassname('headers')} role="tab" onClick={() => selectTab('headers')}>
Headers Headers
</div> </div>

View File

@ -0,0 +1,10 @@
import styled from 'styled-components';
const StyledWrapper = styled.div`
div.CodeMirror {
/* todo: find a better way */
height: calc(100vh - 220px);
}
`;
export default StyledWrapper;

View File

@ -0,0 +1,43 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import CodeEditor from 'components/CodeEditor';
import { updateRequestGraphqlVariables } from 'providers/ReduxStore/slices/collections';
import { sendRequest, saveRequest } from 'providers/ReduxStore/slices/collections/actions';
import { useTheme } from 'providers/Theme';
import StyledWrapper from './StyledWrapper';
const GraphQLVariables = ({ variables, item, collection }) => {
const dispatch = useDispatch();
const {
storedTheme
} = useTheme();
const onEdit = (value) => {
dispatch(
updateRequestGraphqlVariables({
variables: value,
itemUid: item.uid,
collectionUid: collection.uid
})
);
};
const onRun = () => dispatch(sendRequest(item, collection.uid));
const onSave = () => dispatch(saveRequest(item.uid, collection.uid));
return (
<StyledWrapper className="w-full">
<CodeEditor
collection={collection} value={variables || ''}
theme={storedTheme}
onEdit={onEdit}
mode='javascript'
onRun={onRun}
onSave={onSave}
/>
</StyledWrapper>
);
};
export default GraphQLVariables;

View File

@ -622,6 +622,22 @@ export const collectionsSlice = createSlice({
} }
} }
}, },
updateRequestGraphqlVariables: (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 = 'graphql';
item.draft.request.body.graphql = item.draft.request.body.graphql || {};
item.draft.request.body.graphql.variables = action.payload.variables;
}
}
},
updateRequestScript: (state, action) => { updateRequestScript: (state, action) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid); const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
@ -865,6 +881,7 @@ export const {
updateRequestBodyMode, updateRequestBodyMode,
updateRequestBody, updateRequestBody,
updateRequestGraphqlQuery, updateRequestGraphqlQuery,
updateRequestGraphqlVariables,
updateRequestScript, updateRequestScript,
updateRequestTests, updateRequestTests,
updateRequestMethod, updateRequestMethod,

View File

@ -11,6 +11,9 @@ const bodyJsonBegin = regex(/^body\s*\(\s*type\s*=\s*json\s*\)\s*\r?\n/);
// body(type=graphql) // body(type=graphql)
const bodyGraphqlBegin = regex(/^body\s*\(\s*type\s*=\s*graphql\s*\)\s*\r?\n/); const bodyGraphqlBegin = regex(/^body\s*\(\s*type\s*=\s*graphql\s*\)\s*\r?\n/);
// body(type=graphql-vars)
const bodyGraphqlVarsBegin = regex(/^body\s*\(\s*type\s*=\s*graphql-vars\s*\)\s*\r?\n/);
// body(type=text) // body(type=text)
const bodyTextBegin = regex(/^body\s*\(\s*type\s*=\s*text\s*\)\s*\r?\n/); const bodyTextBegin = regex(/^body\s*\(\s*type\s*=\s*text\s*\)\s*\r?\n/);
@ -37,6 +40,16 @@ const bodyGraphqlTag = between(bodyGraphqlBegin)(bodyEnd)(everyCharUntil(bodyEnd
} }
}); });
const bodyGraphqlVarsTag = between(bodyGraphqlVarsBegin)(bodyEnd)(everyCharUntil(bodyEnd)).map((varsGraphql) => {
return {
body: {
graphql: {
variables: varsGraphql
}
}
}
});
const bodyTextTag = between(bodyTextBegin)(bodyEnd)(everyCharUntil(bodyEnd)).map((bodyText) => { const bodyTextTag = between(bodyTextBegin)(bodyEnd)(everyCharUntil(bodyEnd)).map((bodyText) => {
return { return {
body: { body: {
@ -104,6 +117,7 @@ const bodyMultipartFormTag = between(bodyMultipartForm)(bodyEndRelaxed)(keyvalLi
module.exports = { module.exports = {
bodyJsonTag, bodyJsonTag,
bodyGraphqlTag, bodyGraphqlTag,
bodyGraphqlVarsTag,
bodyTextTag, bodyTextTag,
bodyXmlTag, bodyXmlTag,
bodyFormUrlEncodedTagDeprecated, bodyFormUrlEncodedTagDeprecated,

View File

@ -16,6 +16,7 @@ const headersTag = require('./headers-tag');
const { const {
bodyJsonTag, bodyJsonTag,
bodyGraphqlTag, bodyGraphqlTag,
bodyGraphqlVarsTag,
bodyTextTag, bodyTextTag,
bodyXmlTag, bodyXmlTag,
bodyFormUrlEncodedTagDeprecated, bodyFormUrlEncodedTagDeprecated,
@ -32,6 +33,7 @@ const bruToJson = (fileContents) => {
headersTag, headersTag,
bodyJsonTag, bodyJsonTag,
bodyGraphqlTag, bodyGraphqlTag,
bodyGraphqlVarsTag,
bodyTextTag, bodyTextTag,
bodyXmlTag, bodyXmlTag,
bodyFormUrlEncodedTagDeprecated, bodyFormUrlEncodedTagDeprecated,
@ -80,6 +82,10 @@ const bruToJson = (fileContents) => {
body.graphql.query = outdentString(body.graphql.query); body.graphql.query = outdentString(body.graphql.query);
} }
if(body && body.graphql && body.graphql.variables) {
body.graphql.variables = outdentString(body.graphql.variables);
}
return json; return json;
}; };
@ -139,6 +145,14 @@ ${indentString(body.graphql.query)}
`; `;
} }
if(body && body.graphql && body.graphql.variables) {
bru += `
body(type=graphql-vars)
${indentString(body.graphql.variables)}
/body
`;
}
if(body && body.text && body.text.length) { if(body && body.text && body.text.length) {
bru += ` bru += `
body(type=text) body(type=text)