Skip to content

Commit

Permalink
Update new lines in Text Area and Code Editor (#563)
Browse files Browse the repository at this point in the history
* convert value for CODE and TEXTAREA

* ci tests added

* update code editor

* package lock

* Update CHANGELOG.md

---------

Co-authored-by: Mikhail Volkov <[email protected]>
vitPinchuk and mikhail-vl authored Dec 9, 2024
1 parent 6e99bf8 commit 4471ba8
Showing 7 changed files with 130 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@

- Updated change value behavior for custom option (#562)
- Added form-element of type color (#561)
- Updated new lines in Text Area and Code Editor (#563)

## 4.9.0 (2024-11-16)

12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@
"@grafana/scenes": "^5.20.4",
"@grafana/ui": "^11.3.0",
"@hello-pangea/dnd": "^17.0.0",
"@volkovlabs/components": "^3.5.0",
"@volkovlabs/components": "^3.6.0",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"semver": "^7.6.3",
25 changes: 17 additions & 8 deletions src/components/CustomCodeEditor/CustomCodeEditor.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { getTemplateSrv } from '@grafana/runtime';
import { CodeEditor, CodeEditorSuggestionItemKind } from '@grafana/ui';
import { CodeEditorSuggestionItemKind } from '@grafana/ui';
import { render, screen } from '@testing-library/react';
import { AutosizeCodeEditor } from '@volkovlabs/components';
import React, { useEffect } from 'react';

import { CODE_EDITOR_SUGGESTIONS } from '@/constants';
@@ -16,6 +17,14 @@ jest.mock('@grafana/runtime', () => ({
getTemplateSrv: jest.fn(),
}));

/**
* Mock @volkovlabs/components
*/
jest.mock('@volkovlabs/components', () => ({
...jest.requireActual('@volkovlabs/components'),
AutosizeCodeEditor: jest.fn().mockImplementation(() => null),
}));

/**
* Mock timers
*/
@@ -51,7 +60,7 @@ describe('Custom Code Editor', () => {
it('Should show mini map if value more than 100 symbols', () => {
render(getComponent({ value: new Array(102).join('1') }));

expect(CodeEditor).toHaveBeenCalledWith(
expect(AutosizeCodeEditor).toHaveBeenCalledWith(
expect.objectContaining({
showMiniMap: true,
}),
@@ -70,7 +79,7 @@ describe('Custom Code Editor', () => {
})),
};

jest.mocked(CodeEditor).mockImplementationOnce(({ onEditorDidMount }: any) => {
jest.mocked(AutosizeCodeEditor).mockImplementationOnce(({ onEditorDidMount }: any) => {
useEffect(() => {
onEditorDidMount(editor);
}, [onEditorDidMount]);
@@ -86,7 +95,7 @@ describe('Custom Code Editor', () => {
/**
* Check if formatDocument is run
*/
expect(CodeEditor).toHaveBeenCalledWith(
expect(AutosizeCodeEditor).toHaveBeenCalledWith(
expect.objectContaining({
monacoOptions: {
formatOnPaste: true,
@@ -107,7 +116,7 @@ describe('Custom Code Editor', () => {
const value = 'some value';
const onChange = jest.fn();

jest.mocked(CodeEditor).mockImplementationOnce(({ onBlur }: any) => {
jest.mocked(AutosizeCodeEditor).mockImplementationOnce(({ onBlur }: any) => {
onBlur(value);
return null;
});
@@ -134,7 +143,7 @@ describe('Custom Code Editor', () => {
const value = 'some value';
const onChange = jest.fn();

jest.mocked(CodeEditor).mockImplementationOnce(({ onSave }: any) => {
jest.mocked(AutosizeCodeEditor).mockImplementationOnce(({ onSave }: any) => {
onSave(value);
return null;
});
@@ -163,7 +172,7 @@ describe('Custom Code Editor', () => {
const variableWithoutDescription = { name: 'var2', description: '', label: 'Var 2' };
const variables = [variableWithDescription, variableWithoutDescription];

jest.mocked(CodeEditor).mockImplementationOnce(({ getSuggestions }: any) => {
jest.mocked(AutosizeCodeEditor).mockImplementationOnce(({ getSuggestions }: any) => {
suggestionsResult = getSuggestions();
return null;
});
@@ -218,7 +227,7 @@ describe('Custom Code Editor', () => {
const variableWithoutDescription = { name: 'var2', description: '', label: 'Var 2' };
const variables = [variableWithDescription, variableWithoutDescription];

jest.mocked(CodeEditor).mockImplementationOnce(({ getSuggestions }: any) => {
jest.mocked(AutosizeCodeEditor).mockImplementationOnce(({ getSuggestions }: any) => {
suggestionsResult = getSuggestions();
return null;
});
Original file line number Diff line number Diff line change
@@ -53,13 +53,13 @@ export const CodeElement: React.FC<Props> = ({ element, onChange }) => {
language={element.language || CodeLanguage.JAVASCRIPT}
showLineNumbers={true}
showMiniMap={(element.value?.length || 0) > 100}
value={element.value?.replaceAll('\\n', '\n') || ''}
value={element.value || ''}
height={element.height}
width={applyWidth(element.width)}
onBlur={(code) => {
onChange<typeof element>({
...element,
value: code.replaceAll('\n', '\\n'),
value: code,
});
}}
monacoOptions={monacoOptions}
96 changes: 96 additions & 0 deletions src/utils/form-element.test.ts
Original file line number Diff line number Diff line change
@@ -321,6 +321,102 @@ describe('Utils', () => {
},
],
},
{
name: 'Should convert value for code element',
element: {
type: FormElementType.CODE,
},
testCases: [
{
original: 'line1',
expected: 'line1',
},
],
},
{
name: 'Should convert value for code element and replace new lines',
element: {
type: FormElementType.CODE,
},
testCases: [
{
original: 'line1\n',
expected: 'line1\\n',
},
],
},
{
name: 'Should convert value for code element if none-string',
element: {
type: FormElementType.CODE,
},
testCases: [
{
original: 15,
expected: '15',
},
],
},
{
name: 'Should convert value for code element if no value',
element: {
type: FormElementType.CODE,
},
testCases: [
{
original: '',
expected: '',
},
],
},
{
name: 'Should convert value for code element if value is undefined',
element: {
type: FormElementType.CODE,
},
testCases: [
{
original: undefined,
expected: '',
},
],
},
{
name: 'Should convert value for textarea element',
element: {
type: FormElementType.TEXTAREA,
},
testCases: [
{
original: 'line1',
expected: 'line1',
},
],
},
{
name: 'Should convert value for textarea element and replace new lines',
element: {
type: FormElementType.TEXTAREA,
},
testCases: [
{
original: 'line1\n',
expected: 'line1\\n',
},
],
},
{
name: 'Should convert value for textarea element if none-string',
element: {
type: FormElementType.TEXTAREA,
},
testCases: [
{
original: 15,
expected: '15',
},
],
},
])('$name', ({ element, testCases }) => {
testCases.forEach(({ original, expected }) => {
expect(convertToElementValue(element as never, original)).toEqual({
8 changes: 7 additions & 1 deletion src/utils/form-element.ts
Original file line number Diff line number Diff line change
@@ -477,9 +477,15 @@ export const convertToElementValue = (
value: unknown
): FormElementByType<LocalFormElement, typeof element.type> => {
switch (element.type) {
case FormElementType.CODE:
case FormElementType.TEXTAREA: {
return {
...element,
value: typeof value === 'string' ? value.replaceAll('\n', '\\n') : (value?.toString() ?? ''),
};
}
case FormElementType.STRING:
case FormElementType.DISABLED_TEXTAREA:
case FormElementType.CODE:
case FormElementType.PASSWORD:
case FormElementType.SECRET:
case FormElementType.COLOR_PICKER:

0 comments on commit 4471ba8

Please sign in to comment.