Skip to content

Commit

Permalink
[Multiple Datasource] Expose filterfn in datasource menu component to…
Browse files Browse the repository at this point in the history
… allow filter data sources before rendering in navigation bar (#6113)

* expose filterfn in datasource menu component

Signed-off-by: Lu Yu <nluyu@amazon.com>

* add changelog

Signed-off-by: Lu Yu <nluyu@amazon.com>

---------

Signed-off-by: Lu Yu <nluyu@amazon.com>
  • Loading branch information
BionIT committed Mar 12, 2024
1 parent 4b89ad0 commit 45096bb
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- [Multiple Datasource] Test connection schema validation for registered auth types ([#6109](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6109))
- [Workspace] Consume workspace id in saved object client ([#6014](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6014))
- [Multiple Datasource] Export DataSourcePluginRequestContext at top level for plugins to use ([#6108](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6108))
- [Multiple Datasource] Expose filterfn in datasource menu component to allow filter data sources before rendering in navigation bar ([#6113](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6113))
- [Workspace] Add delete saved objects by workspace functionality([#6013](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6013))
- [Workspace] Add a workspace client in workspace plugin ([#6094](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6094))

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ describe('create data source menu', () => {
const component = render(<TestComponent {...props} />);
expect(component).toMatchSnapshot();
expect(client.find).toBeCalledWith({
fields: ['id', 'description', 'title'],
fields: ['id', 'title', 'auth.type'],
perPage: 10000,
type: 'data-source',
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface DataSourceMenuProps {
className?: string;
selectedOption?: DataSourceOption[];
setMenuMountPoint?: (menuMount: MountPoint | undefined) => void;
filterFn?: (dataSource: any) => boolean;
}

export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null {
Expand All @@ -40,6 +41,7 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null
fullWidth,
hideLocalCluster,
selectedOption,
filterFn,
} = props;

if (!showDataSourceSelectable) {
Expand All @@ -66,6 +68,7 @@ export function DataSourceMenu(props: DataSourceMenuProps): ReactElement | null
onSelectedDataSource={dataSourceCallBackFunc}
disabled={disableDataSourceSelectable || false}
selectedOption={selectedOption && selectedOption.length > 0 ? selectedOption : undefined}
filterFn={filterFn}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,21 @@ import { SavedObjectsClientContract } from '../../../../../core/public';
import { notificationServiceMock } from '../../../../../core/public/mocks';
import React from 'react';
import { DataSourceSelectable } from './data_source_selectable';
import { AuthType } from '../../types';
import { getDataSourcesWithFieldsResponse, mockResponseForSavedObjectsCalls } from '../../mocks';

describe('DataSourceSelectable', () => {
let component: ShallowWrapper<any, Readonly<{}>, React.Component<{}, {}, any>>;

let client: SavedObjectsClientContract;
const { toasts } = notificationServiceMock.createStartContract();
const nextTick = () => new Promise((res) => process.nextTick(res));

beforeEach(() => {
client = {
find: jest.fn().mockResolvedValue([]),
} as any;
mockResponseForSavedObjectsCalls(client, 'find', getDataSourcesWithFieldsResponse);
});

it('should render normally with local cluster not hidden', () => {
Expand All @@ -34,7 +38,7 @@ describe('DataSourceSelectable', () => {
);
expect(component).toMatchSnapshot();
expect(client.find).toBeCalledWith({
fields: ['id', 'description', 'title'],
fields: ['id', 'title', 'auth.type'],
perPage: 10000,
type: 'data-source',
});
Expand All @@ -54,10 +58,28 @@ describe('DataSourceSelectable', () => {
);
expect(component).toMatchSnapshot();
expect(client.find).toBeCalledWith({
fields: ['id', 'description', 'title'],
fields: ['id', 'title', 'auth.type'],
perPage: 10000,
type: 'data-source',
});
expect(toasts.addWarning).toBeCalledTimes(0);
});

it('should filter options if configured', async () => {
component = shallow(
<DataSourceSelectable
savedObjectsClient={client}
notifications={toasts}
onSelectedDataSource={jest.fn()}
disabled={false}
hideLocalCluster={false}
fullWidth={false}
filterFn={(ds) => ds.attributes.auth.type !== AuthType.NoAuth}
/>
);
component.instance().componentDidMount!();
await nextTick();
expect(component).toMatchSnapshot();
expect(toasts.addWarning).toBeCalledTimes(0);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
EuiSpacer,
} from '@elastic/eui';
import { SavedObjectsClientContract, ToastsStart } from 'opensearch-dashboards/public';
import { getDataSources } from '../utils';
import { getDataSourcesWithFields } from '../utils';
import { DataSourceOption, LocalCluster } from '../data_source_selector/data_source_selector';

interface DataSourceSelectableProps {
Expand All @@ -26,6 +26,7 @@ interface DataSourceSelectableProps {
hideLocalCluster: boolean;
fullWidth: boolean;
selectedOption?: DataSourceOption[];
filterFn?: (dataSource: any) => boolean;
}

interface DataSourceSelectableState {
Expand Down Expand Up @@ -69,18 +70,24 @@ export class DataSourceSelectable extends React.Component<

async componentDidMount() {
this._isMounted = true;
getDataSources(this.props.savedObjectsClient)
getDataSourcesWithFields(this.props.savedObjectsClient, ['id', 'title', 'auth.type'])
.then((fetchedDataSources) => {
if (fetchedDataSources?.length) {
let dataSourceOptions = fetchedDataSources.map((dataSource) => ({
id: dataSource.id,
label: dataSource.title,
}));
let filteredDataSources = [];
if (this.props.filterFn) {
filteredDataSources = fetchedDataSources.filter((ds) => this.props.filterFn!(ds));
}

dataSourceOptions = dataSourceOptions.sort((a, b) =>
a.label.toLowerCase().localeCompare(b.label.toLowerCase())
);
if (filteredDataSources.length === 0) {
filteredDataSources = fetchedDataSources;
}

const dataSourceOptions = filteredDataSources
.map((dataSource) => ({
id: dataSource.id,
label: dataSource.attributes?.title || '',
}))
.sort((a, b) => a.label.toLowerCase().localeCompare(b.label.toLowerCase()));
if (!this.props.hideLocalCluster) {
dataSourceOptions.unshift(LocalCluster);
}
Expand Down

0 comments on commit 45096bb

Please sign in to comment.