Skip to content

Commit

Permalink
Add Code Editor Element for Configuration Forms (#49)
Browse files Browse the repository at this point in the history
* Update Constants and Types

* Update Components

* Update dashboard

* Update Readme and Changelog

* Fix Code Editor Height type
  • Loading branch information
mikhail-vl authored May 22, 2022
1 parent 06001b2 commit e0a6ea1
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 45 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Change Log

## 1.3.0 (IN PROGRESS)
## 1.3.0 (2022-05-22)

### Features / Enhancements

- Update Architecture Diagram (#44)
- Changing colors on Submit is not working properly (#43)
- Update layout to have sections for Form Fields (#47)
- Add None Request for Initial and Update requests (#48)
- Add Code Editor Element for Configuration Forms (#23)

## 1.2.0 (2022-05-19)

Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ grafana-cli --repo https://volkovlabs.io/plugins plugins install volkovlabs-form
## Features

- Provides functionality to create customizable forms with elements:
- Code Editor
- Date and Time
- Read-only (Disabled)
- Number Input
Expand All @@ -36,10 +37,11 @@ grafana-cli --repo https://volkovlabs.io/plugins plugins install volkovlabs-form
- Select with Custom options
- String Input
- Text Area
- Supports the Custom Code after Initial and Update requests.
- Supports the Custom Code for Initial and Update requests.
- Allows to specify GET request to get initial values and POST, PUT, PATCH request to send values updated in the form.
- Allows to add Header fields to Initial and Update requests.
- Allows to customize Submit, Reset buttons and form layout.
- Allows to split form elements into sections.

![API](https://raw.githubusercontent.com/volkovlabs/volkovlabs-form-panel/main/src/img/form-api.png)

Expand Down
52 changes: 28 additions & 24 deletions provisioning/dashboards/panels.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"iteration": 1653185845519,
"iteration": 1653239526614,
"links": [],
"liveNow": false,
"panels": [
Expand Down Expand Up @@ -86,7 +86,7 @@
"uid": "grafana"
},
"gridPos": {
"h": 7,
"h": 10,
"w": 7,
"x": 9,
"y": 0
Expand Down Expand Up @@ -143,7 +143,7 @@
"uid": "grafana"
},
"gridPos": {
"h": 7,
"h": 10,
"w": 8,
"x": 16,
"y": 0
Expand All @@ -163,12 +163,24 @@
{
"id": "second",
"title": "Second",
"type": "textarea"
"type": "textarea",
"value": "grgrgrg"
},
{
"id": "third",
"title": "Third",
"type": "boolean"
"type": "boolean",
"value": false
},
{
"id": "code",
"labelWidth": 10,
"language": "javascript",
"section": "",
"title": "Code",
"tooltip": "",
"type": "code",
"value": "rgregreg"
}
],
"initial": {
Expand Down Expand Up @@ -210,7 +222,7 @@
"uid": "grafana"
},
"gridPos": {
"h": 16,
"h": 19,
"w": 9,
"x": 0,
"y": 7
Expand All @@ -226,29 +238,25 @@
"id": "amount",
"title": "Amount",
"type": "number",
"unit": "Ghz",
"value": 30
"unit": "Ghz"
},
{
"id": "updated",
"title": "Updated",
"type": "boolean",
"value": false
"type": "boolean"
},
{
"id": "name",
"title": "Name",
"type": "string",
"value": "Name"
"type": "string"
},
{
"id": "step",
"max": 6,
"min": 0,
"step": 1,
"title": "Step",
"type": "slider",
"value": 4
"type": "slider"
},
{
"id": "select",
Expand Down Expand Up @@ -368,7 +376,7 @@
"h": 16,
"w": 15,
"x": 9,
"y": 7
"y": 10
},
"id": 13,
"options": {
Expand All @@ -382,22 +390,19 @@
"section": "Input",
"title": "Amount",
"type": "number",
"unit": "Ghz",
"value": 30
"unit": "Ghz"
},
{
"id": "updated",
"section": "Input",
"title": "Updated",
"type": "boolean",
"value": false
"type": "boolean"
},
{
"id": "name",
"section": "Output",
"title": "Name",
"type": "string",
"value": "Name"
"type": "string"
},
{
"id": "step",
Expand All @@ -407,8 +412,7 @@
"step": 1,
"title": "Step",
"type": "slider",
"unit": "",
"value": 4
"unit": ""
},
{
"id": "select",
Expand Down Expand Up @@ -558,6 +562,6 @@
"timezone": "",
"title": "Panels",
"uid": "O4tc_E6Gz",
"version": 2,
"version": 8,
"weekStart": ""
}
6 changes: 3 additions & 3 deletions src/components/CustomCodeEditor/CustomCodeEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { StandardEditorProps } from '@grafana/data';
import { CodeEditor } from '@grafana/ui';
import { CodeEditorHeight, CodeLanguageDefault } from '../../constants';
import { CodeEditorHeight, CodeLanguage } from '../../constants';

/**
* Properties
Expand All @@ -15,7 +15,7 @@ export const CustomCodeEditor: React.FC<Props> = ({ value, item, onChange }) =>
/**
* Language
*/
const language = item.settings?.language || CodeLanguageDefault;
const language = item.settings?.language || CodeLanguage.JAVASCRIPT;

/**
* Return
Expand All @@ -27,7 +27,7 @@ export const CustomCodeEditor: React.FC<Props> = ({ value, item, onChange }) =>
showLineNumbers={true}
showMiniMap={true}
value={value}
height={CodeEditorHeight}
height={`${CodeEditorHeight}px`}
onBlur={(code) => {
onChange(code);
}}
Expand Down
25 changes: 24 additions & 1 deletion src/components/FormElements/FormElements.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { ChangeEvent } from 'react';
import { DateTime, SelectableValue } from '@grafana/data';
import {
CodeEditor,
DateTimePicker,
InlineField,
InlineFieldRow,
Expand All @@ -11,7 +12,7 @@ import {
Slider,
TextArea,
} from '@grafana/ui';
import { BooleanElementOptions, FormElementType } from '../../constants';
import { BooleanElementOptions, CodeEditorHeight, CodeLanguage, FormElementType } from '../../constants';
import { LayoutSection, PanelOptions } from '../../types';

/**
Expand Down Expand Up @@ -146,6 +147,28 @@ export const FormElements: React.FC<Props> = ({ options, onOptionsChange, sectio
</InlineField>
)}

{element.type === FormElementType.CODE && (
<InlineField
label={element.title}
grow
labelWidth={element.labelWidth}
tooltip={element.tooltip}
transparent={!!!element.title}
>
<CodeEditor
language={element.language || CodeLanguage.JAVASCRIPT}
showLineNumbers={true}
showMiniMap={true}
value={element.value}
height={element.height || `${CodeEditorHeight}px`}
onBlur={(code) => {
element.value = code;
onOptionsChange(options);
}}
/>
</InlineField>
)}

{element.type === FormElementType.BOOLEAN && (
<InlineField
label={element.title}
Expand Down
39 changes: 38 additions & 1 deletion src/components/FormElementsEditor/FormElementsEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ import {
Input,
Select,
} from '@grafana/ui';
import { FormElementDefault, FormElementType, FormElementTypeOptions, SliderDefault } from '../../constants';
import {
CodeEditorHeight,
CodeLanguage,
CodeLanguageOptions,
FormElementDefault,
FormElementType,
FormElementTypeOptions,
SliderDefault,
} from '../../constants';
import { FormElement, LayoutSection } from '../../types';
import { MoveFormElements } from '../../utils';

Expand Down Expand Up @@ -306,6 +314,35 @@ export const FormElementsEditor: React.FC<Props> = ({ value: elements, onChange,
</InlineFieldRow>
)}

{element.type === FormElementType.CODE && (
<InlineFieldRow>
<InlineField label="Language" grow labelWidth={10}>
<Select
options={CodeLanguageOptions}
onChange={(event: SelectableValue) => {
element.language = event?.value;
onChange(elements);
}}
value={CodeLanguageOptions.find((language) => language.value === element.language)}
defaultValue={CodeLanguage.JAVASCRIPT}
/>
</InlineField>
<InlineField label="Height" labelWidth={12} tooltip="Code Editor height in px">
<Input
placeholder="Height"
onChange={(event: ChangeEvent<HTMLInputElement>) => {
element.height = Number(event.target.value);
onChange(elements);
}}
type="number"
value={element.height}
defaultValue={CodeEditorHeight}
min={0}
/>
</InlineField>
</InlineFieldRow>
)}

{(element.type === FormElementType.RADIO || element.type === FormElementType.SELECT) && (
<div>
{element.options?.map((option) => (
Expand Down
29 changes: 29 additions & 0 deletions src/constants/code-editor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { SelectableValue } from '@grafana/data';

/**
* Code Editor
*/
export const CodeEditorHeight = 100;
export const CodeEditorDefault = 'console.log(options, data, response, elements, locationService, templateService)';

/**
* Supported Languages
*/
export const enum CodeLanguage {
JAVASCRIPT = 'javascript',
JSON = 'json',
}

/**
* Code Language Options
*/
export const CodeLanguageOptions: SelectableValue[] = [
{
value: CodeLanguage.JAVASCRIPT,
label: 'Javascript',
},
{
value: CodeLanguage.JSON,
label: 'JSON',
},
];
7 changes: 0 additions & 7 deletions src/constants/default.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { FormElement } from '../types';
import { FormElementType } from './form-element';

/**
* Code Editor
*/
export const CodeEditorHeight = '100px';
export const CodeEditorDefault = 'console.log(options, data, response, elements, locationService, templateService)';
export const CodeLanguageDefault = 'javascript';

/**
* Submit Button
*/
Expand Down
13 changes: 9 additions & 4 deletions src/constants/form-element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@ export const enum FormElementType {
DATETIME = 'datetime',
DISABLED = 'disabled',
PASSWORD = 'password',
CODE = 'code',
}

/**
* Form Element Type Options
*/
export const FormElementTypeOptions: SelectableValue[] = [
{
value: FormElementType.DATETIME,
label: 'Date and Time',
value: FormElementType.CODE,
label: 'Code Editor',
},
{
value: FormElementType.DISABLED,
label: 'Read-only',
value: FormElementType.DATETIME,
label: 'Date and Time',
},
{
value: FormElementType.NUMBER,
Expand All @@ -49,6 +50,10 @@ export const FormElementTypeOptions: SelectableValue[] = [
value: FormElementType.RADIO,
label: 'Radio Group with Custom options',
},
{
value: FormElementType.DISABLED,
label: 'Read-only',
},
{
value: FormElementType.SELECT,
label: 'Select with Custom options',
Expand Down
1 change: 1 addition & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from './button';
export * from './code-editor';
export * from './default';
export * from './form-element';
export * from './layout';
Expand Down
Loading

0 comments on commit e0a6ea1

Please sign in to comment.