feat: refactor codemirror bruno variables mode

This commit is contained in:
Anoop M D 2023-01-21 01:17:27 +05:30
parent 60c3d41c8e
commit 60fc13c765
12 changed files with 99 additions and 86 deletions

View File

@ -30,7 +30,6 @@ const StyledWrapper = styled.div`
.cm-variable-valid{color: green}
.cm-variable-invalid{color: red}
.cm-matchhighlight {background-color: yellow}
`;
export default StyledWrapper;

View File

@ -6,6 +6,9 @@
*/
import React from 'react';
import isEqual from 'lodash/isEqual';
import { getEnvironmentVariables } from 'utils/collections';
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
import StyledWrapper from './StyledWrapper';
let CodeMirror;
@ -15,7 +18,7 @@ if (!SERVER_RENDERED) {
CodeMirror = require('codemirror');
}
export default class QueryEditor extends React.Component {
export default class CodeEditor extends React.Component {
constructor(props) {
super(props);
@ -23,6 +26,7 @@ export default class QueryEditor extends React.Component {
// editor is updated, which can later be used to protect the editor from
// unnecessary updates during the update lifecycle.
this.cachedValue = props.value || '';
this.variables = {};
}
componentDidMount() {
@ -31,7 +35,6 @@ export default class QueryEditor extends React.Component {
lineNumbers: true,
lineWrapping: true,
tabSize: 2,
highlightSelectionMatches: { showToken: /\w/, annotateScrollbar: true },
mode: this.props.mode || 'application/ld+json',
keyMap: 'sublime',
autoCloseBrackets: true,
@ -93,7 +96,10 @@ export default class QueryEditor extends React.Component {
}
if(this.editor) {
this.addOverlay();
let variables = getEnvironmentVariables(this.props.collection);
if (!isEqual(variables, this.variables)) {
this.addOverlay();
}
}
if (this.props.theme !== prevProps.theme && this.editor) {
@ -122,37 +128,11 @@ export default class QueryEditor extends React.Component {
}
addOverlay = () => {
var variables = {
"host": "",
"token": ""
};
const mode = this.props.mode || 'application/ld+json';
CodeMirror.defineMode("brunovariables", function(config, parserConfig) {
let variablesOverlay = {
token: function(stream, state) {
if (stream.match("{{", true)) {
let ch;
let word = "";
while ((ch = stream.next()) != null) {
if (ch == "}" && stream.next() == "}") {
stream.eat("}");
if (word in variables) {
return "variable-valid";
} else {
return "variable-invalid";
}
}
word += ch;
}
}
while (stream.next() != null && !stream.match("{{", false)) {}
return null;
}
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || mode), variablesOverlay);
});
let variables = getEnvironmentVariables(this.props.collection);
this.variables = variables;
defineCodeMirrorBrunoVariablesMode(variables, mode);
this.editor.setOption('mode', 'brunovariables');
}

View File

@ -67,6 +67,7 @@ const GraphQLRequestPane = ({ item, collection, leftPaneWidth, onSchemaLoad, tog
switch (tab) {
case 'query': {
return <QueryEditor
collection={collection}
theme={storedTheme}
schema={schema}
width={leftPaneWidth}

View File

@ -29,6 +29,9 @@ const StyledWrapper = styled.div`
.cm-s-monokai span.cm-atom{
color: #569cd6 !important;
}
.cm-variable-valid{color: green}
.cm-variable-invalid{color: red}
`;
export default StyledWrapper;

View File

@ -6,7 +6,10 @@
*/
import React from 'react';
import isEqual from 'lodash/isEqual';
import MD from 'markdown-it';
import { getEnvironmentVariables } from 'utils/collections';
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
import StyledWrapper from './StyledWrapper';
import onHasCompletion from './onHasCompletion';
@ -29,6 +32,7 @@ export default class QueryEditor extends React.Component {
// editor is updated, which can later be used to protect the editor from
// unnecessary updates during the update lifecycle.
this.cachedValue = props.value || '';
this.variables = {};
}
componentDidMount() {
@ -129,6 +133,7 @@ export default class QueryEditor extends React.Component {
editor.on('hasCompletion', this._onHasCompletion);
editor.on('beforeChange', this._onBeforeChange);
}
this.addOverlay();
}
componentDidUpdate(prevProps) {
@ -152,6 +157,10 @@ export default class QueryEditor extends React.Component {
this.editor.setOption('theme', this.props.theme === 'dark' ? 'monokai' : 'default');
}
this.ignoreChangeEvent = false;
let variables = getEnvironmentVariables(this.props.collection);
if (!isEqual(variables, this.variables)) {
this.addOverlay();
}
}
componentWillUnmount() {
@ -163,6 +172,15 @@ export default class QueryEditor extends React.Component {
}
}
addOverlay = () => {
let variables = getEnvironmentVariables(this.props.collection);
this.variables = variables;
console.log(variables);
defineCodeMirrorBrunoVariablesMode(variables, "text/plain");
this.editor.setOption('mode', 'brunovariables');
}
render() {
return (
<StyledWrapper

View File

@ -45,7 +45,7 @@ const RequestBody = ({ item, collection }) => {
return (
<StyledWrapper className="w-full">
<CodeEditor theme={storedTheme} value={bodyContent[bodyMode] || ''} onEdit={onEdit} onRun={onRun} onSave={onSave} mode={codeMirrorMode[bodyMode]} />
<CodeEditor collection={collection} theme={storedTheme} value={bodyContent[bodyMode] || ''} onEdit={onEdit} onRun={onRun} onSave={onSave} mode={codeMirrorMode[bodyMode]} />
</StyledWrapper>
);
}

View File

@ -17,7 +17,7 @@ const QueryResult = ({ item, collection, value, width }) => {
return (
<StyledWrapper className="px-3 w-full" style={{ maxWidth: width }}>
<div className="h-full">
<CodeEditor theme={storedTheme} onRun={onRun} value={value || ''} readOnly />
<CodeEditor collection={collection} theme={storedTheme} onRun={onRun} value={value || ''} readOnly />
</div>
</StyledWrapper>
);

View File

@ -27,7 +27,6 @@ const StyledWrapper = styled.div`
.cm-variable-valid{color: green}
.cm-variable-invalid{color: red}
.cm-matchhighlight {background-color: yellow}
`;
export default StyledWrapper;

View File

@ -1,10 +1,16 @@
import React, { Component } from 'react';
import CodeMirror from 'codemirror';
import each from 'lodash/each';
import isEqual from 'lodash/isEqual';
import { findEnvironmentInCollection } from 'utils/collections';
import { getEnvironmentVariables } from 'utils/collections';
import { defineCodeMirrorBrunoVariablesMode } from 'utils/common/codemirror';
import StyledWrapper from './StyledWrapper';
let CodeMirror;
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
if (!SERVER_RENDERED) {
CodeMirror = require('codemirror');
}
class SingleLineEditor extends Component {
constructor(props) {
super(props);
@ -35,7 +41,7 @@ class SingleLineEditor extends Component {
}
componentDidUpdate(prevProps) {
let variables = this.getEnvironmentVariables();
let variables = getEnvironmentVariables(this.props.collection);
if (!isEqual(variables, this.variables)) {
this.addOverlay();
}
@ -45,52 +51,11 @@ class SingleLineEditor extends Component {
this.editor.getWrapperElement().remove();
}
getEnvironmentVariables = () => {
let variables = {};
const collection = this.props.collection;
if (collection) {
const environment = findEnvironmentInCollection(collection, collection.activeEnvironmentUid);
if (environment) {
each(environment.variables, (variable) => {
if(variable.name && variable.value && variable.enabled) {
variables[variable.name] = variable.value;
}
});
}
}
return variables;
}
addOverlay = () => {
let variables = this.getEnvironmentVariables();
let variables = getEnvironmentVariables(this.props.collection);
this.variables = variables;
CodeMirror.defineMode("brunovariables", function(config, parserConfig) {
let variablesOverlay = {
token: function(stream, state) {
if (stream.match("{{", true)) {
let ch;
let word = "";
while ((ch = stream.next()) != null) {
if (ch == "}" && stream.next() == "}") {
stream.eat("}");
if (word in variables) {
return "variable-valid";
} else {
return "variable-invalid";
}
}
word += ch;
}
}
while (stream.next() != null && !stream.match("{{", false)) {}
return null;
}
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || "text/plain"), variablesOverlay);
});
defineCodeMirrorBrunoVariablesMode(variables, "text/plain");
this.editor.setOption('mode', 'brunovariables');
}

View File

@ -18,15 +18,12 @@ if (!SERVER_RENDERED) {
require('codemirror/addon/fold/foldgutter');
require('codemirror/addon/mode/overlay');
require('codemirror/addon/hint/show-hint');
require('codemirror/addon/scroll/annotatescrollbar');
require('codemirror/keymap/sublime');
require('codemirror/addon/comment/comment');
require('codemirror/addon/edit/closebrackets');
require('codemirror/addon/search/search');
require('codemirror/addon/search/searchcursor');
require('codemirror/addon/search/jump-to-line');
require('codemirror/addon/search/matchesonscrollbar');
require('codemirror/addon/search/match-highlighter');
require('codemirror/addon/dialog/dialog');
require('codemirror-graphql/hint');

View File

@ -549,3 +549,19 @@ export const getDefaultRequestPaneTab = (item) => {
return 'query';
}
};
export const getEnvironmentVariables = (collection) => {
let variables = {};
if (collection) {
const environment = findEnvironmentInCollection(collection, collection.activeEnvironmentUid);
if (environment) {
each(environment.variables, (variable) => {
if(variable.name && variable.value && variable.enabled) {
variables[variable.name] = variable.value;
}
});
}
}
return variables;
}

View File

@ -0,0 +1,35 @@
let CodeMirror;
const SERVER_RENDERED = typeof navigator === 'undefined' || global['PREVENT_CODEMIRROR_RENDER'] === true;
if (!SERVER_RENDERED) {
CodeMirror = require('codemirror');
}
export const defineCodeMirrorBrunoVariablesMode = (variables, mode) => {
CodeMirror.defineMode("brunovariables", function(config, parserConfig) {
let variablesOverlay = {
token: function(stream, state) {
if (stream.match("{{", true)) {
let ch;
let word = "";
while ((ch = stream.next()) != null) {
if (ch == "}" && stream.next() == "}") {
stream.eat("}");
if (word in variables) {
return "variable-valid";
} else {
return "variable-invalid";
}
}
word += ch;
}
}
while (stream.next() != null && !stream.match("{{", false)) {}
return null;
}
};
return CodeMirror.overlayMode(CodeMirror.getMode(config, parserConfig.backdrop || mode), variablesOverlay);
});
};