mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Variables: Support static keys in AdHocFiltersVariable (#83157)
* initial start * don't use getTagKeysProvider * some cleanup * undo kinds adjustment * simplify * remove async declaration * add description and a couple of unit tests * add transformSaveModelToScene test * add tests for AdHocVariableForm * add tests for AdHocFiltersVariableEditor * update to defaultKeys * fix snapshots * update to 3.13.3
This commit is contained in:
parent
677b765dab
commit
b1b65faf02
@ -250,7 +250,7 @@
|
|||||||
"@grafana/o11y-ds-frontend": "workspace:*",
|
"@grafana/o11y-ds-frontend": "workspace:*",
|
||||||
"@grafana/prometheus": "workspace:*",
|
"@grafana/prometheus": "workspace:*",
|
||||||
"@grafana/runtime": "workspace:*",
|
"@grafana/runtime": "workspace:*",
|
||||||
"@grafana/scenes": "^3.11.0",
|
"@grafana/scenes": "3.13.3",
|
||||||
"@grafana/schema": "workspace:*",
|
"@grafana/schema": "workspace:*",
|
||||||
"@grafana/sql": "workspace:*",
|
"@grafana/sql": "workspace:*",
|
||||||
"@grafana/ui": "workspace:*",
|
"@grafana/ui": "workspace:*",
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { LoadingState } from './data';
|
import { LoadingState } from './data';
|
||||||
|
import { MetricFindValue } from './datasource';
|
||||||
import { DataSourceRef } from './query';
|
import { DataSourceRef } from './query';
|
||||||
|
|
||||||
export type VariableType = TypedVariableModel['type'];
|
export type VariableType = TypedVariableModel['type'];
|
||||||
@ -63,6 +64,10 @@ export interface AdHocVariableModel extends BaseVariableModel {
|
|||||||
* Filters that are always applied to the lookup of keys. Not shown in the AdhocFilterBuilder UI.
|
* Filters that are always applied to the lookup of keys. Not shown in the AdhocFilterBuilder UI.
|
||||||
*/
|
*/
|
||||||
baseFilters?: AdHocVariableFilter[];
|
baseFilters?: AdHocVariableFilter[];
|
||||||
|
/**
|
||||||
|
* Static keys that override any dynamic keys from the datasource.
|
||||||
|
*/
|
||||||
|
defaultKeys?: MetricFindValue[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface GroupByVariableModel extends VariableWithOptions {
|
export interface GroupByVariableModel extends VariableWithOptions {
|
||||||
|
@ -195,6 +195,7 @@ export const Pages = {
|
|||||||
AdHocFiltersVariable: {
|
AdHocFiltersVariable: {
|
||||||
datasourceSelect: Components.DataSourcePicker.inputV2,
|
datasourceSelect: Components.DataSourcePicker.inputV2,
|
||||||
infoText: 'data-testid ad-hoc filters variable info text',
|
infoText: 'data-testid ad-hoc filters variable info text',
|
||||||
|
modeToggle: 'data-testid ad-hoc filters variable mode toggle',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -388,6 +388,91 @@ describe('sceneVariablesSetToVariables', () => {
|
|||||||
"type": "fake-std",
|
"type": "fake-std",
|
||||||
"uid": "fake-std",
|
"uid": "fake-std",
|
||||||
},
|
},
|
||||||
|
"defaultKeys": undefined,
|
||||||
|
"description": "test-desc",
|
||||||
|
"filters": [
|
||||||
|
{
|
||||||
|
"key": "filterTest",
|
||||||
|
"operator": "=",
|
||||||
|
"value": "test",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"label": "test-label",
|
||||||
|
"name": "test",
|
||||||
|
"type": "adhoc",
|
||||||
|
}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should handle AdHocFiltersVariable with defaultKeys', () => {
|
||||||
|
const variable = new AdHocFiltersVariable({
|
||||||
|
name: 'test',
|
||||||
|
label: 'test-label',
|
||||||
|
description: 'test-desc',
|
||||||
|
datasource: { uid: 'fake-std', type: 'fake-std' },
|
||||||
|
defaultKeys: [
|
||||||
|
{
|
||||||
|
text: 'some',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'static',
|
||||||
|
value: '2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'keys',
|
||||||
|
value: '3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
key: 'filterTest',
|
||||||
|
operator: '=',
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
baseFilters: [
|
||||||
|
{
|
||||||
|
key: 'baseFilterTest',
|
||||||
|
operator: '=',
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
const set = new SceneVariableSet({
|
||||||
|
variables: [variable],
|
||||||
|
});
|
||||||
|
|
||||||
|
const result = sceneVariablesSetToVariables(set);
|
||||||
|
|
||||||
|
expect(result).toHaveLength(1);
|
||||||
|
expect(result[0]).toMatchInlineSnapshot(`
|
||||||
|
{
|
||||||
|
"baseFilters": [
|
||||||
|
{
|
||||||
|
"key": "baseFilterTest",
|
||||||
|
"operator": "=",
|
||||||
|
"value": "test",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"datasource": {
|
||||||
|
"type": "fake-std",
|
||||||
|
"uid": "fake-std",
|
||||||
|
},
|
||||||
|
"defaultKeys": [
|
||||||
|
{
|
||||||
|
"text": "some",
|
||||||
|
"value": "1",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "static",
|
||||||
|
"value": "2",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "keys",
|
||||||
|
"value": "3",
|
||||||
|
},
|
||||||
|
],
|
||||||
"description": "test-desc",
|
"description": "test-desc",
|
||||||
"filters": [
|
"filters": [
|
||||||
{
|
{
|
||||||
|
@ -124,12 +124,13 @@ export function sceneVariablesSetToVariables(set: SceneVariables) {
|
|||||||
} else if (sceneUtils.isAdHocVariable(variable)) {
|
} else if (sceneUtils.isAdHocVariable(variable)) {
|
||||||
variables.push({
|
variables.push({
|
||||||
...commonProperties,
|
...commonProperties,
|
||||||
name: variable.state.name!,
|
name: variable.state.name,
|
||||||
type: 'adhoc',
|
type: 'adhoc',
|
||||||
datasource: variable.state.datasource,
|
datasource: variable.state.datasource,
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
baseFilters: variable.state.baseFilters,
|
baseFilters: variable.state.baseFilters,
|
||||||
filters: variable.state.filters,
|
filters: variable.state.filters,
|
||||||
|
defaultKeys: variable.state.defaultKeys,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Unsupported variable type');
|
throw new Error('Unsupported variable type');
|
||||||
|
@ -965,6 +965,88 @@ describe('transformSaveModelToScene', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should migrate adhoc variable with default keys', () => {
|
||||||
|
const variable: TypedVariableModel = {
|
||||||
|
id: 'adhoc',
|
||||||
|
global: false,
|
||||||
|
index: 0,
|
||||||
|
state: LoadingState.Done,
|
||||||
|
error: null,
|
||||||
|
name: 'adhoc',
|
||||||
|
label: 'Adhoc Label',
|
||||||
|
description: 'Adhoc Description',
|
||||||
|
type: 'adhoc',
|
||||||
|
rootStateKey: 'N4XLmH5Vz',
|
||||||
|
datasource: {
|
||||||
|
uid: 'gdev-prometheus',
|
||||||
|
type: 'prometheus',
|
||||||
|
},
|
||||||
|
filters: [
|
||||||
|
{
|
||||||
|
key: 'filterTest',
|
||||||
|
operator: '=',
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
baseFilters: [
|
||||||
|
{
|
||||||
|
key: 'baseFilterTest',
|
||||||
|
operator: '=',
|
||||||
|
value: 'test',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
defaultKeys: [
|
||||||
|
{
|
||||||
|
text: 'some',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'static',
|
||||||
|
value: '2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'keys',
|
||||||
|
value: '3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
hide: 0,
|
||||||
|
skipUrlSync: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
const migrated = createSceneVariableFromVariableModel(variable) as AdHocFiltersVariable;
|
||||||
|
const filterVarState = migrated.state;
|
||||||
|
|
||||||
|
expect(migrated).toBeInstanceOf(AdHocFiltersVariable);
|
||||||
|
expect(filterVarState).toEqual({
|
||||||
|
key: expect.any(String),
|
||||||
|
description: 'Adhoc Description',
|
||||||
|
hide: 0,
|
||||||
|
label: 'Adhoc Label',
|
||||||
|
name: 'adhoc',
|
||||||
|
skipUrlSync: false,
|
||||||
|
type: 'adhoc',
|
||||||
|
filterExpression: 'filterTest="test"',
|
||||||
|
filters: [{ key: 'filterTest', operator: '=', value: 'test' }],
|
||||||
|
baseFilters: [{ key: 'baseFilterTest', operator: '=', value: 'test' }],
|
||||||
|
datasource: { uid: 'gdev-prometheus', type: 'prometheus' },
|
||||||
|
applyMode: 'auto',
|
||||||
|
defaultKeys: [
|
||||||
|
{
|
||||||
|
text: 'some',
|
||||||
|
value: '1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'static',
|
||||||
|
value: '2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'keys',
|
||||||
|
value: '3',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when groupByVariable feature toggle is enabled', () => {
|
describe('when groupByVariable feature toggle is enabled', () => {
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
config.featureToggles.groupByVariable = true;
|
config.featureToggles.groupByVariable = true;
|
||||||
|
@ -344,6 +344,7 @@ export function createSceneVariableFromVariableModel(variable: TypedVariableMode
|
|||||||
applyMode: 'auto',
|
applyMode: 'auto',
|
||||||
filters: variable.filters ?? [],
|
filters: variable.filters ?? [],
|
||||||
baseFilters: variable.baseFilters ?? [],
|
baseFilters: variable.baseFilters ?? [],
|
||||||
|
defaultKeys: variable.defaultKeys,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (variable.type === 'custom') {
|
if (variable.type === 'custom') {
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
import { act, render } from '@testing-library/react';
|
import { act, render, screen } from '@testing-library/react';
|
||||||
import userEvent from '@testing-library/user-event';
|
import userEvent from '@testing-library/user-event';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import { mockDataSource } from 'app/features/alerting/unified/mocks';
|
import { mockDataSource } from 'app/features/alerting/unified/mocks';
|
||||||
|
|
||||||
import { AdHocVariableForm } from './AdHocVariableForm';
|
import { AdHocVariableForm, AdHocVariableFormProps } from './AdHocVariableForm';
|
||||||
|
|
||||||
const defaultDatasource = mockDataSource({
|
const defaultDatasource = mockDataSource({
|
||||||
name: 'Default Test Data Source',
|
name: 'Default Test Data Source',
|
||||||
@ -29,13 +29,15 @@ jest.mock('@grafana/runtime/src/services/dataSourceSrv', () => ({
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
describe('AdHocVariableForm', () => {
|
describe('AdHocVariableForm', () => {
|
||||||
|
const onDataSourceChange = jest.fn();
|
||||||
|
const defaultProps: AdHocVariableFormProps = {
|
||||||
|
datasource: defaultDatasource,
|
||||||
|
onDataSourceChange,
|
||||||
|
infoText: 'Test Info',
|
||||||
|
};
|
||||||
|
|
||||||
it('should render the form with the provided data source', async () => {
|
it('should render the form with the provided data source', async () => {
|
||||||
const onDataSourceChange = jest.fn();
|
const { renderer } = await setup(defaultProps);
|
||||||
const { renderer } = await setup({
|
|
||||||
datasource: defaultDatasource,
|
|
||||||
onDataSourceChange,
|
|
||||||
infoText: 'Test Info',
|
|
||||||
});
|
|
||||||
|
|
||||||
const dataSourcePicker = renderer.getByTestId(
|
const dataSourcePicker = renderer.getByTestId(
|
||||||
selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.datasourceSelect
|
selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.datasourceSelect
|
||||||
@ -51,12 +53,7 @@ describe('AdHocVariableForm', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should call the onDataSourceChange callback when the data source is changed', async () => {
|
it('should call the onDataSourceChange callback when the data source is changed', async () => {
|
||||||
const onDataSourceChange = jest.fn();
|
const { renderer, user } = await setup(defaultProps);
|
||||||
const { renderer, user } = await setup({
|
|
||||||
datasource: defaultDatasource,
|
|
||||||
onDataSourceChange,
|
|
||||||
infoText: 'Test Info',
|
|
||||||
});
|
|
||||||
|
|
||||||
// Simulate changing the data source
|
// Simulate changing the data source
|
||||||
await user.click(renderer.getByTestId(selectors.components.DataSourcePicker.inputV2));
|
await user.click(renderer.getByTestId(selectors.components.DataSourcePicker.inputV2));
|
||||||
@ -65,6 +62,52 @@ describe('AdHocVariableForm', () => {
|
|||||||
expect(onDataSourceChange).toHaveBeenCalledTimes(1);
|
expect(onDataSourceChange).toHaveBeenCalledTimes(1);
|
||||||
expect(onDataSourceChange).toHaveBeenCalledWith(promDatasource, undefined);
|
expect(onDataSourceChange).toHaveBeenCalledWith(promDatasource, undefined);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not render code editor when no default keys provided', async () => {
|
||||||
|
await setup(defaultProps);
|
||||||
|
|
||||||
|
expect(screen.queryByTestId(selectors.components.CodeEditor.container)).not.toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render code editor when defaultKeys and onDefaultKeysChange are provided', async () => {
|
||||||
|
const mockOnStaticKeysChange = jest.fn();
|
||||||
|
await setup({
|
||||||
|
...defaultProps,
|
||||||
|
defaultKeys: [{ text: 'test', value: 'test' }],
|
||||||
|
onDefaultKeysChange: mockOnStaticKeysChange,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await screen.findByTestId(selectors.components.CodeEditor.container)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call onDefaultKeysChange when toggling on default options', async () => {
|
||||||
|
const mockOnStaticKeysChange = jest.fn();
|
||||||
|
await setup({
|
||||||
|
...defaultProps,
|
||||||
|
onDefaultKeysChange: mockOnStaticKeysChange,
|
||||||
|
});
|
||||||
|
|
||||||
|
await userEvent.click(
|
||||||
|
screen.getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.modeToggle)
|
||||||
|
);
|
||||||
|
expect(mockOnStaticKeysChange).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockOnStaticKeysChange).toHaveBeenCalledWith([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call onDefaultKeysChange when toggling off default options', async () => {
|
||||||
|
const mockOnStaticKeysChange = jest.fn();
|
||||||
|
await setup({
|
||||||
|
...defaultProps,
|
||||||
|
defaultKeys: [{ text: 'test', value: 'test' }],
|
||||||
|
onDefaultKeysChange: mockOnStaticKeysChange,
|
||||||
|
});
|
||||||
|
|
||||||
|
await userEvent.click(
|
||||||
|
screen.getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.modeToggle)
|
||||||
|
);
|
||||||
|
expect(mockOnStaticKeysChange).toHaveBeenCalledTimes(1);
|
||||||
|
expect(mockOnStaticKeysChange).toHaveBeenCalledWith(undefined);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function setup(props?: React.ComponentProps<typeof AdHocVariableForm>) {
|
async function setup(props?: React.ComponentProps<typeof AdHocVariableForm>) {
|
||||||
|
@ -1,20 +1,41 @@
|
|||||||
import React from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
|
||||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
import { DataSourceInstanceSettings, MetricFindValue, readCSV } from '@grafana/data';
|
||||||
import { selectors } from '@grafana/e2e-selectors';
|
import { selectors } from '@grafana/e2e-selectors';
|
||||||
import { DataSourceRef } from '@grafana/schema';
|
import { DataSourceRef } from '@grafana/schema';
|
||||||
import { Alert, Field } from '@grafana/ui';
|
import { Alert, CodeEditor, Field, Switch } from '@grafana/ui';
|
||||||
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
|
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
|
||||||
|
|
||||||
import { VariableLegend } from './VariableLegend';
|
import { VariableLegend } from './VariableLegend';
|
||||||
|
|
||||||
interface AdHocVariableFormProps {
|
export interface AdHocVariableFormProps {
|
||||||
datasource?: DataSourceRef;
|
datasource?: DataSourceRef;
|
||||||
onDataSourceChange: (dsSettings: DataSourceInstanceSettings) => void;
|
onDataSourceChange: (dsSettings: DataSourceInstanceSettings) => void;
|
||||||
infoText?: string;
|
infoText?: string;
|
||||||
|
defaultKeys?: MetricFindValue[];
|
||||||
|
onDefaultKeysChange?: (keys?: MetricFindValue[]) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AdHocVariableForm({ datasource, infoText, onDataSourceChange }: AdHocVariableFormProps) {
|
export function AdHocVariableForm({
|
||||||
|
datasource,
|
||||||
|
infoText,
|
||||||
|
onDataSourceChange,
|
||||||
|
onDefaultKeysChange,
|
||||||
|
defaultKeys,
|
||||||
|
}: AdHocVariableFormProps) {
|
||||||
|
const updateStaticKeys = useCallback(
|
||||||
|
(csvContent: string) => {
|
||||||
|
const df = readCSV('key,value\n' + csvContent)[0];
|
||||||
|
const options = [];
|
||||||
|
for (let i = 0; i < df.length; i++) {
|
||||||
|
options.push({ text: df.fields[0].values[i], value: df.fields[1].values[i] });
|
||||||
|
}
|
||||||
|
|
||||||
|
onDefaultKeysChange?.(options);
|
||||||
|
},
|
||||||
|
[onDefaultKeysChange]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<VariableLegend>Ad-hoc options</VariableLegend>
|
<VariableLegend>Ad-hoc options</VariableLegend>
|
||||||
@ -29,6 +50,36 @@ export function AdHocVariableForm({ datasource, infoText, onDataSourceChange }:
|
|||||||
data-testid={selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.infoText}
|
data-testid={selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.infoText}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
{onDefaultKeysChange && (
|
||||||
|
<>
|
||||||
|
<Field label="Use static key dimensions" description="Provide dimensions as CSV: dimensionName, dimensionId">
|
||||||
|
<Switch
|
||||||
|
data-testid={selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.modeToggle}
|
||||||
|
value={defaultKeys !== undefined}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (defaultKeys === undefined) {
|
||||||
|
onDefaultKeysChange([]);
|
||||||
|
} else {
|
||||||
|
onDefaultKeysChange(undefined);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Field>
|
||||||
|
|
||||||
|
{defaultKeys !== undefined && (
|
||||||
|
<CodeEditor
|
||||||
|
height={300}
|
||||||
|
language="csv"
|
||||||
|
value={defaultKeys.map((o) => `${o.text},${o.value}`).join('\n')}
|
||||||
|
onBlur={updateStaticKeys}
|
||||||
|
onSave={updateStaticKeys}
|
||||||
|
showMiniMap={false}
|
||||||
|
showLineNumbers={true}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -51,10 +51,7 @@ export function GroupByVariableForm({
|
|||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<Field
|
<Field label="Use static Group By dimensions" description="Provide dimensions as CSV: dimensionName, dimensionId">
|
||||||
label="Use static Group By dimensions"
|
|
||||||
description="Provide dimensions as CSV: dimensionId, dimensionName "
|
|
||||||
>
|
|
||||||
<Switch
|
<Switch
|
||||||
data-testid={selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.modeToggle}
|
data-testid={selectors.pages.Dashboard.Settings.Variables.Edit.GroupByVariable.modeToggle}
|
||||||
value={defaultOptions !== undefined}
|
value={defaultOptions !== undefined}
|
||||||
|
@ -86,9 +86,31 @@ describe('AdHocFiltersVariableEditor', () => {
|
|||||||
|
|
||||||
expect(variable.state.datasource).toEqual({ uid: 'prometheus', type: 'prometheus' });
|
expect(variable.state.datasource).toEqual({ uid: 'prometheus', type: 'prometheus' });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should update the variable default keys when the default keys options is enabled', async () => {
|
||||||
|
const { renderer, variable, user } = await setup();
|
||||||
|
|
||||||
|
// Simulate toggling default options on
|
||||||
|
await user.click(
|
||||||
|
renderer.getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.modeToggle)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(variable.state.defaultKeys).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should update the variable default keys when the default keys option is disabled', async () => {
|
||||||
|
const { renderer, variable, user } = await setup(undefined, true);
|
||||||
|
|
||||||
|
// Simulate toggling default options off
|
||||||
|
await user.click(
|
||||||
|
renderer.getByTestId(selectors.pages.Dashboard.Settings.Variables.Edit.AdHocFiltersVariable.modeToggle)
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(variable.state.defaultKeys).toEqual(undefined);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
async function setup(props?: React.ComponentProps<typeof AdHocFiltersVariableEditor>) {
|
async function setup(props?: React.ComponentProps<typeof AdHocFiltersVariableEditor>, withDefaultKeys = false) {
|
||||||
const onRunQuery = jest.fn();
|
const onRunQuery = jest.fn();
|
||||||
const variable = new AdHocFiltersVariable({
|
const variable = new AdHocFiltersVariable({
|
||||||
name: 'adhocVariable',
|
name: 'adhocVariable',
|
||||||
@ -110,6 +132,7 @@ async function setup(props?: React.ComponentProps<typeof AdHocFiltersVariableEdi
|
|||||||
value: 'baseTestValue',
|
value: 'baseTestValue',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
defaultKeys: withDefaultKeys ? [{ text: 'A', value: 'A' }] : undefined,
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
renderer: await act(() =>
|
renderer: await act(() =>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useAsync } from 'react-use';
|
import { useAsync } from 'react-use';
|
||||||
|
|
||||||
import { DataSourceInstanceSettings } from '@grafana/data';
|
import { DataSourceInstanceSettings, MetricFindValue } from '@grafana/data';
|
||||||
import { getDataSourceSrv } from '@grafana/runtime';
|
import { getDataSourceSrv } from '@grafana/runtime';
|
||||||
import { AdHocFiltersVariable } from '@grafana/scenes';
|
import { AdHocFiltersVariable } from '@grafana/scenes';
|
||||||
import { DataSourceRef } from '@grafana/schema';
|
import { DataSourceRef } from '@grafana/schema';
|
||||||
@ -15,7 +15,7 @@ interface AdHocFiltersVariableEditorProps {
|
|||||||
|
|
||||||
export function AdHocFiltersVariableEditor(props: AdHocFiltersVariableEditorProps) {
|
export function AdHocFiltersVariableEditor(props: AdHocFiltersVariableEditorProps) {
|
||||||
const { variable } = props;
|
const { variable } = props;
|
||||||
const datasourceRef = variable.useState().datasource ?? undefined;
|
const { datasource: datasourceRef, defaultKeys } = variable.useState();
|
||||||
|
|
||||||
const { value: datasourceSettings } = useAsync(async () => {
|
const { value: datasourceSettings } = useAsync(async () => {
|
||||||
return await getDataSourceSrv().get(datasourceRef);
|
return await getDataSourceSrv().get(datasourceRef);
|
||||||
@ -36,5 +36,19 @@ export function AdHocFiltersVariableEditor(props: AdHocFiltersVariableEditorProp
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return <AdHocVariableForm datasource={datasourceRef} infoText={message} onDataSourceChange={onDataSourceChange} />;
|
const onDefaultKeysChange = (defaultKeys?: MetricFindValue[]) => {
|
||||||
|
variable.setState({
|
||||||
|
defaultKeys,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AdHocVariableForm
|
||||||
|
datasource={datasourceRef ?? undefined}
|
||||||
|
infoText={message}
|
||||||
|
onDataSourceChange={onDataSourceChange}
|
||||||
|
defaultKeys={defaultKeys}
|
||||||
|
onDefaultKeysChange={onDefaultKeysChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
10
yarn.lock
10
yarn.lock
@ -4037,9 +4037,9 @@ __metadata:
|
|||||||
languageName: unknown
|
languageName: unknown
|
||||||
linkType: soft
|
linkType: soft
|
||||||
|
|
||||||
"@grafana/scenes@npm:^3.11.0":
|
"@grafana/scenes@npm:3.13.3":
|
||||||
version: 3.11.0
|
version: 3.13.3
|
||||||
resolution: "@grafana/scenes@npm:3.11.0"
|
resolution: "@grafana/scenes@npm:3.13.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@grafana/e2e-selectors": "npm:10.3.3"
|
"@grafana/e2e-selectors": "npm:10.3.3"
|
||||||
react-grid-layout: "npm:1.3.4"
|
react-grid-layout: "npm:1.3.4"
|
||||||
@ -4053,7 +4053,7 @@ __metadata:
|
|||||||
"@grafana/ui": ^10.0.3
|
"@grafana/ui": ^10.0.3
|
||||||
react: ^18.0.0
|
react: ^18.0.0
|
||||||
react-dom: ^18.0.0
|
react-dom: ^18.0.0
|
||||||
checksum: 10/47629dd3f5129b8f803d54c512d10f921edf9b138b878fbebe664e2537d6813c72ea5119e28216daf7e426ef764400356db9b1532c601a3e029ae12baceb248d
|
checksum: 10/5b7f2e2714dcdbc3ad58352ec0cc7f513f7a240dc11a3e309733a662760a598e9333ec377f2899b6b668e018c2e885e8a044af7d42d1be4487d692cda3b9359a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@ -18336,7 +18336,7 @@ __metadata:
|
|||||||
"@grafana/plugin-e2e": "npm:^0.21.0"
|
"@grafana/plugin-e2e": "npm:^0.21.0"
|
||||||
"@grafana/prometheus": "workspace:*"
|
"@grafana/prometheus": "workspace:*"
|
||||||
"@grafana/runtime": "workspace:*"
|
"@grafana/runtime": "workspace:*"
|
||||||
"@grafana/scenes": "npm:^3.11.0"
|
"@grafana/scenes": "npm:3.13.3"
|
||||||
"@grafana/schema": "workspace:*"
|
"@grafana/schema": "workspace:*"
|
||||||
"@grafana/sql": "workspace:*"
|
"@grafana/sql": "workspace:*"
|
||||||
"@grafana/tsconfig": "npm:^1.3.0-rc1"
|
"@grafana/tsconfig": "npm:^1.3.0-rc1"
|
||||||
|
Loading…
Reference in New Issue
Block a user