diff --git a/examples/multiple_data_source_examples/public/application.tsx b/examples/multiple_data_source_examples/public/application.tsx
index 16d9c928b04c..81248f8adccf 100644
--- a/examples/multiple_data_source_examples/public/application.tsx
+++ b/examples/multiple_data_source_examples/public/application.tsx
@@ -11,7 +11,7 @@ import { CoreStart, AppMountParameters } from '../../../src/core/public';
import { Home } from './components/home';
export const renderApp = (
- { notifications, http, savedObjects, application }: CoreStart,
+ { notifications, http, savedObjects, application, uiSettings }: CoreStart,
dataSource: DataSourcePluginSetup,
dataSourceManagement: DataSourceManagementPluginSetup,
{ appBasePath, element, setHeaderActionMenu }: AppMountParameters,
@@ -28,6 +28,7 @@ export const renderApp = (
dataSourceManagement={dataSourceManagement}
navigateToApp={application.navigateToApp}
navigation={navigation}
+ uiSettings={uiSettings}
/>,
element
);
diff --git a/examples/multiple_data_source_examples/public/components/data_source_list_active_example.tsx b/examples/multiple_data_source_examples/public/components/data_source_list_active_example.tsx
index 529d610c8132..81a15e2c03da 100644
--- a/examples/multiple_data_source_examples/public/components/data_source_list_active_example.tsx
+++ b/examples/multiple_data_source_examples/public/components/data_source_list_active_example.tsx
@@ -28,6 +28,7 @@ interface DataSourceListActiveExampleProps {
notifications: CoreStart['notifications'];
setActionMenu?: (menuMount: MountPoint | undefined) => void;
dataSourceManagement: DataSourceManagementPluginSetup;
+ uiSettings: CoreStart['uiSettings'];
}
export const DataSourceListActiveExample = ({
@@ -36,6 +37,7 @@ export const DataSourceListActiveExample = ({
notifications,
setActionMenu,
dataSourceManagement,
+ uiSettings,
}: DataSourceListActiveExampleProps) => {
const DataSourceMenu = dataSourceManagement.ui.getDataSourceMenu<
DataSourceAggregatedViewConfig
@@ -106,7 +108,10 @@ export const DataSourceListActiveExample = ({
fullWidth: false,
savedObjects: savedObjects.client,
notifications,
- displayAllCompatibleDataSources: true,
+ displayAllCompatibleDataSources: false,
+ // To see selected options, obtain the datasource id and paste it here. Note that this needs to be defined when displayAllCompatibleDataSources is false
+ activeDataSourceIds: [],
+ uiSettings,
}}
/>
)}
diff --git a/examples/multiple_data_source_examples/public/components/data_source_list_all_example.tsx b/examples/multiple_data_source_examples/public/components/data_source_list_all_example.tsx
index 26545fef70c7..570e51be36e9 100644
--- a/examples/multiple_data_source_examples/public/components/data_source_list_all_example.tsx
+++ b/examples/multiple_data_source_examples/public/components/data_source_list_all_example.tsx
@@ -28,6 +28,7 @@ interface DataSourceListAllExampleProps {
notifications: CoreStart['notifications'];
setActionMenu?: (menuMount: MountPoint | undefined) => void;
dataSourceManagement: DataSourceManagementPluginSetup;
+ uiSettings: CoreStart['uiSettings'];
}
export const DataSourceListAllExample = ({
@@ -36,6 +37,7 @@ export const DataSourceListAllExample = ({
notifications,
setActionMenu,
dataSourceManagement,
+ uiSettings,
}: DataSourceListAllExampleProps) => {
const DataSourceMenu = dataSourceManagement.ui.getDataSourceMenu<
DataSourceAggregatedViewConfig
@@ -100,6 +102,7 @@ export const DataSourceListAllExample = ({
savedObjects: savedObjects.client,
notifications,
displayAllCompatibleDataSources: true,
+ uiSettings,
}}
/>
)}
diff --git a/examples/multiple_data_source_examples/public/components/home.tsx b/examples/multiple_data_source_examples/public/components/home.tsx
index fe6ca1f285a4..c7a61c590c63 100644
--- a/examples/multiple_data_source_examples/public/components/home.tsx
+++ b/examples/multiple_data_source_examples/public/components/home.tsx
@@ -22,6 +22,7 @@ export interface HomeProps {
notifications: CoreStart['notifications'];
http: CoreStart['http'];
savedObjects: CoreStart['savedObjects'];
+ uiSettings: CoreStart['uiSettings'];
dataSourceEnabled: boolean;
dataSourceManagement: DataSourceManagementPluginSetup;
navigateToApp: CoreStart['application']['navigateToApp'];
@@ -65,6 +66,7 @@ export const Home = ({
basename,
notifications,
savedObjects,
+ uiSettings,
dataSourceEnabled,
setActionMenu,
dataSourceManagement,
@@ -133,6 +135,7 @@ export const Home = ({
dataSourceEnabled={dataSourceEnabled}
setActionMenu={setActionMenu}
dataSourceManagement={dataSourceManagement}
+ uiSettings={uiSettings}
/>
),
},
@@ -146,6 +149,7 @@ export const Home = ({
dataSourceEnabled={dataSourceEnabled}
setActionMenu={setActionMenu}
dataSourceManagement={dataSourceManagement}
+ uiSettings={uiSettings}
/>
),
},
diff --git a/src/plugins/data_source_management/public/components/data_source_aggregated_view/__snapshots__/data_source_aggregated_view.test.tsx.snap b/src/plugins/data_source_management/public/components/data_source_aggregated_view/__snapshots__/data_source_aggregated_view.test.tsx.snap
index e4f4b1f67c67..57ba243a476b 100644
--- a/src/plugins/data_source_management/public/components/data_source_aggregated_view/__snapshots__/data_source_aggregated_view.test.tsx.snap
+++ b/src/plugins/data_source_management/public/components/data_source_aggregated_view/__snapshots__/data_source_aggregated_view.test.tsx.snap
@@ -1,119 +1,155 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`DataSourceAggregatedView should render normally with data source filter 1`] = `
-
+
}
- }
->
-
-
-
- All
-
-
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read active view (displayAllCompatibleDataSources is set to false) should render normally with local cluster and active selections configured 2`] = `
+
}
closePopover={[Function]}
@@ -124,169 +160,687 @@ exports[`DataSourceAggregatedView should render normally with data source filter
ownFocus={true}
panelPaddingSize="none"
>
-
+
+
+
+
+
+
+
+
-
+
`;
-exports[`DataSourceAggregatedView should render normally with local cluster and actice selections 1`] = `
-
+
}
- }
- savedObjectsClient={
- Object {
- "find": [MockFunction] {
- "calls": Array [
- Array [
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read active view (displayAllCompatibleDataSources is set to false) should render normally with local cluster and active selections configured 4`] = `
+
+
}
- }
->
-
+`;
+
+exports[`DataSourceAggregatedView: read active view (displayAllCompatibleDataSources is set to false) should render normally with local cluster and active selections configured 5`] = `
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
-
-
-
-
-
- Data sources
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read active view (displayAllCompatibleDataSources is set to false) should render normally with local cluster and active selections configured 6`] = `
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
>
-
- 1
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read active view (displayAllCompatibleDataSources is set to false) should render normally with local cluster and active selections configured 7`] = `
+
}
closePopover={[Function]}
@@ -297,165 +851,564 @@ exports[`DataSourceAggregatedView should render normally with local cluster and
ownFocus={true}
panelPaddingSize="none"
>
-
+
+
+
+
+
+
+
+
-
+
`;
-exports[`DataSourceAggregatedView should render normally with local cluster hidden and all options 1`] = `
-
+
}
- }
- savedObjectsClient={
- Object {
- "find": [MockFunction] {
- "calls": Array [
- Array [
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read all view (displayAllCompatibleDataSources is set to true) should render normally with local cluster configured, default datasource removed or added, and if activeDataSourceIds is present or filtered out 1`] = `
+
+
}
- }
->
-
+`;
+
+exports[`DataSourceAggregatedView: read all view (displayAllCompatibleDataSources is set to true) should render normally with local cluster configured, default datasource removed or added, and if activeDataSourceIds is present or filtered out 2`] = `
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
-
-
-
-
-
- Data sources
-
-
-
-
-
-
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read all view (displayAllCompatibleDataSources is set to true) should render normally with local cluster configured, default datasource removed or added, and if activeDataSourceIds is present or filtered out 3`] = `
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
>
-
- 0
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read all view (displayAllCompatibleDataSources is set to true) should render normally with local cluster configured, default datasource removed or added, and if activeDataSourceIds is present or filtered out 4`] = `
+
}
closePopover={[Function]}
@@ -466,78 +1419,96 @@ exports[`DataSourceAggregatedView should render normally with local cluster hidd
ownFocus={true}
panelPaddingSize="none"
>
-
+
+
+
+
+
-
+
`;
-exports[`DataSourceAggregatedView should render normally with local cluster not hidden and all options 1`] = `
+exports[`DataSourceAggregatedView: read all view (displayAllCompatibleDataSources is set to true) should render normally with local cluster configured, default datasource removed or added, and if activeDataSourceIds is present or filtered out 5`] = `
-
- Data sources
-
-
- All
-
}
closePopover={[Function]}
@@ -548,246 +1519,579 @@ exports[`DataSourceAggregatedView should render normally with local cluster not
ownFocus={true}
panelPaddingSize="none"
>
-
+
+
+
+
+
+
+
+
+
+
+
+
`;
-exports[`DataSourceAggregatedView should render popup when clicking on info icon 1`] = `
-Object {
- "asFragment": [Function],
- "baseElement":
-
-
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
-
+
+
+
-
-
- Data sources
-
-
-
-
- 1
-
-
-
-
-
-
-
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read all view (displayAllCompatibleDataSources is set to true) should render normally with local cluster configured, default datasource removed or added, and if activeDataSourceIds is present or filtered out 8`] = `
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
+
+
+
+
+
-
-
- You are in a dialog. To close this dialog, hit escape.
-
-
-
-
-
-
-
- ,
- "container":
-
+
+
+
+
+
+
+`;
+
+exports[`DataSourceAggregatedView: read all view (displayAllCompatibleDataSources is set to true) should render normally with local cluster configured, default datasource removed or added, and if activeDataSourceIds is present or filtered out 9`] = `
+
+
+ }
+ closePopover={[Function]}
+ display="inlineBlock"
+ hasArrow={true}
+ id="dataSourceSViewContextMenuPopover"
+ isOpen={false}
+ ownFocus={true}
+ panelPaddingSize="none"
+ >
+
-
-
-
+
+
- Data sources
-
-
-
-
- 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_aggregated_view/data_source_aggregated_view.scss b/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.scss
new file mode 100644
index 000000000000..9e8d78eac91b
--- /dev/null
+++ b/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.scss
@@ -0,0 +1,19 @@
+.dataSourceAggregatedViewOuiPanel {
+ width: 300px;
+
+ .dataSourceAggregatedViewOuiFlexGroup {
+ .dataSourceAggregatedViewOuiFlexItem {
+ color: grey;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ display: inline-block;
+ }
+ }
+
+ .dataSourceAggregatedViewOuiSwitch {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+}
diff --git a/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.test.tsx b/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.test.tsx
index 5bb518af2d06..5251ed199cca 100644
--- a/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.test.tsx
+++ b/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.test.tsx
@@ -3,124 +3,269 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { ShallowWrapper, mount, shallow } from 'enzyme';
+import { ShallowWrapper, shallow } from 'enzyme';
import React from 'react';
import { DataSourceAggregatedView } from './data_source_aggregated_view';
-import { SavedObjectsClientContract } from '../../../../../core/public';
-import { notificationServiceMock } from '../../../../../core/public/mocks';
-import { getDataSourcesWithFieldsResponse, mockResponseForSavedObjectsCalls } from '../../mocks';
-import { render } from '@testing-library/react';
+import { SavedObject, SavedObjectsClientContract } from '../../../../../core/public';
+import {
+ applicationServiceMock,
+ notificationServiceMock,
+ uiSettingsServiceMock,
+} from '../../../../../core/public/mocks';
+import {
+ getDataSourcesWithFieldsResponse,
+ mockResponseForSavedObjectsCalls,
+ mockUiSettingsCalls,
+} from '../../mocks';
+import * as utils from '../utils';
+import { EuiSelectable, EuiSwitch } from '@elastic/eui';
+import { DataSourceAttributes } from '../../types';
-describe('DataSourceAggregatedView', () => {
+describe('DataSourceAggregatedView: read all view (displayAllCompatibleDataSources is set to true)', () => {
let component: ShallowWrapper, React.Component<{}, {}, any>>;
let client: SavedObjectsClientContract;
const { toasts } = notificationServiceMock.createStartContract();
+ const uiSettings = uiSettingsServiceMock.createStartContract();
+ const application = applicationServiceMock.createStartContract();
+ const nextTick = () => new Promise((res) => process.nextTick(res));
beforeEach(() => {
client = {
find: jest.fn().mockResolvedValue([]),
} as any;
mockResponseForSavedObjectsCalls(client, 'find', getDataSourcesWithFieldsResponse);
+ mockUiSettingsCalls(uiSettings, 'get', 'test1');
+ jest.spyOn(utils, 'getApplication').mockReturnValue(application);
});
- it('should render normally with local cluster not hidden and all options', () => {
- 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.each([
+ {
+ filter: (ds: SavedObject) => {
+ return ds.id !== 'test1';
+ },
+ activeDataSourceIds: undefined,
+ hideLocalCluster: false,
+ },
+ {
+ filter: (ds: SavedObject) => {
+ return ds.id !== 'test1';
+ },
+ activeDataSourceIds: ['non-existent-id'],
+ hideLocalCluster: false,
+ },
+ {
+ filter: undefined,
+ activeDataSourceIds: undefined,
+ hideLocalCluster: false,
+ },
+ {
+ filter: undefined,
+ activeDataSourceIds: ['non-existent-id'],
+ hideLocalCluster: false,
+ },
+ {
+ filter: undefined,
+ activeDataSourceIds: ['test1'],
+ hideLocalCluster: false,
+ },
+ {
+ filter: (ds: SavedObject) => {
+ return ds.id !== 'test1';
+ },
+ activeDataSourceIds: undefined,
+ hideLocalCluster: true,
+ },
+ {
+ filter: (ds: SavedObject) => {
+ return ds.id !== 'test1';
+ },
+ activeDataSourceIds: ['non-existent-id'],
+ hideLocalCluster: true,
+ },
+ {
+ filter: undefined,
+ activeDataSourceIds: undefined,
+ hideLocalCluster: true,
+ },
+ {
+ filter: undefined,
+ activeDataSourceIds: ['non-existent-id'],
+ hideLocalCluster: true,
+ },
+ {
+ filter: undefined,
+ activeDataSourceIds: ['test1'],
+ hideLocalCluster: true,
+ },
+ ])(
+ 'should render normally with local cluster configured, default datasource removed or added, and if activeDataSourceIds is present or filtered out',
+ async ({ filter, activeDataSourceIds, hideLocalCluster }) => {
+ component = shallow(
+
+ );
- it('should render normally with local cluster hidden and all options', () => {
- const container = mount(
-
- );
- expect(container).toMatchSnapshot();
- expect(client.find).toBeCalledWith({
- fields: ['id', 'title', 'auth.type'],
- perPage: 10000,
- type: 'data-source',
- });
- expect(toasts.addWarning).toBeCalledTimes(0);
- const badge = container.find('EuiNotificationBadge').text();
- expect(badge).toEqual('0');
- });
+ // Renders normally
+ expect(component).toMatchSnapshot();
+ expect(client.find).toBeCalledWith({
+ fields: ['id', 'title', 'auth.type'],
+ perPage: 10000,
+ type: 'data-source',
+ });
+ expect(toasts.addWarning).toBeCalledTimes(0);
+ await nextTick();
- it('should render normally with local cluster and actice selections', () => {
- const container = mount(
-
- );
- expect(container).toMatchSnapshot();
- expect(client.find).toBeCalledWith({
- fields: ['id', 'title', 'auth.type'],
- perPage: 10000,
- type: 'data-source',
- });
- expect(toasts.addWarning).toBeCalledTimes(0);
- const badge = container.find('EuiNotificationBadge').text();
- expect(badge).toEqual('1');
- });
+ // Renders correctly for hide local cluster configuration
+ if (!hideLocalCluster) {
+ expect(component.find(EuiSelectable).prop('options')).toEqual(
+ expect.arrayContaining([expect.objectContaining({ id: '' })])
+ );
+ } else {
+ expect(component.find(EuiSelectable).prop('options')).not.toEqual(
+ expect.arrayContaining([expect.objectContaining({ id: '' })])
+ );
+ }
- it('should render normally with data source filter', () => {
- const container = mount(
- ds.attributes.auth.type !== 'no_auth'}
- />
- );
- expect(container).toMatchSnapshot();
- expect(client.find).toBeCalledWith({
- fields: ['id', 'title', 'auth.type'],
- perPage: 10000,
- type: 'data-source',
- });
- expect(toasts.addWarning).toBeCalledTimes(0);
- const badge = container.find('EuiNotificationBadge').text();
- expect(badge).toEqual('All');
- });
+ // Renders correctly when default datasource is filtered out or not
+ if (!filter) {
+ expect(component.find(EuiSelectable).prop('options')).toEqual(
+ expect.arrayContaining([expect.objectContaining({ id: 'test1' })])
+ );
+ } else {
+ expect(component.find(EuiSelectable).prop('options')).not.toEqual(
+ expect.arrayContaining([expect.objectContaining({ id: 'test1' })])
+ );
+ }
+
+ // All renders should not have a switch
+ expect(component.find(EuiSwitch).exists()).toBeFalsy();
+ }
+ );
+});
+
+describe('DataSourceAggregatedView: read active view (displayAllCompatibleDataSources is set to false)', () => {
+ let client: SavedObjectsClientContract;
+ const { toasts } = notificationServiceMock.createStartContract();
+ const uiSettings = uiSettingsServiceMock.createStartContract();
+ const nextTick = () => new Promise((res) => process.nextTick(res));
- it('should render popup when clicking on info icon', async () => {
- const container = render(
-
- );
- const infoIcon = await container.findByTestId('dataSourceAggregatedViewInfoButton');
- infoIcon.click();
- expect(container).toMatchSnapshot();
+ beforeEach(() => {
+ client = {
+ find: jest.fn().mockResolvedValue([]),
+ } as any;
+ mockResponseForSavedObjectsCalls(client, 'find', getDataSourcesWithFieldsResponse);
+ mockUiSettingsCalls(uiSettings, 'get', 'test1');
});
+
+ it.each([
+ {
+ filter: (ds: SavedObject) => {
+ return ds.id !== 'test1';
+ },
+ hideLocalCluster: false,
+ activeDataSourceIds: ['test1', 'test2'],
+ },
+ {
+ filter: undefined,
+ hideLocalCluster: false,
+ activeDataSourceIds: ['test1', 'test2'],
+ },
+ {
+ filter: (ds: SavedObject) => {
+ return ds.id !== 'test1';
+ },
+ hideLocalCluster: true,
+ activeDataSourceIds: ['test1', 'test2'],
+ },
+ {
+ filter: undefined,
+ hideLocalCluster: true,
+ activeDataSourceIds: ['test1', 'test2'],
+ },
+ {
+ filter: (ds: SavedObject) => {
+ return ds.id !== 'test1';
+ },
+ hideLocalCluster: false,
+ activeDataSourceIds: [],
+ },
+ {
+ filter: undefined,
+ hideLocalCluster: false,
+ activeDataSourceIds: [],
+ },
+ {
+ filter: (ds: SavedObject) => {
+ return ds.id !== 'test1';
+ },
+ hideLocalCluster: true,
+ activeDataSourceIds: [],
+ },
+ {
+ filter: undefined,
+ hideLocalCluster: true,
+ activeDataSourceIds: [],
+ },
+ ])(
+ 'should render normally with local cluster and active selections configured',
+ async ({ filter, hideLocalCluster, activeDataSourceIds }) => {
+ const component = shallow(
+
+ );
+ await nextTick();
+
+ // Should render normally
+ expect(component).toMatchSnapshot();
+ expect(client.find).toBeCalledWith({
+ fields: ['id', 'title', 'auth.type'],
+ perPage: 10000,
+ type: 'data-source',
+ });
+ expect(toasts.addWarning).toBeCalledTimes(0);
+
+ // Should render only active options
+ const euiSwitch = component.find(EuiSwitch);
+ expect(euiSwitch.exists()).toBeTruthy();
+ euiSwitch.prop('onChange')({ target: { checked: true } });
+ const expectedOptions = activeDataSourceIds.length
+ ? [
+ {
+ id: 'test2',
+ label: 'test2',
+ disabled: true,
+ checked: 'on',
+ },
+ ]
+ : [];
+
+ if (!filter && activeDataSourceIds.length) {
+ expectedOptions.push({
+ id: 'test1',
+ label: 'test1',
+ disabled: true,
+ checked: 'on',
+ });
+ }
+ expect(component.find(EuiSelectable).prop('options')).toEqual(
+ expect.arrayContaining(expectedOptions)
+ );
+ }
+ );
});
diff --git a/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.tsx b/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.tsx
index c77a49a75831..16b63d36d912 100644
--- a/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.tsx
+++ b/src/plugins/data_source_management/public/components/data_source_aggregated_view/data_source_aggregated_view.tsx
@@ -6,19 +6,28 @@
import React from 'react';
import {
EuiButtonEmpty,
- EuiButtonIcon,
- EuiContextMenu,
- EuiNotificationBadge,
+ EuiContextMenuPanel,
+ EuiPanel,
EuiPopover,
+ EuiSelectable,
+ EuiSwitch,
} from '@elastic/eui';
import { i18n } from '@osd/i18n';
-import { SavedObjectsClientContract, ToastsStart } from 'opensearch-dashboards/public';
-import { getDataSourcesWithFields, handleDataSourceFetchError } from '../utils';
+import {
+ IUiSettingsClient,
+ SavedObjectsClientContract,
+ ToastsStart,
+} from 'opensearch-dashboards/public';
+import { getApplication, getDataSourcesWithFields, handleDataSourceFetchError } from '../utils';
import { SavedObject } from '../../../../../core/public';
import { DataSourceAttributes } from '../../types';
import { NoDataSource } from '../no_data_source';
import { DataSourceErrorMenu } from '../data_source_error_menu';
import { DataSourceBaseState } from '../data_source_menu/types';
+import { DataSourceOption } from '../data_source_menu/types';
+import { DataSourceItem } from '../data_source_item';
+import { DataSourceDropDownHeader } from '../drop_down_header';
+import './data_source_aggregated_view.scss';
interface DataSourceAggregatedViewProps {
savedObjectsClient: SavedObjectsClientContract;
@@ -28,11 +37,19 @@ interface DataSourceAggregatedViewProps {
activeDataSourceIds?: string[];
dataSourceFilter?: (dataSource: SavedObject) => boolean;
displayAllCompatibleDataSources: boolean;
+ uiSettings?: IUiSettingsClient;
}
interface DataSourceAggregatedViewState extends DataSourceBaseState {
isPopoverOpen: boolean;
allDataSourcesIdToTitleMap: Map;
+ switchChecked: boolean;
+ defaultDataSource: string | null;
+}
+
+interface DataSourceOptionDisplay extends DataSourceOption {
+ disabled?: boolean;
+ checked?: string;
}
export class DataSourceAggregatedView extends React.Component<
@@ -49,6 +66,8 @@ export class DataSourceAggregatedView extends React.Component<
allDataSourcesIdToTitleMap: new Map(),
showEmptyState: false,
showError: false,
+ switchChecked: false,
+ defaultDataSource: null,
};
}
@@ -56,10 +75,14 @@ export class DataSourceAggregatedView extends React.Component<
this._isMounted = false;
}
- onClick() {
+ onDataSourcesClick() {
this.setState({ ...this.state, isPopoverOpen: !this.state.isPopoverOpen });
}
+ onSwitchClick(e) {
+ this.setState({ ...this.state, switchChecked: e.target.checked });
+ }
+
closePopover() {
this.setState({ ...this.state, isPopoverOpen: false });
}
@@ -68,6 +91,8 @@ export class DataSourceAggregatedView extends React.Component<
this._isMounted = true;
getDataSourcesWithFields(this.props.savedObjectsClient, ['id', 'title', 'auth.type'])
.then((fetchedDataSources) => {
+ const allDataSourcesIdToTitleMap = new Map();
+
if (fetchedDataSources?.length) {
let filteredDataSources = fetchedDataSources;
if (this.props.dataSourceFilter) {
@@ -75,22 +100,24 @@ export class DataSourceAggregatedView extends React.Component<
this.props.dataSourceFilter!(ds)
);
}
- const allDataSourcesIdToTitleMap = new Map();
filteredDataSources.forEach((ds) => {
allDataSourcesIdToTitleMap.set(ds.id, ds.attributes!.title || '');
});
- if (!this.props.hideLocalCluster) {
- allDataSourcesIdToTitleMap.set('', 'Local cluster');
- }
-
if (!this._isMounted) return;
- this.setState({
- ...this.state,
- allDataSourcesIdToTitleMap,
- });
}
+
+ if (!this.props.hideLocalCluster) {
+ allDataSourcesIdToTitleMap.set('', 'Local cluster');
+ }
+
+ this.setState({
+ ...this.state,
+ allDataSourcesIdToTitleMap,
+ defaultDataSource: this.props.uiSettings?.get('defaultDataSource', null) ?? null,
+ showEmptyState: allDataSourcesIdToTitleMap.size === 0,
+ });
})
.catch(() => {
handleDataSourceFetchError(this.onError.bind(this), this.props.notifications);
@@ -109,65 +136,64 @@ export class DataSourceAggregatedView extends React.Component<
return ;
}
const button = (
-
);
- let items = [];
+ let items: DataSourceOptionDisplay[] = [];
// only display active data sources
- if (this.props.displayAllCompatibleDataSources) {
- items = [...this.state.allDataSourcesIdToTitleMap.values()].map((title) => {
- return {
- name: title,
- disabled: true,
- };
- });
+ if (!this.props.displayAllCompatibleDataSources && this.state.switchChecked) {
+ items = this.props
+ .activeDataSourceIds!.filter((id) => this.state.allDataSourcesIdToTitleMap.has(id))
+ .map((id) => {
+ return {
+ id,
+ label: this.state.allDataSourcesIdToTitleMap.get(id),
+ disabled: true,
+ checked: 'on',
+ };
+ });
} else {
- items = this.props.activeDataSourceIds!.map((id) => {
- return {
- name: this.state.allDataSourcesIdToTitleMap.get(id),
+ this.state.allDataSourcesIdToTitleMap.forEach((label, id) => {
+ items.push({
+ id,
+ label,
disabled: true,
- };
+ checked:
+ !this.props.displayAllCompatibleDataSources &&
+ this.props.activeDataSourceIds &&
+ this.props.activeDataSourceIds.length &&
+ this.props.activeDataSourceIds.includes(id)
+ ? 'on'
+ : undefined,
+ });
});
}
- const title = this.props.displayAllCompatibleDataSources
- ? `Data sources (${this.state.allDataSourcesIdToTitleMap.size})`
- : 'Selected data sources';
+ const numSelectedItems = items.filter((item) => item.checked === 'on').length;
- const panels = [
- {
- id: 0,
- title,
- items,
- },
- ];
+ const titleComponent = (
+
+ );
return (
<>
-
- {'Data sources'}
-
-
- {(this.props.displayAllCompatibleDataSources && 'All') ||
- this.props.activeDataSourceIds!.length}
-
>
);
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 517f8de733ba..3ec264b888ff 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
@@ -68,33 +68,6 @@ Object {
"asFragment": [Function],
"baseElement":
-
-
- All
-
,
"container":
-
-
- All
-
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 4353dfc0bbf7..c8325a5b14b4 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
@@ -5,17 +5,19 @@
import { ShallowWrapper, shallow } from 'enzyme';
import { SavedObjectsClientContract } from '../../../../../core/public';
-import { notificationServiceMock } from '../../../../../core/public/mocks';
+import { applicationServiceMock, notificationServiceMock } from '../../../../../core/public/mocks';
import React from 'react';
import { DataSourceMenu } from './data_source_menu';
import { render } from '@testing-library/react';
import { DataSourceComponentType } from './types';
+import * as utils from '../utils';
describe('DataSourceMenu', () => {
let component: ShallowWrapper, React.Component<{}, {}, any>>;
let client: SavedObjectsClientContract;
const notifications = notificationServiceMock.createStartContract();
+ const application = applicationServiceMock.createStartContract();
beforeEach(() => {
client = {
@@ -112,6 +114,7 @@ describe('DataSourceMenu', () => {
});
it('should render data source aggregated view', () => {
+ jest.spyOn(utils, 'getApplication').mockReturnValue(application);
const container = render(
(props: DataSourceMenuProps): ReactElement |
notifications={notifications!.toasts}
activeDataSourceIds={activeDataSourceIds}
dataSourceFilter={dataSourceFilter}
- displayAllCompatibleDataSources={displayAllCompatibleDataSources || false}
+ displayAllCompatibleDataSources={displayAllCompatibleDataSources}
+ uiSettings={uiSettings}
/>
);
}
diff --git a/src/plugins/data_source_management/public/components/data_source_menu/types.ts b/src/plugins/data_source_management/public/components/data_source_menu/types.ts
index d6d960c0e40a..3708291f0a89 100644
--- a/src/plugins/data_source_management/public/components/data_source_menu/types.ts
+++ b/src/plugins/data_source_management/public/components/data_source_menu/types.ts
@@ -59,14 +59,23 @@ export interface DataSourceViewConfig extends DataSourceBaseConfig {
onSelectedDataSources?: (dataSources: DataSourceOption[]) => void;
}
-export interface DataSourceAggregatedViewConfig extends DataSourceBaseConfig {
+interface DataSourceAggregatedViewBaseConfig extends DataSourceBaseConfig {
savedObjects: SavedObjectsClientContract;
notifications: NotificationsStart;
- activeDataSourceIds?: string[];
- displayAllCompatibleDataSources?: boolean;
dataSourceFilter?: (dataSource: SavedObject) => boolean;
+ uiSettings?: IUiSettingsClient;
}
+export type DataSourceAggregatedViewConfig =
+ | (DataSourceAggregatedViewBaseConfig & {
+ activeDataSourceIds: string[];
+ displayAllCompatibleDataSources: false;
+ })
+ | (DataSourceAggregatedViewBaseConfig & {
+ activeDataSourceIds?: string[];
+ displayAllCompatibleDataSources: true;
+ });
+
export interface DataSourceSelectableConfig extends DataSourceBaseConfig {
onSelectedDataSources: (dataSources: DataSourceOption[]) => void;
savedObjects: SavedObjectsClientContract;