diff --git a/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.test.tsx b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.test.tsx new file mode 100644 index 00000000000..a1551b0028f --- /dev/null +++ b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.test.tsx @@ -0,0 +1,34 @@ +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { TextBoxVariableForm } from './TextBoxVariableForm'; + +describe('TextBoxVariableForm', () => { + it('renders correctly', () => { + const onChange = jest.fn(); + const onBlur = jest.fn(); + const value = 'test value'; + + render(); + + expect(screen.getByText('Text options')).toBeInTheDocument(); + expect(screen.getByRole('textbox', { name: 'Default value' })).toBeInTheDocument(); + }); + + it('calls onChange when input value changes', async () => { + const onChange = jest.fn(); + const onBlur = jest.fn(); + const value = 'test value'; + + render(); + + const input = screen.getByRole('textbox', { name: 'Default value' }); + expect(input).toHaveValue(value); + + // change input value + const newValue = 'new value'; + await userEvent.type(input, newValue); + expect(onChange).toHaveBeenCalledTimes(newValue.length); + }); +}); diff --git a/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx new file mode 100644 index 00000000000..e91b7860dda --- /dev/null +++ b/public/app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm.tsx @@ -0,0 +1,28 @@ +import React, { FormEvent } from 'react'; + +import { selectors } from '@grafana/e2e-selectors'; +import { VariableLegend } from 'app/features/dashboard-scene/settings/variables/components/VariableLegend'; +import { VariableTextField } from 'app/features/dashboard-scene/settings/variables/components/VariableTextField'; + +interface TextBoxVariableFormProps { + value: string; + onChange: (event: FormEvent) => void; + onBlur: (event: FormEvent) => void; +} + +export function TextBoxVariableForm({ onChange, onBlur, value }: TextBoxVariableFormProps) { + return ( + <> + Text options + + + ); +} diff --git a/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.test.tsx b/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.test.tsx new file mode 100644 index 00000000000..063a1d033f3 --- /dev/null +++ b/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.test.tsx @@ -0,0 +1,54 @@ +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; + +import { TextBoxVariable } from '@grafana/scenes'; + +import { TextBoxVariableEditor } from './TextBoxVariableEditor'; + +describe('TextBoxVariableEditor', () => { + let textBoxVar: TextBoxVariable; + beforeEach(async () => { + const result = await buildTestScene(); + textBoxVar = result.textBoxVar; + }); + + it('renders default value if any', () => { + const onChange = jest.fn(); + render(); + + const input = screen.getByRole('textbox', { name: 'Default value' }); + expect(input).toBeInTheDocument(); + expect(input).toHaveValue('initial value test'); + }); + + it('changes the value', async () => { + const onChange = jest.fn(); + render(); + + const input = screen.getByRole('textbox', { name: 'Default value' }); + expect(input).toBeInTheDocument(); + expect(input).toHaveValue('initial value test'); + + // change input value + const newValue = 'new textbox value'; + await userEvent.clear(input); + await userEvent.type(input, newValue); + + expect(input).toHaveValue(newValue); + + await userEvent.tab(); + expect(textBoxVar.state.value).toBe(newValue); + }); +}); + +async function buildTestScene() { + const textBoxVar = new TextBoxVariable({ + name: 'textBoxVar', + label: 'textBoxVar', + type: 'textbox', + value: 'initial value test', + }); + + return { textBoxVar }; +} diff --git a/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.tsx b/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.tsx index 3eb6289eb3f..36da5e25491 100644 --- a/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.tsx +++ b/public/app/features/dashboard-scene/settings/variables/editors/TextBoxVariableEditor.tsx @@ -1,12 +1,25 @@ -import React from 'react'; +import React, { useState } from 'react'; import { TextBoxVariable } from '@grafana/scenes'; +import { TextBoxVariableForm } from '../components/TextBoxVariableForm'; + interface TextBoxVariableEditorProps { variable: TextBoxVariable; onChange: (variable: TextBoxVariable) => void; } -export function TextBoxVariableEditor(props: TextBoxVariableEditorProps) { - return
TextBoxVariableEditor
; +export function TextBoxVariableEditor({ variable }: TextBoxVariableEditorProps) { + const { value } = variable.useState(); + const [textValue, setTextValue] = useState(value); + + const onTextValueChange = (event: React.FormEvent) => { + setTextValue(event.currentTarget.value); + }; + + const onBlur = () => { + variable.setState({ value: textValue }); + }; + + return ; } diff --git a/public/app/features/variables/textbox/TextBoxVariableEditor.tsx b/public/app/features/variables/textbox/TextBoxVariableEditor.tsx index 4ec385d370c..f3919521c62 100644 --- a/public/app/features/variables/textbox/TextBoxVariableEditor.tsx +++ b/public/app/features/variables/textbox/TextBoxVariableEditor.tsx @@ -1,9 +1,7 @@ import React, { FormEvent, ReactElement, useCallback } from 'react'; -import { selectors } from '@grafana/e2e-selectors'; +import { TextBoxVariableForm } from 'app/features/dashboard-scene/settings/variables/components/TextBoxVariableForm'; -import { VariableLegend } from '../../dashboard-scene/settings/variables/components/VariableLegend'; -import { VariableTextField } from '../../dashboard-scene/settings/variables/components/VariableTextField'; import { VariableEditorProps } from '../editor/types'; import { TextBoxVariableModel } from '../types'; @@ -22,18 +20,5 @@ export function TextBoxVariableEditor({ onPropChange, variable: { query } }: Pro const onChange = useCallback((e: FormEvent) => updateVariable(e, false), [updateVariable]); const onBlur = useCallback((e: FormEvent) => updateVariable(e, true), [updateVariable]); - return ( - <> - Text options - - - ); + return ; }