From f3c54a136e8fdddc3061d1dc9f14ef5556c98486 Mon Sep 17 00:00:00 2001 From: Lu Yu Date: Tue, 19 Mar 2024 22:15:55 +0000 Subject: [PATCH 1/8] add multi selectable data source component Signed-off-by: Lu Yu --- .../data_source_menu.test.tsx | 4 +- .../data_source_menu/data_source_menu.tsx | 33 +- .../data_source_selectable.tsx | 4 +- .../data_source_filter_group.test.tsx.snap | 365 ++++++++++++++++++ ...data_source_multi_selectable.test.tsx.snap | 15 + .../data_source_filter_group.test.tsx | 37 ++ .../data_source_filter_group.tsx | 161 ++++++++ .../data_source_multi_selectable.test.tsx | 63 +++ .../data_source_multi_selectable.tsx | 100 +++++ .../data_source_multi_selectable/index.ts | 6 + 10 files changed, 780 insertions(+), 8 deletions(-) create mode 100644 src/plugins/data_source_management/public/components/data_source_multi_selectable/__snapshots__/data_source_filter_group.test.tsx.snap create mode 100644 src/plugins/data_source_management/public/components/data_source_multi_selectable/__snapshots__/data_source_multi_selectable.test.tsx.snap create mode 100644 src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_filter_group.test.tsx create mode 100644 src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_filter_group.tsx create mode 100644 src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.test.tsx create mode 100644 src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.tsx create mode 100644 src/plugins/data_source_management/public/components/data_source_multi_selectable/index.ts diff --git a/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.test.tsx b/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.test.tsx index a5ec61107b3e..7447f68d6906 100644 --- a/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.test.tsx +++ b/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.test.tsx @@ -33,7 +33,7 @@ describe('DataSourceMenu', () => { hideLocalCluster={false} disableDataSourceSelectable={false} className={'myclass'} - dataSourceCallBackFunc={jest.fn()} + onDataSourcesSelectionChange={jest.fn()} /> ); expect(component).toMatchSnapshot(); @@ -50,7 +50,7 @@ describe('DataSourceMenu', () => { hideLocalCluster={true} disableDataSourceSelectable={false} className={'myclass'} - dataSourceCallBackFunc={jest.fn()} + onDataSourcesSelectionChange={jest.fn()} /> ); expect(component).toMatchSnapshot(); diff --git a/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.tsx b/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.tsx index 9be65882a9b8..89651f0d0e3a 100644 --- a/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.tsx +++ b/src/plugins/data_source_management/public/components/data_source_menu/data_source_menu.tsx @@ -18,11 +18,13 @@ import { DataSourceSelectable } from './data_source_selectable'; import { DataSourceOption } from '../data_source_selector/data_source_selector'; import { DataSourceAggregatedView } from '../data_source_aggregated_view'; import { DataSourceView } from '../data_source_view'; +import { DataSourceMultiSelectable } from '../data_source_multi_selectable/data_source_multi_selectable'; import { DataSourceAttributes } from '../../types'; export interface DataSourceMenuProps { showDataSourceSelectable?: boolean; showDataSourceView?: boolean; + showDataSourceMultiSelectable?: boolean; showDataSourceAggregatedView?: boolean; activeDataSourceIds?: string[]; appName: string; @@ -30,7 +32,7 @@ export interface DataSourceMenuProps { notifications?: NotificationsStart; fullWidth: boolean; hideLocalCluster?: boolean; - dataSourceCallBackFunc?: (dataSource: DataSourceOption) => void; + onDataSourcesSelectionChange?: (dataSources: DataSourceOption[]) => void; disableDataSourceSelectable?: boolean; className?: string; selectedOption?: DataSourceOption[]; @@ -43,7 +45,7 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null const { savedObjects, notifications, - dataSourceCallBackFunc, + onDataSourcesSelectionChange, showDataSourceSelectable, disableDataSourceSelectable, showDataSourceAggregatedView, @@ -51,12 +53,18 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null hideLocalCluster, selectedOption, showDataSourceView, + showDataSourceMultiSelectable, dataSourceFilter, activeDataSourceIds, displayAllCompatibleDataSources, } = props; - if (!showDataSourceSelectable && !showDataSourceView && !showDataSourceAggregatedView) { + if ( + !showDataSourceSelectable && + !showDataSourceView && + !showDataSourceAggregatedView && + !showDataSourceMultiSelectable + ) { return null; } @@ -72,6 +80,21 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null ); } + function renderDataSourceMultiSelectable(className: string): ReactElement | null { + if (!showDataSourceMultiSelectable) return null; + return ( + + + + ); + } + function renderDataSourceSelectable(className: string): ReactElement | null { if (!showDataSourceSelectable) return null; return ( @@ -81,7 +104,7 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null hideLocalCluster={hideLocalCluster || false} savedObjectsClient={savedObjects!} notifications={notifications!.toasts} - onSelectedDataSource={dataSourceCallBackFunc!} + onSelectedDataSource={onDataSourcesSelectionChange!} disabled={disableDataSourceSelectable || false} selectedOption={selectedOption && selectedOption.length > 0 ? selectedOption : undefined} dataSourceFilter={dataSourceFilter} @@ -115,6 +138,7 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null {renderDataSourceAggregatedView()} {renderDataSourceSelectable(menuClassName)} {renderDataSourceView(menuClassName)} + {renderDataSourceMultiSelectable(menuClassName)} ); @@ -135,6 +159,7 @@ DataSourceMenu.defaultProps = { disableDataSourceSelectable: false, showDataSourceAggregatedView: false, showDataSourceSelectable: false, + showDataSourceMultiSelectable: false, displayAllCompatibleDataSources: false, showDataSourceView: false, hideLocalCluster: false, diff --git a/src/plugins/data_source_management/public/components/data_source_menu/data_source_selectable.tsx b/src/plugins/data_source_management/public/components/data_source_menu/data_source_selectable.tsx index 9c71c1f0aaa1..b33cc4b78332 100644 --- a/src/plugins/data_source_management/public/components/data_source_menu/data_source_selectable.tsx +++ b/src/plugins/data_source_management/public/components/data_source_menu/data_source_selectable.tsx @@ -23,7 +23,7 @@ import { DataSourceAttributes } from '../../types'; interface DataSourceSelectableProps { savedObjectsClient: SavedObjectsClientContract; notifications: ToastsStart; - onSelectedDataSource: (dataSource: DataSourceOption) => void; + onSelectedDataSource: (dataSources: DataSourceOption[]) => void; disabled: boolean; hideLocalCluster: boolean; fullWidth: boolean; @@ -119,7 +119,7 @@ export class DataSourceSelectable extends React.Component< this.setState({ selectedOption: [selectedDataSource], }); - this.props.onSelectedDataSource({ ...selectedDataSource }); + this.props.onSelectedDataSource([...selectedDataSource]); } render() { diff --git a/src/plugins/data_source_management/public/components/data_source_multi_selectable/__snapshots__/data_source_filter_group.test.tsx.snap b/src/plugins/data_source_management/public/components/data_source_multi_selectable/__snapshots__/data_source_filter_group.test.tsx.snap new file mode 100644 index 000000000000..e6682b4bf58f --- /dev/null +++ b/src/plugins/data_source_management/public/components/data_source_multi_selectable/__snapshots__/data_source_filter_group.test.tsx.snap @@ -0,0 +1,365 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DataSourceFilterGroup should render normally 1`] = ` + + + Data sources + + + 1 + + + } + closePopover={[Function]} + display="inlineBlock" + hasArrow={true} + id="popoverExampleMultiSelect" + isOpen={false} + ownFocus={true} + panelPaddingSize="none" +> + + + +
+ + name1 + +
+ + + +
+`; + +exports[`DataSourceFilterGroup should render popup when clicking on button 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+ + + 1 + +
+
+
+
+
+ +
+ , + "container":
+
+
+ + + 1 + +
+
+
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; diff --git a/src/plugins/data_source_management/public/components/data_source_multi_selectable/__snapshots__/data_source_multi_selectable.test.tsx.snap b/src/plugins/data_source_management/public/components/data_source_multi_selectable/__snapshots__/data_source_multi_selectable.test.tsx.snap new file mode 100644 index 000000000000..627a1169c15b --- /dev/null +++ b/src/plugins/data_source_management/public/components/data_source_multi_selectable/__snapshots__/data_source_multi_selectable.test.tsx.snap @@ -0,0 +1,15 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DataSourceMultiSelectable should render normally with local cluster hidden 1`] = ` + +`; + +exports[`DataSourceMultiSelectable should render normally with local cluster not hidden 1`] = ` + +`; diff --git a/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_filter_group.test.tsx b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_filter_group.test.tsx new file mode 100644 index 000000000000..f59b187fbdba --- /dev/null +++ b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_filter_group.test.tsx @@ -0,0 +1,37 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { ShallowWrapper, shallow } from 'enzyme'; +import React from 'react'; +import { DataSourceFilterGroup } from './data_source_filter_group'; +import { render } from '@testing-library/react'; + +describe('DataSourceFilterGroup', () => { + let component: ShallowWrapper, React.Component<{}, {}, any>>; + + it('should render normally', () => { + const mockCallBack = jest.fn(); + component = shallow( + mockCallBack(items)} + /> + ); + expect(component).toMatchSnapshot(); + }); + + it('should render popup when clicking on button', async () => { + const mockCallBack = jest.fn(); + const container = render( + mockCallBack(items)} + /> + ); + const button = await container.findByTestId('dataSourceFilterGroupButton'); + button.click(); + expect(container).toMatchSnapshot(); + }); +}); diff --git a/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_filter_group.tsx b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_filter_group.tsx new file mode 100644 index 000000000000..d35725e97aad --- /dev/null +++ b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_filter_group.tsx @@ -0,0 +1,161 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React, { useState } from 'react'; +import { + EuiNotificationBadge, + EuiFilterSelectItem, + EuiPopover, + EuiPopoverTitle, + EuiFieldSearch, + FilterChecked, + EuiPopoverFooter, + EuiButtonGroup, + EuiButtonEmpty, +} from '@elastic/eui'; +import { DataSourceOption } from '../data_source_selector/data_source_selector'; + +export interface SelectedDataSourceOption extends DataSourceOption { + label: string; + id: string; + visible: boolean; + checked?: FilterChecked; +} + +export interface DataSourceFilterGroupProps { + selectedOptions: SelectedDataSourceOption[]; + setSelectedOptions: (options: SelectedDataSourceOption[]) => void; +} + +type SelectionToggleOptionIds = 'select_all' | 'deselect_all'; + +const selectionToggleButtons = [ + { + id: 'select_all', + label: 'Select all', + }, + { + id: 'deselect_all', + label: 'Deselect all', + }, +]; + +export const DataSourceFilterGroup: React.FC = ({ + selectedOptions, + setSelectedOptions, +}) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const [selectionToggleSelectedId, setSelectionToggleSelectedId] = useState< + SelectionToggleOptionIds + >('select_all'); + + const onButtonClick = () => { + setIsPopoverOpen(!isPopoverOpen); + }; + + const closePopover = () => { + setIsPopoverOpen(false); + }; + + function toggleItem(index: number) { + if (!selectedOptions[index]) { + return; + } + + const newItems = [...selectedOptions]; + + if (newItems[index].checked === 'on') { + newItems[index] = { + ...newItems[index], + checked: undefined, + }; + } else { + newItems[index] = { + ...newItems[index], + checked: 'on', + }; + } + + setSelectedOptions(newItems); + } + + function onSelectionToggleChange(optionId: string) { + setSelectionToggleSelectedId(optionId as SelectionToggleOptionIds); + toggleAll(optionId === 'select_all' ? 'on' : undefined); + } + + function toggleAll(state: 'on' | undefined) { + const optionsAfterToggle = selectedOptions.map((option) => ({ + ...option, + checked: state, + })); + + setSelectedOptions(optionsAfterToggle); + } + + function search(term: string) { + const optionsAfterSearch = selectedOptions.map((option) => { + option.visible = option.label.toLowerCase().includes(term.toLowerCase()); + return option; + }); + setSelectedOptions(optionsAfterSearch); + } + + const numActiveSelections = selectedOptions.filter((option) => option.checked === 'on').length; + const button = ( + <> + + {'Data sources'} + + {numActiveSelections} + + ); + + return ( + + + + +
+ {selectedOptions.map((item, index) => { + const itemStyle: any = {}; + itemStyle.display = !item.visible ? 'none' : itemStyle.display; + + return ( + toggleItem(index)} + showIcons={true} + style={itemStyle} + > + {item.label} + + ); + })} +
+ + + +
+ ); +}; diff --git a/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.test.tsx b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.test.tsx new file mode 100644 index 000000000000..9c352b3578c9 --- /dev/null +++ b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.test.tsx @@ -0,0 +1,63 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import { SavedObjectsClientContract } from 'opensearch-dashboards/public'; +import { notificationServiceMock } from '../../../../../core/public/mocks'; +import { getDataSourcesWithFieldsResponse, mockResponseForSavedObjectsCalls } from '../../mocks'; +import { ShallowWrapper, shallow } from 'enzyme'; +import { DataSourceMultiSelectable } from './data_source_multi_selectable'; +import React from 'react'; + +describe('DataSourceMultiSelectable', () => { + let component: ShallowWrapper, React.Component<{}, {}, any>>; + + let client: SavedObjectsClientContract; + const { toasts } = notificationServiceMock.createStartContract(); + + beforeEach(() => { + client = { + find: jest.fn().mockResolvedValue([]), + } as any; + mockResponseForSavedObjectsCalls(client, 'find', getDataSourcesWithFieldsResponse); + }); + + it('should render normally with local cluster not hidden', () => { + component = shallow( + + ); + expect(component).toMatchSnapshot(); + expect(client.find).toBeCalledWith({ + fields: ['id', 'title', 'auth.type'], + perPage: 10000, + type: 'data-source', + }); + expect(toasts.addWarning).toBeCalledTimes(0); + }); + + it('should render normally with local cluster hidden', () => { + component = shallow( + + ); + expect(component).toMatchSnapshot(); + expect(client.find).toBeCalledWith({ + fields: ['id', 'title', 'auth.type'], + perPage: 10000, + type: 'data-source', + }); + expect(toasts.addWarning).toBeCalledTimes(0); + }); +}); diff --git a/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.tsx b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.tsx new file mode 100644 index 000000000000..8405a37a43c2 --- /dev/null +++ b/src/plugins/data_source_management/public/components/data_source_multi_selectable/data_source_multi_selectable.tsx @@ -0,0 +1,100 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +import React from 'react'; +import { SavedObjectsClientContract, ToastsStart } from 'opensearch-dashboards/public'; +import { i18n } from '@osd/i18n'; +import { DataSourceFilterGroup, SelectedDataSourceOption } from './data_source_filter_group'; +import { getDataSourcesWithFields } from '../utils'; + +export interface DataSourceMultiSeletableProps { + savedObjectsClient: SavedObjectsClientContract; + notifications: ToastsStart; + onSelectedDataSources: (dataSources: SelectedDataSourceOption[]) => void; + hideLocalCluster: boolean; + fullWidth: boolean; +} + +interface DataSourceMultiSeletableState { + dataSourceOptions: SelectedDataSourceOption[]; + selectedOptions: SelectedDataSourceOption[]; +} + +export class DataSourceMultiSelectable extends React.Component< + DataSourceMultiSeletableProps, + DataSourceMultiSeletableState +> { + private _isMounted: boolean = false; + + constructor(props: DataSourceMultiSeletableProps) { + super(props); + + this.state = { + dataSourceOptions: [], + selectedOptions: [], + }; + } + + componentWillUnmount() { + this._isMounted = false; + } + + async componentDidMount() { + this._isMounted = true; + getDataSourcesWithFields(this.props.savedObjectsClient, ['id', 'title', 'auth.type']) + .then((fetchedDataSources) => { + if (fetchedDataSources?.length) { + // all data sources are selected by default on initial page load + const selectedOptions: SelectedDataSourceOption[] = fetchedDataSources.map( + (dataSource) => ({ + id: dataSource.id, + label: dataSource.attributes?.title || '', + checked: 'on', + visible: true, + }) + ); + + if (!this.props.hideLocalCluster) { + selectedOptions.unshift({ + id: '', + label: 'Local cluster', + checked: 'on', + visible: true, + }); + } + + if (!this._isMounted) return; + this.setState({ + ...this.state, + selectedOptions, + }); + } + }) + .catch(() => { + this.props.notifications.addWarning( + i18n.translate('dataSource.fetchDataSourceError', { + defaultMessage: 'Unable to fetch existing data sources', + }) + ); + }); + } + + onChange(selectedOptions: SelectedDataSourceOption[]) { + if (!this._isMounted) return; + this.setState({ + selectedOptions, + }); + this.props.onSelectedDataSources(selectedOptions.filter((option) => option.checked === 'on')); + } + + render() { + return ( + + ); + } +} diff --git a/src/plugins/data_source_management/public/components/data_source_multi_selectable/index.ts b/src/plugins/data_source_management/public/components/data_source_multi_selectable/index.ts new file mode 100644 index 000000000000..440cbfdc8202 --- /dev/null +++ b/src/plugins/data_source_management/public/components/data_source_multi_selectable/index.ts @@ -0,0 +1,6 @@ +/* + * Copyright OpenSearch Contributors + * SPDX-License-Identifier: Apache-2.0 + */ + +export { DataSourceMultiSelectable } from './data_source_multi_selectable'; From e725a3f8f2fdb9d1f531df96fde94d7451fc1f6e Mon Sep 17 00:00:00 2001 From: Lu Yu Date: Tue, 19 Mar 2024 22:52:40 +0000 Subject: [PATCH 2/8] update change log Signed-off-by: Lu Yu --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f66d66183da8..520812549fa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) - [Dynamic Configurations] Pass request headers when making application config calls ([#6164](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6164)) - [Discover] Options button to configure legacy mode and remove the top navigation option ([#6170](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6170)) - [Multiple Datasource] Add default functionality for customer to choose default datasource ([#6058](https://github.com/opensearch-project/OpenSearch-Dashboards/issues/6058)) +- [Multiple Datasource] Add multi selectable data source component ([#6211](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6211)) ### 🐛 Bug Fixes From 44324d57889f2e386558070c2864bb86641e2271 Mon Sep 17 00:00:00 2001 From: Lu Yu Date: Thu, 21 Mar 2024 05:18:01 +0000 Subject: [PATCH 3/8] add tests Signed-off-by: Lu Yu --- .../data_source_menu.test.tsx.snap | 61 ++++ .../data_source_selectable.test.tsx.snap | 238 ++++++++++++++ .../data_source_menu.test.tsx | 14 + .../data_source_selectable.test.tsx | 19 ++ .../data_source_selectable.tsx | 1 + .../data_source_filter_group.test.tsx.snap | 299 ++++++++++++++++++ .../data_source_filter_group.test.tsx | 40 ++- .../data_source_filter_group.tsx | 7 +- 8 files changed, 677 insertions(+), 2 deletions(-) diff --git a/src/plugins/data_source_management/public/components/data_source_menu/__snapshots__/data_source_menu.test.tsx.snap b/src/plugins/data_source_management/public/components/data_source_menu/__snapshots__/data_source_menu.test.tsx.snap index ea00d96c5798..74e3611b7379 100644 --- a/src/plugins/data_source_management/public/components/data_source_menu/__snapshots__/data_source_menu.test.tsx.snap +++ b/src/plugins/data_source_management/public/components/data_source_menu/__snapshots__/data_source_menu.test.tsx.snap @@ -61,6 +61,67 @@ Object { } `; +exports[`DataSourceMenu should render data source multi select component 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+ , + "container":
, + "debug": [Function], + "findAllByAltText": [Function], + "findAllByDisplayValue": [Function], + "findAllByLabelText": [Function], + "findAllByPlaceholderText": [Function], + "findAllByRole": [Function], + "findAllByTestId": [Function], + "findAllByText": [Function], + "findAllByTitle": [Function], + "findByAltText": [Function], + "findByDisplayValue": [Function], + "findByLabelText": [Function], + "findByPlaceholderText": [Function], + "findByRole": [Function], + "findByTestId": [Function], + "findByText": [Function], + "findByTitle": [Function], + "getAllByAltText": [Function], + "getAllByDisplayValue": [Function], + "getAllByLabelText": [Function], + "getAllByPlaceholderText": [Function], + "getAllByRole": [Function], + "getAllByTestId": [Function], + "getAllByText": [Function], + "getAllByTitle": [Function], + "getByAltText": [Function], + "getByDisplayValue": [Function], + "getByLabelText": [Function], + "getByPlaceholderText": [Function], + "getByRole": [Function], + "getByTestId": [Function], + "getByText": [Function], + "getByTitle": [Function], + "queryAllByAltText": [Function], + "queryAllByDisplayValue": [Function], + "queryAllByLabelText": [Function], + "queryAllByPlaceholderText": [Function], + "queryAllByRole": [Function], + "queryAllByTestId": [Function], + "queryAllByText": [Function], + "queryAllByTitle": [Function], + "queryByAltText": [Function], + "queryByDisplayValue": [Function], + "queryByLabelText": [Function], + "queryByPlaceholderText": [Function], + "queryByRole": [Function], + "queryByTestId": [Function], + "queryByText": [Function], + "queryByTitle": [Function], + "rerender": [Function], + "unmount": [Function], +} +`; + exports[`DataSourceMenu should render data source selectable only with local cluster is hidden 1`] = ` `; + +exports[`DataSourceSelectable should show popover when click on button 1`] = ` +Object { + "asFragment": [Function], + "baseElement": +
+
+
+ + +
+
+
+
+
+