Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSPicker: Use new DS picker everywhere #70609

Merged
merged 17 commits into from Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 0 additions & 3 deletions .betterer.results
Expand Up @@ -792,9 +792,6 @@ exports[`better eslint`] = {
"packages/grafana-runtime/src/analytics/types.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-runtime/src/components/DataSourcePicker.tsx:5381": [
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
],
"packages/grafana-runtime/src/components/PanelRenderer.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
Expand Down
11 changes: 5 additions & 6 deletions e2e/dashboards-suite/new-query-variable.spec.ts
Expand Up @@ -38,10 +38,9 @@ describe('Variables - Query - Add variable', () => {
e2e().get('label').contains('Show on dashboard').should('be.visible');

e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsDataSourceSelect()
.should('be.visible')
.within((select) => {
e2e.components.Select.singleValue().should('have.text', 'gdev-testdata');
});
.get('input[placeholder="gdev-testdata"]')
.scrollIntoView()
.should('be.visible');

e2e().get('label').contains('Refresh').scrollIntoView().should('be.visible');
e2e().get('label').contains('On dashboard load').scrollIntoView().should('be.visible');
Expand Down Expand Up @@ -89,7 +88,7 @@ describe('Variables - Query - Add variable', () => {

e2e().get('[placeholder="Descriptive text"]').should('be.visible').clear().type('a description');

e2e.components.DataSourcePicker.inputV2().should('be.visible').type('gdev-testdata{enter}');
e2e.components.DataSourcePicker.container().should('be.visible').type('gdev-testdata{enter}');

e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsQueryInput()
.should('be.visible')
Expand Down Expand Up @@ -137,7 +136,7 @@ describe('Variables - Query - Add variable', () => {

e2e().get('[placeholder="Descriptive text"]').should('be.visible').clear().type('a description');

e2e.components.DataSourcePicker.inputV2().type('gdev-testdata{enter}');
e2e.components.DataSourcePicker.container().type('gdev-testdata{enter}');

e2e.pages.Dashboard.Settings.Variables.Edit.QueryVariable.queryOptionsQueryInput()
.should('be.visible')
Expand Down
Expand Up @@ -307,7 +307,7 @@ export const Components = {
* @deprecated use inputV2 instead
*/
input: () => 'input[id="data-source-picker"]',
inputV2: 'Select a data source',
inputV2: 'data-testid Select a data source',
},
TimeZonePicker: {
/**
Expand Down
Expand Up @@ -188,7 +188,8 @@ export class DataSourcePicker extends PureComponent<DataSourcePickerProps, DataS
<Select
isLoading={isLoading}
disabled={disabled}
aria-label={selectors.components.DataSourcePicker.inputV2}
aria-label={'Select a data source'}
data-testid={selectors.components.DataSourcePicker.inputV2}
inputId={inputId || 'data-source-picker'}
className="ds-picker select-container"
isMulti={false}
Expand Down
Expand Up @@ -3,9 +3,9 @@ import React, { useCallback, useMemo } from 'react';

import { DataSourceJsonData, DataSourceInstanceSettings, DataSourcePluginOptionsEditorProps } from '@grafana/data';
import { ConfigSection } from '@grafana/experimental';
import { DataSourcePicker } from '@grafana/runtime';
import { InlineField, InlineFieldRow, Input, InlineSwitch } from '@grafana/ui';
import { ConfigDescriptionLink } from 'app/core/components/ConfigDescriptionLink';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import { IntervalInput } from '../IntervalInput/IntervalInput';

Expand Down
Expand Up @@ -2,14 +2,15 @@ import { css } from '@emotion/css';
import React from 'react';

import {
DataSourceInstanceSettings,
DataSourceJsonData,
DataSourcePluginOptionsEditorProps,
GrafanaTheme2,
updateDatasourcePluginJsonDataOption,
} from '@grafana/data';
import { ConfigSection } from '@grafana/experimental';
import { DataSourcePicker } from '@grafana/runtime';
import { Button, InlineField, InlineFieldRow, Input, useStyles2 } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import { ConfigDescriptionLink } from '../ConfigDescriptionLink';
import { IntervalInput } from '../IntervalInput/IntervalInput';
Expand Down Expand Up @@ -52,7 +53,7 @@ export function TraceToMetricsSettings({ options, onOptionsChange }: Props) {
current={options.jsonData.tracesToMetrics?.datasourceUid}
noDefault={true}
width={40}
onChange={(ds) =>
onChange={(ds: DataSourceInstanceSettings) =>
updateDatasourcePluginJsonDataOption({ onOptionsChange, options }, 'tracesToMetrics', {
...options.jsonData.tracesToMetrics,
datasourceUid: ds.uid,
Expand Down
Expand Up @@ -2,7 +2,7 @@ import React, { useCallback } from 'react';
import { useAsync } from 'react-use';

import { DataSourceInstanceSettings } from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
import { dispatch } from 'app/store/store';

import { useRulesSourcesWithRuler } from '../../hooks/useRuleSourcesWithRuler';
Expand All @@ -28,14 +28,6 @@ export function CloudRulesSourcePicker({ value, ...props }: Props): JSX.Element
);

return (
<DataSourcePicker
disabled={loading}
isLoading={loading}
noDefault
alerting
filter={dataSourceFilter}
current={value}
{...props}
/>
<DataSourcePicker disabled={loading} noDefault alerting filter={dataSourceFilter} current={value} {...props} />
);
}
Expand Up @@ -3,8 +3,8 @@ import React from 'react';
import { Controller, useFormContext } from 'react-hook-form';

import { DataSourceInstanceSettings, GrafanaTheme2 } from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { Card, Field, FieldSet, Input, useStyles2 } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';

import { getVariableUsageInfo } from '../../explore/utils/links';
Expand Down
Expand Up @@ -2,8 +2,8 @@ import React from 'react';
import { Controller, useFormContext, useWatch } from 'react-hook-form';

import { DataSourceInstanceSettings } from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { Field, FieldSet } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import { QueryEditorField } from './QueryEditorField';
import { useCorrelationsFormContext } from './correlationsFormContext';
Expand Down
Expand Up @@ -11,7 +11,7 @@ import {
} from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { Stack } from '@grafana/experimental';
import { DataSourcePicker, getDataSourceSrv, locationService } from '@grafana/runtime';
import { getDataSourceSrv, locationService } from '@grafana/runtime';
import { AnnotationPanelFilter } from '@grafana/schema/src/raw/dashboard/x/dashboard_types.gen';
import {
Button,
Expand All @@ -27,6 +27,7 @@ import {
import { ColorValueEditor } from 'app/core/components/OptionsUI/color';
import config from 'app/core/config';
import StandardAnnotationQueryEditor from 'app/features/annotations/components/StandardAnnotationQueryEditor';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import { DashboardModel } from '../../state/DashboardModel';

Expand Down
Expand Up @@ -4,6 +4,7 @@ import { UserEvent } from '@testing-library/user-event/dist/types/setup/setup';
import React from 'react';

import { DataSourceInstanceSettings, DataSourcePluginMeta, PluginMetaInfo, PluginType } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { ModalRoot, ModalsProvider } from '@grafana/ui';
import config from 'app/core/config';
import { defaultFileUploadQuery } from 'app/plugins/datasource/grafana/types';
Expand Down Expand Up @@ -145,7 +146,10 @@ describe('DataSourceDropdown', () => {
it('should display the current selected DS in the selector', async () => {
getInstanceSettingsMock.mockReturnValue(mockDS2);
render(<DataSourceDropdown onChange={jest.fn()} current={mockDS2}></DataSourceDropdown>);
expect(screen.getByTestId('Select a data source')).toHaveAttribute('placeholder', mockDS2.name);
expect(screen.getByTestId(selectors.components.DataSourcePicker.inputV2)).toHaveAttribute(
'placeholder',
mockDS2.name
);
expect(screen.getByAltText(`${mockDS2.meta.name} logo`)).toBeVisible();
});

Expand All @@ -166,7 +170,10 @@ describe('DataSourceDropdown', () => {
it('should display the default DS as selected when `current` is not set', async () => {
getInstanceSettingsMock.mockReturnValue(mockDS2);
render(<DataSourceDropdown onChange={jest.fn()} current={undefined}></DataSourceDropdown>);
expect(screen.getByTestId('Select a data source')).toHaveAttribute('placeholder', mockDS2.name);
expect(screen.getByTestId(selectors.components.DataSourcePicker.inputV2)).toHaveAttribute(
'placeholder',
mockDS2.name
);
expect(screen.getByAltText(`${mockDS2.meta.name} logo`)).toBeVisible();
});

Expand All @@ -180,12 +187,15 @@ describe('DataSourceDropdown', () => {

it('should disable the dropdown when `disabled` is true', () => {
render(<DataSourceDropdown onChange={jest.fn()} disabled></DataSourceDropdown>);
expect(screen.getByTestId('Select a data source')).toBeDisabled();
expect(screen.getByTestId(selectors.components.DataSourcePicker.inputV2)).toBeDisabled();
});

it('should assign the correct `id` to the input element to pair it with a label', () => {
render(<DataSourceDropdown onChange={jest.fn()} inputId={'custom.input.id'}></DataSourceDropdown>);
expect(screen.getByTestId('Select a data source')).toHaveAttribute('id', 'custom.input.id');
expect(screen.getByTestId(selectors.components.DataSourcePicker.inputV2)).toHaveAttribute(
'id',
'custom.input.id'
);
});

it('should not set the default DS when setting `noDefault` to true and `current` is not provided', () => {
Expand All @@ -195,7 +205,10 @@ describe('DataSourceDropdown', () => {
// Doesn't try to get the default DS
expect(getListMock).not.toBeCalled();
expect(getInstanceSettingsMock).not.toBeCalled();
expect(screen.getByTestId('Select a data source')).toHaveAttribute('placeholder', 'Select data source');
expect(screen.getByTestId(selectors.components.DataSourcePicker.inputV2)).toHaveAttribute(
'placeholder',
'Select data source'
);
});
});

Expand Down
Expand Up @@ -197,6 +197,7 @@ export function DataSourceDropdown(props: DataSourceDropdownProps) {
id={inputId || 'data-source-picker'}
className={inputHasFocus ? undefined : styles.input}
data-testid={selectors.components.DataSourcePicker.inputV2}
aria-label="Select a data source"
prefix={currentValue ? prefixIcon : undefined}
suffix={<Icon name={isOpen ? 'search' : 'angle-down'} />}
placeholder={hideTextValue ? '' : dataSourceLabel(currentValue) || placeholder}
Expand Down
@@ -1,7 +1,6 @@
import React, { useEffect, useState } from 'react';

import { selectors } from '@grafana/e2e-selectors';
import { DataSourcePicker } from '@grafana/runtime';
import { ExpressionDatasourceRef } from '@grafana/runtime/src/utils/DataSourceWithBackend';
import {
Button,
Expand All @@ -15,6 +14,7 @@ import {
Legend,
} from '@grafana/ui';
import { OldFolderPicker } from 'app/core/components/Select/OldFolderPicker';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import {
DashboardInput,
Expand Down
Expand Up @@ -83,7 +83,7 @@ describe('QueryEditorRowHeader', () => {
it('should render variables in the data source picker', async () => {
renderScenario({ onChangeDataSource: () => {} });

const dsSelect = screen.getByLabelText(selectors.components.DataSourcePicker.inputV2);
const dsSelect = screen.getByTestId(selectors.components.DataSourcePicker.container).querySelector('input')!;
openMenu(dsSelect);
expect(await screen.findByText('${dsVariable}')).toBeInTheDocument();
});
Expand Down
Expand Up @@ -60,12 +60,14 @@ describe('AdHocVariableEditor', () => {
it('has a datasource select menu', async () => {
render(<AdHocVariableEditor {...props} />);

expect(await screen.findByLabelText(selectors.components.DataSourcePicker.inputV2)).toBeInTheDocument();
expect(await screen.getByTestId(selectors.components.DataSourcePicker.container)).toBeInTheDocument();
});

it('calls the callback when changing the datasource', async () => {
render(<AdHocVariableEditor {...props} />);
const selectEl = screen.getByLabelText(selectors.components.DataSourcePicker.inputV2);
const selectEl = screen
.getByTestId(selectors.components.DataSourcePicker.container)
.getElementsByTagName('input')[0];
await selectOptionInTest(selectEl, 'Loki');

expect(props.changeVariableDatasource).toBeCalledWith(
Expand Down
Expand Up @@ -2,8 +2,8 @@ import React, { PureComponent } from 'react';
import { connect, ConnectedProps } from 'react-redux';

import { DataSourceInstanceSettings, getDataSourceRef } from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { Alert, Field } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
import { StoreState } from 'app/types';

import { VariableLegend } from '../editor/VariableLegend';
Expand Down
Expand Up @@ -3,8 +3,9 @@ import { connect, ConnectedProps } from 'react-redux';

import { DataSourceInstanceSettings, getDataSourceRef, LoadingState, SelectableValue } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { DataSourcePicker, getTemplateSrv } from '@grafana/runtime';
import { getTemplateSrv } from '@grafana/runtime';
import { Field } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import { StoreState } from '../../../types';
import { getTimeSrv } from '../../dashboard/services/TimeSrv';
Expand Down
@@ -1,9 +1,9 @@
import { css } from '@emotion/css';
import React from 'react';

import { GrafanaTheme2 } from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { GrafanaTheme2, DataSourceInstanceSettings } from '@grafana/data';
import { Alert, InlineField, useStyles2 } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';

const getStyles = (theme: GrafanaTheme2) => ({
Expand Down Expand Up @@ -51,7 +51,7 @@ export function XrayLinkConfig({ datasourceUid, onChange }: Props) {
>
<DataSourcePicker
pluginId={xRayDsId}
onChange={(ds) => onChange(ds.uid)}
onChange={(ds: DataSourceInstanceSettings) => onChange(ds.uid)}
current={datasourceUid}
noDefault={true}
/>
Expand Down
Expand Up @@ -2,9 +2,9 @@ import { css } from '@emotion/css';
import React, { Dispatch, SetStateAction, useEffect, useState } from 'react';
import { usePrevious } from 'react-use';

import { VariableSuggestion } from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { DataSourceInstanceSettings, VariableSuggestion } from '@grafana/data';
import { Button, LegacyForms, DataLinkInput, stylesFactory } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import { DataLinkConfig } from '../types';

Expand Down Expand Up @@ -126,7 +126,7 @@ export const DataLink = (props: Props) => {
<DataSourcePicker
tracing={true}
// Uid and value should be always set in the db and so in the items.
onChange={(ds) => {
onChange={(ds: DataSourceInstanceSettings) => {
onChange({
...value,
datasourceUid: ds.uid,
Expand Down
Expand Up @@ -67,7 +67,7 @@ describe('DerivedField', () => {
);
expect(await screen.findByText('Name')).toBeInTheDocument();

expect(screen.getByLabelText(selectors.components.DataSourcePicker.inputV2)).toBeInTheDocument();
expect(screen.getByTestId(selectors.components.DataSourcePicker.container)).toBeInTheDocument();
});

it('shows url link if uid is not set', async () => {
Expand All @@ -89,7 +89,7 @@ describe('DerivedField', () => {
);
expect(await screen.findByText('Name')).toBeInTheDocument();

expect(screen.queryByLabelText(selectors.components.DataSourcePicker.inputV2)).not.toBeInTheDocument();
expect(await screen.queryByTestId(selectors.components.DataSourcePicker.container)).not.toBeInTheDocument();
});

it('shows only tracing datasources for internal link', async () => {
Expand Down
Expand Up @@ -2,9 +2,9 @@ import { css } from '@emotion/css';
import React, { ChangeEvent, useEffect, useState } from 'react';
import { usePrevious } from 'react-use';

import { GrafanaTheme2, VariableSuggestion } from '@grafana/data';
import { DataSourcePicker } from '@grafana/runtime';
import { GrafanaTheme2, DataSourceInstanceSettings, VariableSuggestion } from '@grafana/data';
import { Button, DataLinkInput, Field, Icon, Input, Label, Tooltip, useStyles2, Switch } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import { DerivedFieldConfig } from '../types';

Expand Down Expand Up @@ -145,7 +145,7 @@ export const DerivedField = (props: Props) => {
<Field label="" className={styles.dataSource}>
<DataSourcePicker
tracing={true}
onChange={(ds) =>
onChange={(ds: DataSourceInstanceSettings) =>
onChange({
...value,
datasourceUid: ds.uid,
Expand Down
@@ -1,8 +1,9 @@
import React, { useState } from 'react';

import { DataSourceInstanceSettings } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { DataSourcePicker } from '@grafana/runtime';
import { Button, InlineField, Input, Switch, useTheme2 } from '@grafana/ui';
import { DataSourcePicker } from 'app/features/datasources/components/picker/DataSourcePicker';

import { ExemplarTraceIdDestination } from '../types';

Expand Down Expand Up @@ -58,7 +59,7 @@ export default function ExemplarSetting({ value, onChange, onDelete, disabled }:
current={value.datasourceUid}
noDefault={true}
width={40}
onChange={(ds) =>
onChange={(ds: DataSourceInstanceSettings) =>
onChange({
...value,
datasourceUid: ds.uid,
Expand Down