Skip to content

Commit

Permalink
Add Custom Values Editor (#44)
Browse files Browse the repository at this point in the history
* Add Custom Values Editor

* Revert container name

* Add throwing error during custom code execution

* Add CodeEditor disabled option

* Formatting

* Fix tests, update defaults for Values Editors

* Update Provisioning and Editor

* Update Custom to JavaScript

* Formatting

---------

Co-authored-by: Mikhail <[email protected]>
  • Loading branch information
asimonok and mikhail-vl authored Jun 28, 2023
1 parent f678dc0 commit 422da82
Show file tree
Hide file tree
Showing 23 changed files with 1,109 additions and 49 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- Migrate to Plugin Tools 1.5.2 (#42)
- Update to Node 18 and npm (#42)
- Add E2E Cypress testing (#43)
- Add JavaScript Values Editor (#44)

## 2.2.0 (2023-03-27)

Expand Down
86 changes: 85 additions & 1 deletion provisioning/dashboards/panels.json
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"overrides": []
},
"gridPos": {
"h": 19,
"h": 10,
"w": 12,
"x": 12,
"y": 0
Expand Down Expand Up @@ -179,6 +179,7 @@
"id": 4,
"options": {
"autoPlay": true,
"buttons": [],
"controls": true,
"height": 0,
"heightMode": "auto",
Expand Down Expand Up @@ -213,6 +214,89 @@
],
"title": "Image",
"type": "volkovlabs-image-panel"
},
{
"datasource": {
"type": "marcusolsson-static-datasource",
"uid": "P1D2C73DC01F2359B"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
}
},
"mappings": []
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 10
},
"id": 7,
"options": {
"displayLabels": ["name"],
"legend": {
"displayMode": "table",
"placement": "right",
"showLegend": true,
"values": ["percent"]
},
"pieType": "pie",
"reduceOptions": {
"calcs": ["lastNotNull"],
"fields": "",
"values": true
},
"tooltip": {
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "9.2.2",
"targets": [
{
"datasource": {
"type": "marcusolsson-static-datasource",
"uid": "P1D2C73DC01F2359B"
},
"frame": {
"fields": [
{
"config": {},
"name": "Name",
"type": "string",
"values": ["Graph", "Logs", "Node Graph", "Table", "Trace"]
},
{
"config": {},
"name": "Amount",
"type": "number",
"values": [10, 7, 3, 4, 2]
}
],
"meta": {
"custom": {
"customCode": "const values = [['Graph', 'Logs', 'Node Graph', 'Table', 'Trace'], [10, 7, 3, 4, 2]];\n\nconst result = {\n ...frame,\n fields: frame.fields.map((field, i) => ({\n ...field,\n values: values[i]\n }))\n}\n\nreturn Promise.resolve(result);",
"valuesEditor": "custom"
}
},
"name": "sales"
},
"refId": "A"
}
],
"title": "Custom Code",
"type": "piechart"
}
],
"refresh": "",
Expand Down
2 changes: 2 additions & 0 deletions provisioning/datasources/datasources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ datasources:
orgId: 1
version: 1
editable: true
jsonData:
codeEditorEnabled: true
84 changes: 84 additions & 0 deletions src/components/ConfigEditor/ConfigEditor.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import React from 'react';
import { DataSourceSettings } from '@grafana/data';
import { fireEvent, render, screen } from '@testing-library/react';
import { TestIds } from '../../constants';
import { StaticDataSourceOptions } from '../../types';
import { ConfigEditor } from './ConfigEditor';

/**
* Override Options
*/
interface OverrideOptions {
[key: string]: unknown;
jsonData?: object;
secureJsonData?: object | null;
}

/**
* Configuration Options
*/
const getOptions = ({
jsonData = {},
secureJsonData = {},
...overrideOptions
}: OverrideOptions = {}): DataSourceSettings<StaticDataSourceOptions, any> => ({
id: 1,
orgId: 2,
name: '',
typeLogoUrl: '',
type: '',
uid: '',
typeName: '',
access: '',
url: '',
user: '',
database: '',
basicAuth: false,
basicAuthUser: '',
isDefault: false,
secureJsonFields: {},
readOnly: false,
withCredentials: false,
...overrideOptions,
jsonData: {
codeEditorEnabled: false,
...jsonData,
},
secureJsonData: {
apiKey: '',
...secureJsonData,
},
});

/**
* Config Editor
*/
describe('ConfigEditor', () => {
const onChange = jest.fn();

beforeEach(() => {
onChange.mockReset();
});

/**
* Code Editor
*/
describe('Code Editor Enabled', () => {
it('Should change code editor enabled value', () => {
let appliedOptions = getOptions({ jsonData: { codeEditorEnabled: false } });
const onChange = jest.fn((options) => (appliedOptions = options));

const { rerender } = render(<ConfigEditor options={appliedOptions} onOptionsChange={onChange} />);

expect(screen.getByTestId(TestIds.configEditor.codeEditorEnabledContainer)).toBeInTheDocument();
expect(screen.getByLabelText(TestIds.configEditor.codeEditorEnabledOption('false'))).toBeChecked();

fireEvent.click(screen.getByLabelText(TestIds.configEditor.codeEditorEnabledOption('true')));

rerender(<ConfigEditor options={appliedOptions} onOptionsChange={onChange} />);

expect(screen.getByLabelText(TestIds.configEditor.codeEditorEnabledOption('false'))).not.toBeChecked();
expect(screen.getByLabelText(TestIds.configEditor.codeEditorEnabledOption('true'))).toBeChecked();
});
});
});
44 changes: 44 additions & 0 deletions src/components/ConfigEditor/ConfigEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { useCallback } from 'react';
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { FieldSet, InlineField, InlineFieldRow, RadioButtonGroup } from '@grafana/ui';
import { CodeEditorEnabledOptions, TestIds } from '../../constants';
import { StaticDataSourceOptions } from '../../types';

/**
* Editor Properties
*/
interface Props extends DataSourcePluginOptionsEditorProps<StaticDataSourceOptions> {}

/**
* Config Editor
*/
export const ConfigEditor: React.FC<Props> = ({ options, onOptionsChange }) => {
/**
* Code Editor Enabled Change
*/
const onChangeCodeEditorEnabled = useCallback(
(value: boolean) => {
onOptionsChange({
...options,
jsonData: {
codeEditorEnabled: value,
},
});
},
[onOptionsChange, options]
);

return (
<FieldSet data-testid={TestIds.configEditor.root}>
<InlineFieldRow>
<InlineField label="Code Editor" labelWidth={14} data-testid={TestIds.configEditor.codeEditorEnabledContainer}>
<RadioButtonGroup
options={CodeEditorEnabledOptions}
value={options.jsonData.codeEditorEnabled || false}
onChange={onChangeCodeEditorEnabled}
/>
</InlineField>
</InlineFieldRow>
</FieldSet>
);
};
1 change: 1 addition & 0 deletions src/components/ConfigEditor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './ConfigEditor';
Loading

0 comments on commit 422da82

Please sign in to comment.