mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
Dashboards: Add template variables to selectable options (#75870)
This commit is contained in:
parent
c5914d92d4
commit
b2ba28ab40
@ -1,8 +1,9 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { initTemplateSrv } from 'test/helpers/initTemplateSrv';
|
||||
|
||||
import { FetchError } from '@grafana/runtime';
|
||||
import { FetchError, setTemplateSrv } from '@grafana/runtime';
|
||||
|
||||
import { TraceqlFilter, TraceqlSearchScope } from '../dataquery.gen';
|
||||
import { TempoDatasource } from '../datasource';
|
||||
@ -35,9 +36,11 @@ jest.mock('../language_provider', () => {
|
||||
});
|
||||
|
||||
describe('SearchField', () => {
|
||||
let templateSrv = initTemplateSrv('key', [{ name: 'templateVariable1' }, { name: 'templateVariable2' }]);
|
||||
let user: ReturnType<typeof userEvent.setup>;
|
||||
|
||||
beforeEach(() => {
|
||||
setTemplateSrv(templateSrv);
|
||||
jest.useFakeTimers();
|
||||
// Need to use delay: null here to work with fakeTimers
|
||||
// see https://github.com/testing-library/user-event/issues/833
|
||||
@ -172,6 +175,8 @@ describe('SearchField', () => {
|
||||
expect(await screen.findByText('span')).toBeInTheDocument();
|
||||
expect(await screen.findByText('unscoped')).toBeInTheDocument();
|
||||
expect(screen.queryByText('intrinsic')).not.toBeInTheDocument();
|
||||
expect(await screen.findByText('$templateVariable1')).toBeInTheDocument();
|
||||
expect(await screen.findByText('$templateVariable2')).toBeInTheDocument();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -3,8 +3,9 @@ import { uniq } from 'lodash';
|
||||
import React, { useState, useEffect, useMemo } from 'react';
|
||||
import useAsync from 'react-use/lib/useAsync';
|
||||
|
||||
import { SelectableValue } from '@grafana/data';
|
||||
import { AccessoryButton } from '@grafana/experimental';
|
||||
import { FetchError, isFetchError } from '@grafana/runtime';
|
||||
import { FetchError, getTemplateSrv, isFetchError } from '@grafana/runtime';
|
||||
import { Select, HorizontalGroup, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { createErrorNotification } from '../../../../core/copy/appNotification';
|
||||
@ -112,13 +113,24 @@ const SearchField = ({
|
||||
operatorList = numberOperators;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to a list of options the current template variables.
|
||||
*
|
||||
* @param options a list of options
|
||||
* @returns the list of given options plus the template variables
|
||||
*/
|
||||
const withTemplateVariableOptions = (options: SelectableValue[] | undefined) => {
|
||||
const templateVariables = getTemplateSrv().getVariables();
|
||||
return [...(options || []), ...templateVariables.map((v) => ({ label: `$${v.name}`, value: `$${v.name}` }))];
|
||||
};
|
||||
|
||||
return (
|
||||
<HorizontalGroup spacing={'none'} width={'auto'}>
|
||||
{!hideScope && (
|
||||
<Select
|
||||
className={styles.dropdown}
|
||||
inputId={`${filter.id}-scope`}
|
||||
options={scopeOptions}
|
||||
options={withTemplateVariableOptions(scopeOptions)}
|
||||
value={filter.scope}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...filter, scope: v?.value });
|
||||
@ -133,10 +145,12 @@ const SearchField = ({
|
||||
inputId={`${filter.id}-tag`}
|
||||
isLoading={isTagsLoading}
|
||||
// Add the current tag to the list if it doesn't exist in the tags prop, otherwise the field will be empty even though the state has a value
|
||||
options={(filter.tag !== undefined ? uniq([filter.tag, ...tags]) : tags).map((t) => ({
|
||||
label: t,
|
||||
value: t,
|
||||
}))}
|
||||
options={withTemplateVariableOptions(
|
||||
(filter.tag !== undefined ? uniq([filter.tag, ...tags]) : tags).map((t) => ({
|
||||
label: t,
|
||||
value: t,
|
||||
}))
|
||||
)}
|
||||
value={filter.tag}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...filter, tag: v?.value });
|
||||
@ -150,7 +164,7 @@ const SearchField = ({
|
||||
<Select
|
||||
className={styles.dropdown}
|
||||
inputId={`${filter.id}-operator`}
|
||||
options={operatorList.map(operatorSelectableValue)}
|
||||
options={withTemplateVariableOptions(operatorList.map(operatorSelectableValue))}
|
||||
value={filter.operator}
|
||||
onChange={(v) => {
|
||||
updateFilter({ ...filter, operator: v?.value });
|
||||
@ -165,7 +179,7 @@ const SearchField = ({
|
||||
className={styles.dropdown}
|
||||
inputId={`${filter.id}-value`}
|
||||
isLoading={isLoadingValues}
|
||||
options={options}
|
||||
options={withTemplateVariableOptions(options)}
|
||||
value={filter.value}
|
||||
onChange={(val) => {
|
||||
if (Array.isArray(val)) {
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { initTemplateSrv } from 'test/helpers/initTemplateSrv';
|
||||
|
||||
import { FetchError } from '@grafana/runtime';
|
||||
import { FetchError, setTemplateSrv } from '@grafana/runtime';
|
||||
|
||||
import { TraceqlFilter, TraceqlSearchScope } from '../dataquery.gen';
|
||||
import { TempoDatasource } from '../datasource';
|
||||
@ -13,9 +14,11 @@ import TagsInput from './TagsInput';
|
||||
import { v1Tags, v2Tags } from './utils.test';
|
||||
|
||||
describe('TagsInput', () => {
|
||||
let templateSrv = initTemplateSrv('key', [{ name: 'templateVariable1' }, { name: 'templateVariable2' }]);
|
||||
let user: ReturnType<typeof userEvent.setup>;
|
||||
|
||||
beforeEach(() => {
|
||||
setTemplateSrv(templateSrv);
|
||||
jest.useFakeTimers();
|
||||
// Need to use delay: null here to work with fakeTimers
|
||||
// see https://github.com/testing-library/user-event/issues/833
|
||||
@ -37,6 +40,8 @@ describe('TagsInput', () => {
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('foo')).toBeInTheDocument();
|
||||
expect(screen.getByText('bar')).toBeInTheDocument();
|
||||
expect(screen.getByText('$templateVariable1')).toBeInTheDocument();
|
||||
expect(screen.getByText('$templateVariable2')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@ -50,6 +55,8 @@ describe('TagsInput', () => {
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('cluster')).toBeInTheDocument();
|
||||
expect(screen.getByText('container')).toBeInTheDocument();
|
||||
expect(screen.getByText('$templateVariable1')).toBeInTheDocument();
|
||||
expect(screen.getByText('$templateVariable2')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@ -62,6 +69,8 @@ describe('TagsInput', () => {
|
||||
jest.advanceTimersByTime(1000);
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('db')).toBeInTheDocument();
|
||||
expect(screen.getByText('$templateVariable1')).toBeInTheDocument();
|
||||
expect(screen.getByText('$templateVariable2')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
@ -76,6 +85,8 @@ describe('TagsInput', () => {
|
||||
expect(screen.getByText('cluster')).toBeInTheDocument();
|
||||
expect(screen.getByText('container')).toBeInTheDocument();
|
||||
expect(screen.getByText('db')).toBeInTheDocument();
|
||||
expect(screen.getByText('$templateVariable1')).toBeInTheDocument();
|
||||
expect(screen.getByText('$templateVariable2')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user