diff --git a/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.test.tsx b/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.test.tsx new file mode 100644 index 00000000000..e557f4dc911 --- /dev/null +++ b/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.test.tsx @@ -0,0 +1,84 @@ +import { render, screen } from '@testing-library/react'; +import { useState } from 'react'; +import { userEvent } from 'test/test-utils'; + +import { CustomVariable, SceneVariable, SceneVariableSet } from '@grafana/scenes'; +import { DashboardScene } from 'app/features/dashboard-scene/scene/DashboardScene'; +import { activateFullSceneTree } from 'app/features/dashboard-scene/utils/test-utils'; + +import { RepeatRowSelect2 } from './RepeatRowSelect'; + +async function buildTestScene(variables?: SceneVariable[]) { + const dashboard = new DashboardScene({ + uid: 'A', + $variables: new SceneVariableSet({ + variables: variables ?? [], + }), + }); + + activateFullSceneTree(dashboard); + await new Promise((r) => setTimeout(r, 1)); + return dashboard; +} + +const Wrapper = ({ scene }: { scene: DashboardScene }) => { + const [repeat, setRepeat] = useState(undefined); + return setRepeat(newRepeat)} />; +}; + +const setup = async (variables?: SceneVariable[]) => { + const scene = await buildTestScene(variables); + + return render(); +}; + +describe('RepeatRowSelect2', () => { + beforeAll(() => { + const mockGetBoundingClientRect = jest.fn(() => ({ + width: 120, + height: 120, + top: 0, + left: 0, + bottom: 0, + right: 0, + })); + + Object.defineProperty(Element.prototype, 'getBoundingClientRect', { + value: mockGetBoundingClientRect, + }); + }); + + it('should render correct options', async () => { + const variableA = new CustomVariable({ + name: 'testVar', + query: 'test, test2', + value: 'test', + text: 'testVar', + }); + const variableB = new CustomVariable({ + name: 'otherVar', + query: 'test, test2', + value: 'test', + text: 'otherVar', + }); + + await setup([variableA, variableB]); + + const input = screen.getByRole('combobox'); + + expect(input).not.toBeDisabled(); + expect(input).toHaveProperty('placeholder', 'Choose'); + await userEvent.click(input); + + expect(await screen.findByText(/Disable repeating/)).toBeInTheDocument(); + expect(screen.getByText(/testVar/)).toBeInTheDocument(); + expect(screen.getByText(/otherVar/)).toBeInTheDocument(); + }); + + it('should be disabled when there are no template variables', async () => { + await setup(); + + expect(screen.getByRole('combobox')).toHaveProperty('placeholder', 'No template variables found'); + expect(screen.getByRole('combobox')).toBeDisabled(); + }); +}); diff --git a/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.tsx b/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.tsx index 1c7efb14f56..cc7b6c55a99 100644 --- a/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.tsx +++ b/public/app/features/dashboard/components/RepeatRowSelect/RepeatRowSelect.tsx @@ -3,7 +3,7 @@ import { useCallback, useMemo } from 'react'; import { SelectableValue } from '@grafana/data'; import { useTranslate } from '@grafana/i18n'; import { SceneObject, sceneGraph } from '@grafana/scenes'; -import { Select } from '@grafana/ui'; +import { Combobox, ComboboxOption, Select } from '@grafana/ui'; import { useSelector } from 'app/types'; import { getLastKey, getVariablesByKey } from '../../../variables/state/selectors'; @@ -61,30 +61,38 @@ export const RepeatRowSelect2 = ({ sceneContext, repeat, id, onChange }: Props2) const variables = sceneVars.useState().variables; const variableOptions = useMemo(() => { - const options: Array> = variables.map((item) => ({ + const options: ComboboxOption[] = variables.map((item) => ({ label: item.state.name, value: item.state.name, })); - if (options.length === 0) { - options.unshift({ - label: t( - 'dashboard.repeat-row-select2.variable-options.label.no-template-variables-found', - 'No template variables found' - ), - value: null, - }); - } - options.unshift({ label: t('dashboard.repeat-row-select2.variable-options.label.disable-repeating', 'Disable repeating'), - value: null, + value: '', }); return options; }, [variables, t]); - const onSelectChange = useCallback((option: SelectableValue) => onChange(option.value!), [onChange]); + const onSelectChange = useCallback((value: ComboboxOption | null) => value && onChange(value.value), [onChange]); - return