diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js b/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js
index ee3145c06..a0ffb77db 100644
--- a/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js
+++ b/packages/bruno-app/src/components/RequestPane/GraphQLRequestPane/index.js
@@ -6,6 +6,7 @@ import { IconRefresh, IconLoader2, IconBook, IconDownload } from '@tabler/icons'
import { useSelector, useDispatch } from 'react-redux';
import { updateRequestPaneTab } from 'providers/ReduxStore/slices/tabs';
import QueryEditor from 'components/RequestPane/QueryEditor';
+import GraphQLVariables from 'components/RequestPane/GraphQLVariables';
import RequestHeaders from 'components/RequestPane/RequestHeaders';
import { useTheme } from 'providers/Theme';
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 activeTabUid = useSelector((state) => state.tabs.activeTabUid);
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 {
storedTheme
@@ -81,6 +83,9 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
onClickReference={handleGqlClickReference}
/>;
}
+ case 'variables': {
+ return ;
+ }
case 'headers': {
return ;
}
@@ -111,6 +116,9 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
selectTab('query')}>
Query
+ selectTab('variables')}>
+ Variables
+
selectTab('headers')}>
Headers
diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLVariables/StyledWrapper.js b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/StyledWrapper.js
new file mode 100644
index 000000000..9f7583222
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/StyledWrapper.js
@@ -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;
diff --git a/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js
new file mode 100644
index 000000000..f5c51c639
--- /dev/null
+++ b/packages/bruno-app/src/components/RequestPane/GraphQLVariables/index.js
@@ -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 (
+
+
+
+ );
+};
+
+export default GraphQLVariables;
diff --git a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
index a87db2ebb..31f421f41 100644
--- a/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
+++ b/packages/bruno-app/src/providers/ReduxStore/slices/collections/index.js
@@ -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) => {
const collection = findCollectionByUid(state.collections, action.payload.collectionUid);
@@ -865,6 +881,7 @@ export const {
updateRequestBodyMode,
updateRequestBody,
updateRequestGraphqlQuery,
+ updateRequestGraphqlVariables,
updateRequestScript,
updateRequestTests,
updateRequestMethod,
diff --git a/packages/bruno-lang/src/body-tag.js b/packages/bruno-lang/src/body-tag.js
index de4dbbc87..c51f435e2 100644
--- a/packages/bruno-lang/src/body-tag.js
+++ b/packages/bruno-lang/src/body-tag.js
@@ -11,6 +11,9 @@ const bodyJsonBegin = regex(/^body\s*\(\s*type\s*=\s*json\s*\)\s*\r?\n/);
// body(type=graphql)
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)
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) => {
return {
body: {
@@ -104,6 +117,7 @@ const bodyMultipartFormTag = between(bodyMultipartForm)(bodyEndRelaxed)(keyvalLi
module.exports = {
bodyJsonTag,
bodyGraphqlTag,
+ bodyGraphqlVarsTag,
bodyTextTag,
bodyXmlTag,
bodyFormUrlEncodedTagDeprecated,
diff --git a/packages/bruno-lang/src/index.js b/packages/bruno-lang/src/index.js
index 71511c366..877e8ce35 100644
--- a/packages/bruno-lang/src/index.js
+++ b/packages/bruno-lang/src/index.js
@@ -16,6 +16,7 @@ const headersTag = require('./headers-tag');
const {
bodyJsonTag,
bodyGraphqlTag,
+ bodyGraphqlVarsTag,
bodyTextTag,
bodyXmlTag,
bodyFormUrlEncodedTagDeprecated,
@@ -32,6 +33,7 @@ const bruToJson = (fileContents) => {
headersTag,
bodyJsonTag,
bodyGraphqlTag,
+ bodyGraphqlVarsTag,
bodyTextTag,
bodyXmlTag,
bodyFormUrlEncodedTagDeprecated,
@@ -80,6 +82,10 @@ const bruToJson = (fileContents) => {
body.graphql.query = outdentString(body.graphql.query);
}
+ if(body && body.graphql && body.graphql.variables) {
+ body.graphql.variables = outdentString(body.graphql.variables);
+ }
+
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) {
bru += `
body(type=text)