diff --git a/package.json b/package.json
index 58989df..184ae01 100644
--- a/package.json
+++ b/package.json
@@ -6,6 +6,7 @@
"@grafana/runtime": "7.3.6",
"@grafana/toolkit": "7.3.6",
"@grafana/ui": "7.3.6",
+ "@monaco-editor/react": "^4.0.9",
"@types/enzyme": "^3.10.8",
"@types/enzyme-adapter-react-16": "^1.0.6",
"emotion": "10.0.27",
diff --git a/src/dashboards/redis-gears.json b/src/dashboards/redis-gears.json
index 81dae16..2414003 100644
--- a/src/dashboards/redis-gears.json
+++ b/src/dashboards/redis-gears.json
@@ -23,7 +23,7 @@
"type": "panel",
"id": "redis-gears-panel",
"name": "RedisGears",
- "version": "1.3.1"
+ "version": "1.1.0"
},
{
"type": "panel",
@@ -49,7 +49,7 @@
"gnetId": null,
"graphTooltip": 0,
"id": null,
- "iteration": 1611706223976,
+ "iteration": 1612064044040,
"links": [],
"panels": [
{
@@ -200,10 +200,6 @@
{
"color": "green",
"value": null
- },
- {
- "color": "red",
- "value": 80
}
]
}
@@ -293,18 +289,6 @@
}
]
},
- {
- "matcher": {
- "id": "byName",
- "options": "Last Error"
- },
- "properties": [
- {
- "id": "custom.width",
- "value": 99
- }
- ]
- },
{
"matcher": {
"id": "byName",
@@ -360,7 +344,8 @@
"command": "rg.dumpregistrations",
"query": "",
"refId": "A",
- "streaming": false,
+ "streaming": true,
+ "streamingDataType": "DataFrame",
"type": "gears"
}
],
@@ -462,5 +447,5 @@
"timezone": "",
"title": "RedisGears",
"uid": "xFPiNzLMz",
- "version": 2
+ "version": 1
}
diff --git a/src/redis-gears-panel/components/code-editor/code-editor.test.tsx b/src/redis-gears-panel/components/code-editor/code-editor.test.tsx
new file mode 100644
index 0000000..47dda4b
--- /dev/null
+++ b/src/redis-gears-panel/components/code-editor/code-editor.test.tsx
@@ -0,0 +1,90 @@
+import React from 'react';
+import { shallow } from 'enzyme';
+import Editor from '@monaco-editor/react';
+import { UnthemedCodeEditor } from './code-editor';
+
+/**
+ * Unthemed Code Editor
+ */
+describe('UnthemedCodeEditor', () => {
+ it('Should pass correct props', () => {
+ const onChange = jest.fn();
+ const wrapper = shallow(
+
+ );
+ const component = wrapper.find(Editor);
+ expect(component.prop('width')).toEqual(100);
+ expect(component.prop('height')).toEqual(200);
+ expect(component.prop('value')).toEqual('hello');
+ expect(component.prop('theme')).toEqual('vs-dark');
+ expect(component.prop('onChange')).toEqual(onChange);
+ expect(component.prop('options')).toEqual({
+ wordWrap: 'off',
+ codeLens: false,
+ minimap: {
+ enabled: undefined,
+ renderCharacters: false,
+ },
+ readOnly: false,
+ overviewRulerBorder: false,
+ automaticLayout: true,
+ glyphMargin: false,
+ folding: false,
+ lineNumbers: 'off',
+ lineDecorationsWidth: 5,
+ lineNumbersMinChars: 0,
+ });
+ });
+
+ it('Should pass correct props when lineNumbers are shown', () => {
+ const onChange = jest.fn();
+ const value =
+ "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.";
+ const wrapper = shallow(
+
+ );
+ const component = wrapper.find(Editor);
+ expect(component.prop('theme')).toEqual('vs-light');
+ expect(component.prop('language')).toEqual('python');
+ expect(component.prop('options')).toEqual({
+ wordWrap: 'off',
+ codeLens: false,
+ minimap: {
+ enabled: true,
+ renderCharacters: false,
+ },
+ readOnly: false,
+ overviewRulerBorder: false,
+ automaticLayout: true,
+ lineDecorationsWidth: 0,
+ lineNumbersMinChars: 4,
+ });
+ });
+
+ it('Should use correctly if value is undefined', () => {
+ const onChange = jest.fn();
+ const wrapper = shallow(
+
+ );
+ const component = wrapper.find(Editor);
+ expect(component.prop('value')).toEqual('');
+ });
+});
diff --git a/src/redis-gears-panel/components/code-editor/code-editor.tsx b/src/redis-gears-panel/components/code-editor/code-editor.tsx
new file mode 100644
index 0000000..2b0cb5a
--- /dev/null
+++ b/src/redis-gears-panel/components/code-editor/code-editor.tsx
@@ -0,0 +1,115 @@
+import React, { PureComponent } from 'react';
+import { Themeable, withTheme } from '@grafana/ui';
+import Editor from '@monaco-editor/react';
+
+/**
+ * Properties
+ */
+interface Props {
+ /**
+ * Width
+ *
+ * @type {number}
+ */
+ width: number;
+
+ /**
+ * Height
+ *
+ * @type {number}
+ */
+ height: number;
+
+ /**
+ * Value
+ *
+ * @type {string}
+ */
+ value?: string;
+
+ /**
+ * Show Mini map
+ *
+ * @type {boolean}
+ */
+ showMiniMap?: boolean;
+
+ /**
+ * Show Line numbers
+ *
+ * @type {boolean}
+ */
+ showLineNumbers?: boolean;
+
+ /**
+ * Language
+ *
+ * @type {string}
+ */
+ language?: string;
+
+ /**
+ * Read-only
+ *
+ * @type {boolean}
+ */
+ readOnly?: boolean;
+
+ /**
+ * On Change
+ */
+ onChange: (value?: string) => void;
+}
+
+/**
+ * Unthemed Code Editor
+ *
+ * @see https://github.com/suren-atoyan/monaco-react
+ */
+export class UnthemedCodeEditor extends PureComponent {
+ render() {
+ const { width, height, theme, showMiniMap, showLineNumbers, language = 'python', onChange, readOnly } = this.props;
+
+ /**
+ * Options similar to Grafana
+ */
+ const options: any = {
+ wordWrap: 'off',
+ codeLens: false, // not included in the bundle
+ minimap: {
+ enabled: showMiniMap,
+ renderCharacters: false,
+ },
+ readOnly: !!readOnly,
+ lineNumbersMinChars: 4,
+ lineDecorationsWidth: 0,
+ overviewRulerBorder: false,
+ automaticLayout: true,
+ };
+
+ /**
+ * Line numbers similar to Grafana
+ */
+ if (!showLineNumbers) {
+ options.glyphMargin = false;
+ options.folding = false;
+ options.lineNumbers = 'off';
+ options.lineDecorationsWidth = 5; // left margin when not showing line numbers
+ options.lineNumbersMinChars = 0;
+ }
+
+ return (
+
+ );
+ }
+}
+
+export const CodeEditor = withTheme(UnthemedCodeEditor);
diff --git a/src/redis-gears-panel/components/code-editor/index.ts b/src/redis-gears-panel/components/code-editor/index.ts
new file mode 100644
index 0000000..7201cee
--- /dev/null
+++ b/src/redis-gears-panel/components/code-editor/index.ts
@@ -0,0 +1 @@
+export { CodeEditor } from './code-editor';
diff --git a/src/redis-gears-panel/components/index.ts b/src/redis-gears-panel/components/index.ts
index 97804fd..d8da358 100644
--- a/src/redis-gears-panel/components/index.ts
+++ b/src/redis-gears-panel/components/index.ts
@@ -1 +1,2 @@
+export * from './code-editor';
export * from './redis-gears-panel';
diff --git a/src/redis-gears-panel/components/redis-gears-panel/redis-gears-panel.test.tsx b/src/redis-gears-panel/components/redis-gears-panel/redis-gears-panel.test.tsx
index d99648d..708f646 100644
--- a/src/redis-gears-panel/components/redis-gears-panel/redis-gears-panel.test.tsx
+++ b/src/redis-gears-panel/components/redis-gears-panel/redis-gears-panel.test.tsx
@@ -2,7 +2,8 @@ import React from 'react';
import { shallow } from 'enzyme';
import { Observable } from 'rxjs';
import { FieldType, LoadingState, toDataFrame } from '@grafana/data';
-import { Alert, Button, CodeEditor, Input, Switch, Table } from '@grafana/ui';
+import { Alert, Button, Input, Switch, Table } from '@grafana/ui';
+import { CodeEditor } from '../code-editor';
import { RedisGearsPanel } from './redis-gears-panel';
/**
@@ -52,7 +53,7 @@ describe('RedisGearsPanel', () => {
it('Should update script', () => {
const wrapper = shallow(getComponent());
const component = wrapper.find(CodeEditor);
- component.simulate('blur', 'myscript');
+ component.simulate('change', 'myscript');
expect(wrapper.state().script).toEqual('myscript');
});
diff --git a/src/redis-gears-panel/components/redis-gears-panel/redis-gears-panel.tsx b/src/redis-gears-panel/components/redis-gears-panel/redis-gears-panel.tsx
index 5171648..5768fd1 100644
--- a/src/redis-gears-panel/components/redis-gears-panel/redis-gears-panel.tsx
+++ b/src/redis-gears-panel/components/redis-gears-panel/redis-gears-panel.tsx
@@ -15,8 +15,9 @@ import {
toDataFrame,
} from '@grafana/data';
import { getDataSourceSrv, toDataQueryError } from '@grafana/runtime';
-import { Alert, Button, CodeEditor, InlineField, InlineFormLabel, Input, Switch, Table } from '@grafana/ui';
+import { Alert, Button, InlineField, InlineFormLabel, Input, Switch, Table } from '@grafana/ui';
import { PanelOptions } from '../../types';
+import { CodeEditor } from '../code-editor';
/**
* Properties
@@ -117,7 +118,7 @@ export class RedisGearsPanel extends PureComponent {
*
* @param script
*/
- onChangeScript = (script: string) => {
+ onChangeScript = (script = '') => {
this.setState({
script,
});
@@ -293,9 +294,8 @@ export class RedisGearsPanel extends PureComponent {
language="python"
width={width}
height={height - footerHeight}
- onBlur={this.onChangeScript}
- onSave={this.onChangeScript}
- showMiniMap={false}
+ onChange={this.onChangeScript}
+ showMiniMap={true}
showLineNumbers={true}
/>
diff --git a/src/redis-gears-panel/constants.ts b/src/redis-gears-panel/constants.ts
index a7a1d1c..44399c4 100644
--- a/src/redis-gears-panel/constants.ts
+++ b/src/redis-gears-panel/constants.ts
@@ -1,4 +1,4 @@
/**
* Default script
*/
-export const DefaultScript = 'GB().run()';
+export const DefaultScript = 'gb = GearsBuilder()';
diff --git a/yarn.lock b/yarn.lock
index efa0195..9002702 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1470,6 +1470,22 @@
"@types/yargs" "^15.0.0"
chalk "^4.0.0"
+"@monaco-editor/loader@^1.0.0":
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/@monaco-editor/loader/-/loader-1.0.0.tgz#c7ea78ef07cebcae83d92bbfe2bddab563468102"
+ integrity sha512-CA35bf5Y7wFWfeJZfkLslOxiatln3oTBKkfbdo+TF5H+UdPP96qHvhOUjjd1DeQ2NWsRkVPSnoSYek7NE5B26w==
+ dependencies:
+ state-local "^1.0.6"
+
+"@monaco-editor/react@^4.0.9":
+ version "4.0.9"
+ resolved "https://registry.yarnpkg.com/@monaco-editor/react/-/react-4.0.9.tgz#77f3170c6c8409efe6b450467748f0df4f64d6b2"
+ integrity sha512-mTDqf47FsPnud/Ct3ekKqSFxmytkk4oMVIPUFMJF9iJcKH5AoqXs1oobXtPoVWiL9uWePatBNVCFv1pg4AqZuA==
+ dependencies:
+ "@monaco-editor/loader" "^1.0.0"
+ prop-types "^15.7.2"
+ state-local "^1.0.7"
+
"@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@@ -11612,6 +11628,11 @@ stack-utils@^1.0.1:
dependencies:
escape-string-regexp "^2.0.0"
+state-local@^1.0.6, state-local@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/state-local/-/state-local-1.0.7.tgz#da50211d07f05748d53009bee46307a37db386d5"
+ integrity sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==
+
static-extend@^0.1.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6"