Skip to content

Commit

Permalink
add category option for context menus
Browse files Browse the repository at this point in the history
Signed-off-by: David Sinclair <[email protected]>
  • Loading branch information
sikhote committed May 26, 2023
1 parent ec4c1df commit 51722f6
Show file tree
Hide file tree
Showing 7 changed files with 552 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { PanelViewWithSharingLong } from './panel_view_with_sharing_long';
import { PanelEdit } from './panel_edit';
import { PanelEditWithDrilldowns } from './panel_edit_with_drilldowns';
import { PanelEditWithDrilldownsAndContextActions } from './panel_edit_with_drilldowns_and_context_actions';
import { PanelGroupOptionsAndContextActions } from './panel_group_options_and_context_actions';

export const ContextMenuExamples: React.FC = () => {
return (
Expand All @@ -44,6 +45,8 @@ export const ContextMenuExamples: React.FC = () => {
<p>
Below examples show how context menu panels look with varying number of actions and how the
actions can be grouped into different panels using <EuiCode>grouping</EuiCode> field.
Grouping can only be one layer deep. A group needs to have at least two items for grouping
to work. A separator is automatically added between groups.
</p>

<EuiFlexGroup>
Expand All @@ -57,7 +60,6 @@ export const ContextMenuExamples: React.FC = () => {
<PanelViewWithSharingLong />
</EuiFlexItem>
</EuiFlexGroup>

<EuiFlexGroup>
<EuiFlexItem>
<PanelEdit />
Expand All @@ -69,6 +71,11 @@ export const ContextMenuExamples: React.FC = () => {
<PanelEditWithDrilldownsAndContextActions />
</EuiFlexItem>
</EuiFlexGroup>
<EuiFlexGroup>
<EuiFlexItem>
<PanelGroupOptionsAndContextActions />
</EuiFlexItem>
</EuiFlexGroup>
</EuiText>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Any modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import * as React from 'react';
import { EuiButton, EuiContextMenu, EuiPopover } from '@elastic/eui';
import useAsync from 'react-use/lib/useAsync';
import { buildContextMenuForActions, Action } from '../../../../src/plugins/ui_actions/public';
import { sampleAction } from './util';

export const PanelGroupOptionsAndContextActions: React.FC = () => {
const [open, setOpen] = React.useState(false);

const context = {};
const trigger: any = 'TEST_TRIGGER';
const drilldownGrouping: Action['grouping'] = [
{
id: 'drilldowns',
getDisplayName: () => 'Uncategorized group',
getIconType: () => 'popout',
order: 20,
},
];
const exampleGroup: Action['grouping'] = [
{
id: 'example',
getDisplayName: () => 'Example group',
getIconType: () => 'cloudStormy',
order: 20,
category: 'visAug',
},
];
const alertingGroup: Action['grouping'] = [
{
id: 'alerting',
getDisplayName: () => 'Alerting',
getIconType: () => 'cloudStormy',
order: 20,
category: 'visAug',
},
];
const anomaliesGroup: Action['grouping'] = [
{
id: 'anomalies',
getDisplayName: () => 'Anomalies',
getIconType: () => 'cloudStormy',
order: 30,
category: 'visAug',
},
];
const actions = [
sampleAction('test-1', 100, 'Edit visualization', 'pencil'),
sampleAction('test-2', 99, 'Clone panel', 'partial'),

sampleAction('test-9', 10, 'Create drilldown', 'plusInCircle', drilldownGrouping),
sampleAction('test-10', 9, 'Manage drilldowns', 'list', drilldownGrouping),

sampleAction('test-11', 10, 'Example action', 'dashboardApp', exampleGroup),
sampleAction('test-11', 10, 'Alertin action 1', 'dashboardApp', alertingGroup),
sampleAction('test-12', 9, 'Alertin action 2', 'dashboardApp', alertingGroup),
sampleAction('test-13', 8, 'Anomalies 1', 'cloudStormy', anomaliesGroup),
sampleAction('test-14', 7, 'Anomalies 2', 'link', anomaliesGroup),
];

const panels = useAsync(() =>
buildContextMenuForActions({
actions: actions.map((action) => ({ action, context, trigger })),
})
);

return (
<EuiPopover
button={<EuiButton onClick={() => setOpen((x) => !x)}>Grouping with categories</EuiButton>}
isOpen={open}
panelPaddingSize="none"
anchorPosition="downLeft"
closePopover={() => setOpen(false)}
>
<EuiContextMenu initialPanelId={'mainMenu'} panels={panels.value} />
</EuiPopover>
);
};
2 changes: 1 addition & 1 deletion src/plugins/ui_actions/public/actions/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export interface Action<Context extends BaseContext = {}, T = ActionType>
* Returns a title to be displayed to the user.
* @param context
*/
getDisplayName(context: ActionExecutionContext<Context>): string;
getDisplayName(context: ActionExecutionContext<Context>): JSX.Element | string;

/**
* `UiComponent` to render when displaying this action as a context menu item.
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/ui_actions/public/actions/action_internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export class ActionInternal<A extends ActionDefinition = ActionDefinition>
return this.definition.getIconType(context);
}

public getDisplayName(context: Context<A>): string {
public getDisplayName(context: Context<A>): JSX.Element | string {
if (!this.definition.getDisplayName) return `Action: ${this.id}`;
return this.definition.getDisplayName(context);
}
Expand Down
Loading

0 comments on commit 51722f6

Please sign in to comment.