Add href option in addition to onClick (#25233) (#25640)

* Add href option in addition to onClick

* Small modificationd and adding tests

* Add missing import

* Switch order of tests

* Don't close panel menu again
This commit is contained in:
Stacey Gammon 2018-11-14 11:50:30 -05:00 committed by GitHub
parent 171e1bcef2
commit 030d90cea8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 103 additions and 20 deletions

View file

@ -40,9 +40,9 @@ export function getEditPanelAction() {
isDisabled: ({ embeddable }) =>
!embeddable || !embeddable.metadata || !embeddable.metadata.editUrl,
isVisible: ({ containerState }) => containerState.viewMode === DashboardViewMode.EDIT,
onClick: ({ embeddable }) => {
getHref: ({ embeddable }) => {
if (embeddable && embeddable.metadata.editUrl) {
window.location.href = embeddable.metadata.editUrl;
return embeddable.metadata.editUrl;
}
},
}

View file

@ -140,12 +140,25 @@ function convertPanelActionToContextMenuItem({
containerState: ContainerState;
embeddable?: Embeddable;
}): EuiContextMenuPanelItemDescriptor {
return {
const menuPanelItem: EuiContextMenuPanelItemDescriptor = {
name: action.displayName,
icon: action.icon,
panel: _.get(action, 'childContextMenuPanel.id'),
onClick: () => action.onClick({ embeddable, containerState }),
disabled: action.isDisabled({ embeddable, containerState }),
'data-test-subj': `dashboardPanelAction-${action.id}`,
};
if (action.onClick) {
menuPanelItem.onClick = () => {
if (action.onClick) {
action.onClick({ embeddable, containerState });
}
};
}
if (action.getHref) {
menuPanelItem.href = action.getHref({ embeddable, containerState });
}
return menuPanelItem;
}

View file

@ -21,12 +21,6 @@ import { ContextMenuPanel } from './context_menu_panel';
import { PanelActionAPI } from './types';
interface ContextMenuActionOptions {
/**
* An optional action to take when the action is clicked on. Either this or childContextMenuPanel should be
* given.
*/
onClick?: (actionAPI: PanelActionAPI) => void;
/**
* An optional child context menu to display when the action is clicked.
*/
@ -57,6 +51,21 @@ interface ContextMenuActionOptions {
icon?: EuiContextMenuItemIcon;
}
interface ContextMenuButtonOptions extends ContextMenuActionOptions {
/**
* An optional action to take when the action is clicked on. Either this or childContextMenuPanel should be
* given.
*/
onClick?: (actionAPI: PanelActionAPI) => void;
}
interface ContextMenuLinkOptions extends ContextMenuActionOptions {
/**
* An optional href to use as navigation when the action is clicked on.
*/
getHref?: (actionAPI: PanelActionAPI) => string;
}
interface ContextMenuActionsConfig {
id: string;
@ -94,6 +103,16 @@ export class ContextMenuAction {
*/
public readonly parentPanelId: string;
/**
* @param {PanelActionAPI} panelActionAPI
*/
public readonly onClick?: (panelActionAPI: PanelActionAPI) => void;
/**
* @param {PanelActionAPI} panelActionAPI
*/
public readonly getHref?: (panelActionAPI: PanelActionAPI) => string;
/**
*
* @param {string} config.id
@ -103,9 +122,13 @@ export class ContextMenuAction {
* @param {ContextMenuPanel} options.childContextMenuPanel - optional child panel to open when clicked.
* @param {function} options.isDisabled - optionally set a custom disabled function
* @param {function} options.isVisible - optionally set a custom isVisible function
* @param {function} options.getHref
* @param {Element} options.icon
*/
public constructor(config: ContextMenuActionsConfig, options: ContextMenuActionOptions = {}) {
public constructor(
config: ContextMenuActionsConfig,
options: ContextMenuButtonOptions | ContextMenuLinkOptions = {}
) {
this.id = config.id;
this.displayName = config.displayName;
this.parentPanelId = config.parentPanelId;
@ -113,7 +136,7 @@ export class ContextMenuAction {
this.icon = options.icon;
this.childContextMenuPanel = options.childContextMenuPanel;
if (options.onClick) {
if ('onClick' in options) {
this.onClick = options.onClick;
}
@ -124,13 +147,10 @@ export class ContextMenuAction {
if (options.isVisible) {
this.isVisible = options.isVisible;
}
}
/**
* @param {PanelActionAPI} panelActionAPI
*/
public onClick(panelActionAPI: PanelActionAPI): void {
return;
if ('getHref' in options) {
this.getHref = options.getHref;
}
}
/**

View file

@ -20,7 +20,10 @@
function samplePanelAction(kibana) {
return new kibana.Plugin({
uiExports: {
contextMenuActions: ['plugins/sample_panel_action/sample_panel_action'],
contextMenuActions: [
'plugins/sample_panel_action/sample_panel_action',
'plugins/sample_panel_action/sample_panel_link',
],
},
});
}

View file

@ -0,0 +1,37 @@
/*
* 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 {
ContextMenuAction,
ContextMenuActionsRegistryProvider,
} from 'ui/embeddable';
class SamplePanelLink extends ContextMenuAction {
constructor() {
super({
displayName: 'Sample Panel Link',
id: 'samplePanelLink',
parentPanelId: 'mainMenu',
});
}
getHref() {
return 'https://example.com/kibana/test';
}
}
ContextMenuActionsRegistryProvider.register(() => new SamplePanelLink());

View file

@ -17,6 +17,8 @@
* under the License.
*/
import expect from 'expect.js';
export default function ({ getService, getPageObjects }) {
const dashboardPanelActions = getService('dashboardPanelActions');
const testSubjects = getService('testSubjects');
@ -27,8 +29,16 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.dashboard.loadSavedDashboard('few panels');
});
it('Sample action appears in context menu in view mode', async () => {
it('allows to register links into the context menu', async () => {
await dashboardPanelActions.openContextMenu();
const actionElement = await testSubjects.find('dashboardPanelAction-samplePanelLink');
const actionElementTag = await actionElement.getTagName();
expect(actionElementTag).to.be('a');
const actionElementLink = await actionElement.getProperty('href');
expect(actionElementLink).to.be('https://example.com/kibana/test');
});
it('Sample action appears in context menu in view mode', async () => {
await testSubjects.existOrFail(
'dashboardPanelAction-samplePanelAction'
);