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

Add registrable DiscoverActions to discover page #7793

Closed
2 changes: 2 additions & 0 deletions changelogs/fragments/7793.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
feat:
- Add registrable DiscoverActions to discover page ([#7793](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/7793))
1 change: 1 addition & 0 deletions src/plugins/data_explorer/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ export {
setIndexPattern,
setDataSet,
} from './utils/state_management';
export { DiscoverAction, DiscoverActionContext } from './types';
10 changes: 8 additions & 2 deletions src/plugins/data_explorer/public/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
DataExplorerPluginStart,
DataExplorerPluginStartDependencies,
DataExplorerServices,
DiscoverAction,
} from './types';
import { PLUGIN_ID, PLUGIN_NAME } from '../common';
import { ViewService } from './services/view_service';
Expand All @@ -43,11 +44,12 @@ export class DataExplorerPlugin
private appStateUpdater = new BehaviorSubject<AppUpdater>(() => ({}));
private stopUrlTracking?: () => void;
private currentHistory?: ScopedHistory;
private discoverActions: DiscoverAction[] = [];

public setup(
core: CoreSetup<DataExplorerPluginStartDependencies, DataExplorerPluginStart>,
{ data }: DataExplorerPluginSetupDependencies
): DataExplorerPluginSetup {
) {
gaobinlong marked this conversation as resolved.
Show resolved Hide resolved
const viewService = this.viewService;

const { appMounted, appUnMounted, stop: stopUrlTracker } = createOsdUrlTracker({
Expand Down Expand Up @@ -105,6 +107,7 @@ export class DataExplorerPlugin
...withNotifyOnErrors(coreStart.notifications.toasts),
}),
viewRegistry: viewService.start(),
discoverActions: this.discoverActions,
gaobinlong marked this conversation as resolved.
Show resolved Hide resolved
};

// Get start services as specified in opensearch_dashboards.json
Expand All @@ -124,7 +127,10 @@ export class DataExplorerPlugin
});

return {
...this.viewService.setup(),
registerView: this.viewService.setup().registerView,
registerDiscoverAction: (discoverAction: DiscoverAction) => {
this.discoverActions.push(discoverAction);
},
};
}

Expand Down
14 changes: 13 additions & 1 deletion src/plugins/data_explorer/public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EmbeddableStart } from '../../embeddable/public';
import { ExpressionsStart } from '../../expressions/public';
import { ViewServiceStart, ViewServiceSetup } from './services/view_service';
import { IOsdUrlStateStorage } from '../../opensearch_dashboards_utils/public';
import { DataPublicPluginSetup, DataPublicPluginStart } from '../../data/public';
import { DataPublicPluginSetup, DataPublicPluginStart, IndexPattern } from '../../data/public';
import { Store } from './utils/state_management';

export type DataExplorerPluginSetup = ViewServiceSetup;
Expand All @@ -34,4 +34,16 @@ export interface DataExplorerServices extends CoreStart {
data: DataPublicPluginStart;
scopedHistory: ScopedHistory;
osdUrlStateStorage: IOsdUrlStateStorage;
discoverActions?: DiscoverAction[];
}

export interface DiscoverActionContext {
indexPattern: IndexPattern | undefined;
}

export interface DiscoverAction {
order: number;
name: string;
iconType: string;
onClick: (context: DiscoverActionContext) => void;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { DiscoverActions } from './discover_actions';
import {
DiscoverAction,
DiscoverActionContext,
} from '../../../../../../plugins/data_explorer/public';

jest.mock('@elastic/eui', () => ({
EuiButtonEmpty: jest.requireActual('@elastic/eui').EuiButtonEmpty,
}));

const mockActions: DiscoverAction[] = [
{ order: 2, iconType: 'icon1', name: 'Action 2', onClick: jest.fn() },
{ order: 1, iconType: 'icon2', name: 'Action 1', onClick: jest.fn() },
{ order: 3, iconType: 'icon3', name: 'Action 3', onClick: jest.fn() },
];

const mockContext: DiscoverActionContext = {
indexPattern: undefined,
};

describe('DiscoverActions Component', () => {
it('renders all actions in the correct order', () => {
render(<DiscoverActions actions={mockActions} context={mockContext} />);

const buttons = screen.getAllByRole('button');
expect(buttons[0]).toHaveTextContent('Action 1');
expect(buttons[1]).toHaveTextContent('Action 2');
expect(buttons[2]).toHaveTextContent('Action 3');
});

it('calls the action onClick function with the correct context', () => {
render(<DiscoverActions actions={mockActions} context={mockContext} />);

const buttons = screen.getAllByRole('button');
fireEvent.click(buttons[0]);
expect(mockActions[0].onClick).toHaveBeenCalledWith(mockContext);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { EuiButtonEmpty } from '@elastic/eui';
import {
DiscoverAction,
DiscoverActionContext,
} from '../../../../../../plugins/data_explorer/public';

interface DiscoverActionsProps {
actions: DiscoverAction[];
context: DiscoverActionContext;
}

const DiscoverActions: React.FC<DiscoverActionsProps> = ({ actions, context }) => {
actions.sort((a, b) => {
return a.order - b.order;
});

return (
<div className="dscCanvas_actions">
{actions.map((action) => (
<EuiButtonEmpty
key={action.order}
size="s"
iconType={action.iconType}
onClick={() => {
action.onClick(context);
}}
>
{action.name}
</EuiButtonEmpty>
))}
</div>
);
};

export { DiscoverActions };
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@
position: relative;
}

&_actions {
position: absolute;
top: 0;
right: 30px;
gaobinlong marked this conversation as resolved.
Show resolved Hide resolved
}

&_options {
position: absolute;
top: 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import {
EuiCompressedSwitch,
} from '@elastic/eui';
import { TopNav } from './top_nav';
import { ViewProps } from '../../../../../data_explorer/public';
import {
DataExplorerServices,
DiscoverAction,
ViewProps,
} from '../../../../../data_explorer/public';
import { DiscoverTable } from './discover_table';
import { DiscoverChartContainer } from './discover_chart_container';
import { useDiscoverContext } from '../context';
Expand All @@ -35,6 +39,7 @@ import { buildColumns } from '../../utils/columns';
import './discover_canvas.scss';
import { getNewDiscoverSetting, setNewDiscoverSetting } from '../../components/utils/local_storage';
import { HeaderVariant } from '../../../../../../core/public';
import { DiscoverActions } from './discover_actions';

// eslint-disable-next-line import/no-default-export
export default function DiscoverCanvas({ setHeaderActionMenu, history, optionalRef }: ViewProps) {
Expand All @@ -47,6 +52,10 @@ export default function DiscoverCanvas({ setHeaderActionMenu, history, optionalR
chrome: { setHeaderVariant },
},
} = useOpenSearchDashboards<DiscoverViewServices>();
const {
services: { discoverActions },
} = useOpenSearchDashboards<DataExplorerServices>();

const { columns } = useSelector((state) => {
const stateColumns = state.discover.columns;

Expand Down Expand Up @@ -166,6 +175,10 @@ export default function DiscoverCanvas({ setHeaderActionMenu, history, optionalR
<EuiPanel hasShadow={false} paddingSize="none" className="dscCanvas_results">
<MemoizedDiscoverChartContainer {...fetchState} />
<MemoizedDiscoverTable rows={rows} scrollToTop={scrollToTop} />
<DiscoverActions
actions={discoverActions as DiscoverAction[]}
context={{ indexPattern }}
/>
</EuiPanel>
)}
</EuiPanel>
Expand Down
Loading