diff --git a/CHANGELOG.md b/CHANGELOG.md
index bbcc7f0a9c96..13fe245175ec 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -91,6 +91,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [Dynamic Configurations] Improve dynamic configurations by adding cache and simplifying client fetch ([#6364](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6364))
- [MD] Add OpenSearch cluster group label to top of single selectable dropdown ([#6400](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6400))
- [Workspace] Support workspace in saved objects client in server side. ([#6365](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6365))
+- [MD] Add dropdown header to data source single selector ([#6431](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6431))
### 🐛 Bug Fixes
diff --git a/src/plugins/data_source_management/public/components/__snapshots__/drop_down_header.test.tsx.snap b/src/plugins/data_source_management/public/components/__snapshots__/drop_down_header.test.tsx.snap
new file mode 100644
index 000000000000..ceae0b915add
--- /dev/null
+++ b/src/plugins/data_source_management/public/components/__snapshots__/drop_down_header.test.tsx.snap
@@ -0,0 +1,34 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`DataSourceDropDownHeader should render correctly with the provided dataSourceCount 1`] = `
+
+
+
+ DATA SOURCE(
+ 5
+ )
+
+
+
+
+ Manage
+
+
+
+
+`;
diff --git a/src/plugins/data_source_management/public/components/data_source_menu/create_data_source_menu.tsx b/src/plugins/data_source_management/public/components/data_source_menu/create_data_source_menu.tsx
index 56fd7a7a7cb3..f99cc6558bca 100644
--- a/src/plugins/data_source_management/public/components/data_source_menu/create_data_source_menu.tsx
+++ b/src/plugins/data_source_management/public/components/data_source_menu/create_data_source_menu.tsx
@@ -10,11 +10,13 @@ import { DataSourcePluginSetup } from 'src/plugins/data_source/public';
import { DataSourceMenu } from './data_source_menu';
import { DataSourceMenuProps } from './types';
import { MountPointPortal } from '../../../../opensearch_dashboards_react/public';
+import { applicationService } from '../utils';
export function createDataSourceMenu(
uiSettings: IUiSettingsClient,
dataSourcePluginSetup: DataSourcePluginSetup
) {
+ const application = applicationService.getApplication();
return (props: DataSourceMenuProps) => {
const { hideLocalCluster } = dataSourcePluginSetup;
if (props.setMenuMountPoint) {
@@ -25,13 +27,19 @@ export function createDataSourceMenu(
{...props}
uiSettings={uiSettings}
hideLocalCluster={hideLocalCluster}
+ application={application}
/>
);
}
return (
-
+
);
};
}
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 fdc5d2c7508b..d0db133108bc 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
@@ -19,8 +19,7 @@ import {
import { DataSourceSelectable } from '../data_source_selectable';
export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null {
- const { componentType, componentConfig, uiSettings, hideLocalCluster } = props;
-
+ const { componentType, componentConfig, uiSettings, hideLocalCluster, application } = props;
function renderDataSourceView(config: DataSourceViewConfig): ReactElement | null {
const { activeOption, fullWidth, savedObjects, notifications } = config;
return (
@@ -70,6 +69,7 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement |
hideLocalCluster={hideLocalCluster || false}
fullWidth={fullWidth}
uiSettings={uiSettings}
+ application={application}
/>
);
}
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 17aa35d8b8d0..446824d14084 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
@@ -8,6 +8,7 @@ import {
SavedObjectsClientContract,
SavedObject,
IUiSettingsClient,
+ ApplicationStart,
} from '../../../../../core/public';
import { DataSourceAttributes } from '../../types';
@@ -31,6 +32,7 @@ export interface DataSourceMenuProps {
componentConfig: T;
hideLocalCluster?: boolean;
uiSettings?: IUiSettingsClient;
+ application?: ApplicationStart;
setMenuMountPoint?: (menuMount: MountPoint | undefined) => void;
}
diff --git a/src/plugins/data_source_management/public/components/data_source_selectable/__snapshots__/data_source_selectable.test.tsx.snap b/src/plugins/data_source_management/public/components/data_source_selectable/__snapshots__/data_source_selectable.test.tsx.snap
index 851d37b3d71b..bdd3ad57aa3e 100644
--- a/src/plugins/data_source_management/public/components/data_source_selectable/__snapshots__/data_source_selectable.test.tsx.snap
+++ b/src/plugins/data_source_management/public/components/data_source_selectable/__snapshots__/data_source_selectable.test.tsx.snap
@@ -24,6 +24,7 @@ exports[`DataSourceSelectable should filter options if configured 1`] = `
display="inlineBlock"
hasArrow={true}
id="dataSourceSelectableContextMenuPopover"
+ initialFocus=".euiSelectableSearch"
isOpen={false}
ownFocus={true}
panelPaddingSize="none"
@@ -41,6 +42,12 @@ exports[`DataSourceSelectable should filter options if configured 1`] = `
}
}
>
+
+
@@ -109,6 +116,7 @@ exports[`DataSourceSelectable should render normally with local cluster is hidde
display="inlineBlock"
hasArrow={true}
id="dataSourceSelectableContextMenuPopover"
+ initialFocus=".euiSelectableSearch"
isOpen={false}
ownFocus={true}
panelPaddingSize="none"
@@ -126,6 +134,12 @@ exports[`DataSourceSelectable should render normally with local cluster is hidde
}
}
>
+
+
@@ -173,6 +187,7 @@ exports[`DataSourceSelectable should render normally with local cluster not hidd
display="inlineBlock"
hasArrow={true}
id="dataSourceSelectableContextMenuPopover"
+ initialFocus=".euiSelectableSearch"
isOpen={false}
ownFocus={true}
panelPaddingSize="none"
@@ -190,6 +205,12 @@ exports[`DataSourceSelectable should render normally with local cluster not hidd
}
}
>
+
+
@@ -286,6 +307,34 @@ Object {
class="euiPanel euiPanel--paddingSmall euiPanel--borderRadiusMedium euiPanel--transparent euiPanel--noShadow"
style="width: 300px;"
>
+
+
+ DATA SOURCE(
+ 3
+ )
+
+
+
+
+
+
+
diff --git a/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.test.tsx b/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.test.tsx
index 78b63a57144c..26c441d0e4bf 100644
--- a/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.test.tsx
+++ b/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.test.tsx
@@ -431,4 +431,50 @@ describe('DataSourceSelectable', () => {
const optionsProp = component.find(EuiSelectable).prop('options');
expect(optionsProp).toEqual([]);
});
+
+ it('should render group lablel normally after onChange', async () => {
+ const onSelectedDataSource = jest.fn();
+ component = shallow(
+
+ );
+ const componentInstance = component.instance();
+
+ componentInstance.componentDidMount!();
+ await nextTick();
+ const optionsPropBefore = component.find(EuiSelectable).prop('options');
+ expect(optionsPropBefore).toEqual([
+ opensearchClusterGroupLabel,
+ {
+ id: 'test1',
+ label: 'test1',
+ checked: 'on',
+ },
+ {
+ id: 'test2',
+ label: 'test2',
+ },
+ {
+ id: 'test3',
+ label: 'test3',
+ },
+ ]);
+ componentInstance.onChange([
+ opensearchClusterGroupLabel,
+ { id: 'test2', label: 'test2', checked: 'on' },
+ ]);
+ await nextTick();
+ const optionsPropAfter = component.find(EuiSelectable).prop('options');
+ expect(optionsPropAfter).toEqual([
+ opensearchClusterGroupLabel,
+ { id: 'test2', label: 'test2', checked: 'on' },
+ ]);
+ });
});
diff --git a/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.tsx b/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.tsx
index 40a7edce7558..71e9ee22f375 100644
--- a/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.tsx
+++ b/src/plugins/data_source_management/public/components/data_source_selectable/data_source_selectable.tsx
@@ -15,8 +15,10 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiBadge,
+ EuiHorizontalRule,
} from '@elastic/eui';
import {
+ ApplicationStart,
IUiSettingsClient,
SavedObjectsClientContract,
ToastsStart,
@@ -26,6 +28,7 @@ import { LocalCluster } from '../data_source_selector/data_source_selector';
import { SavedObject } from '../../../../../core/public';
import { DataSourceAttributes } from '../../types';
import { DataSourceGroupLabelOption, DataSourceOption } from '../data_source_menu/types';
+import { DataSourceDropDownHeader } from '../drop_down_header';
interface DataSourceSelectableProps {
savedObjectsClient: SavedObjectsClientContract;
@@ -34,6 +37,7 @@ interface DataSourceSelectableProps {
disabled: boolean;
hideLocalCluster: boolean;
fullWidth: boolean;
+ application?: ApplicationStart;
selectedOption?: DataSourceOption[];
dataSourceFilter?: (dataSource: SavedObject) => boolean;
uiSettings?: IUiSettingsClient;
@@ -198,6 +202,7 @@ export class DataSourceSelectable extends React.Component<
onChange(options: SelectedDataSourceOption[]) {
if (!this._isMounted) return;
+ options = options.filter((option) => !option.hasOwnProperty('isGroupLabel'));
const selectedDataSource = options.find(({ checked }) => checked);
this.setState({ dataSourceOptions: options });
@@ -247,6 +252,7 @@ export class DataSourceSelectable extends React.Component<
return (