mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Drilldowns] improve action.getHref() for drilldowns (#63228)
getHref on Action interfaces in uiActions plugin is now async. getHref is now used only to support right click behaviour. execute() takes control on regular click.
This commit is contained in:
parent
88d3523925
commit
3b64a65ed6
8 changed files with 46 additions and 25 deletions
|
@ -56,7 +56,7 @@ test('getHref returns the edit urls', async () => {
|
|||
if (action.getHref) {
|
||||
const embeddable = new EditableEmbeddable({ id: '123', viewMode: ViewMode.EDIT }, true);
|
||||
expect(
|
||||
action.getHref({
|
||||
await action.getHref({
|
||||
embeddable,
|
||||
})
|
||||
).toBe(embeddable.getOutput().editUrl);
|
||||
|
|
|
@ -62,11 +62,16 @@ export class EditPanelAction implements Action<ActionContext> {
|
|||
return Boolean(canEditEmbeddable && inDashboardEditMode);
|
||||
}
|
||||
|
||||
public async execute() {
|
||||
return;
|
||||
public async execute(context: ActionContext) {
|
||||
const href = await this.getHref(context);
|
||||
if (href) {
|
||||
// TODO: when apps start using browser router instead of hash router this has to be fixed
|
||||
// https://github.com/elastic/kibana/issues/58217
|
||||
window.location.href = href;
|
||||
}
|
||||
}
|
||||
|
||||
public getHref({ embeddable }: ActionContext): string {
|
||||
public async getHref({ embeddable }: ActionContext): Promise<string> {
|
||||
const editUrl = embeddable ? embeddable.getOutput().editUrl : undefined;
|
||||
return editUrl ? editUrl : '';
|
||||
}
|
||||
|
|
|
@ -63,9 +63,11 @@ export interface Action<Context = {}, T = ActionType> {
|
|||
isCompatible(context: Context): Promise<boolean>;
|
||||
|
||||
/**
|
||||
* If this returns something truthy, this is used in addition to the `execute` method when clicked.
|
||||
* If this returns something truthy, this will be used as [href] attribute on a link if possible (e.g. in context menu item)
|
||||
* to support right click -> open in a new tab behavior.
|
||||
* For regular click navigation is prevented and `execute()` takes control.
|
||||
*/
|
||||
getHref?(context: Context): string | undefined;
|
||||
getHref?(context: Context): Promise<string | undefined>;
|
||||
|
||||
/**
|
||||
* Executes the action.
|
||||
|
|
|
@ -63,7 +63,7 @@ export interface ActionDefinition<T extends ActionType> {
|
|||
/**
|
||||
* If this returns something truthy, this is used in addition to the `execute` method when clicked.
|
||||
*/
|
||||
getHref?(context: ActionContextMapping[T]): string | undefined;
|
||||
getHref?(context: ActionContextMapping[T]): Promise<string | undefined>;
|
||||
|
||||
/**
|
||||
* Executes the action.
|
||||
|
|
|
@ -28,7 +28,6 @@ export function createAction<T extends ActionType>(action: ActionDefinition<T>):
|
|||
id: action.type,
|
||||
isCompatible: () => Promise.resolve(true),
|
||||
getDisplayName: () => '',
|
||||
getHref: () => undefined,
|
||||
...action,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ async function buildEuiContextMenuPanelItems<A>({
|
|||
}
|
||||
|
||||
items.push(
|
||||
convertPanelActionToContextMenuItem({
|
||||
await convertPanelActionToContextMenuItem({
|
||||
action,
|
||||
actionContext,
|
||||
closeMenu,
|
||||
|
@ -88,9 +88,9 @@ async function buildEuiContextMenuPanelItems<A>({
|
|||
*
|
||||
* @param {ContextMenuAction} action
|
||||
* @param {Embeddable} embeddable
|
||||
* @return {EuiContextMenuPanelItemDescriptor}
|
||||
* @return {Promise<EuiContextMenuPanelItemDescriptor>}
|
||||
*/
|
||||
function convertPanelActionToContextMenuItem<A>({
|
||||
async function convertPanelActionToContextMenuItem<A>({
|
||||
action,
|
||||
actionContext,
|
||||
closeMenu,
|
||||
|
@ -98,7 +98,7 @@ function convertPanelActionToContextMenuItem<A>({
|
|||
action: Action<A>;
|
||||
actionContext: A;
|
||||
closeMenu: () => void;
|
||||
}): EuiContextMenuPanelItemDescriptor {
|
||||
}): Promise<EuiContextMenuPanelItemDescriptor> {
|
||||
const menuPanelItem: EuiContextMenuPanelItemDescriptor = {
|
||||
name: action.MenuItem
|
||||
? React.createElement(uiToReactComponent(action.MenuItem), {
|
||||
|
@ -110,13 +110,33 @@ function convertPanelActionToContextMenuItem<A>({
|
|||
'data-test-subj': `embeddablePanelAction-${action.id}`,
|
||||
};
|
||||
|
||||
menuPanelItem.onClick = () => {
|
||||
action.execute(actionContext);
|
||||
menuPanelItem.onClick = event => {
|
||||
if (event.currentTarget instanceof HTMLAnchorElement) {
|
||||
// from react-router's <Link/>
|
||||
if (
|
||||
!event.defaultPrevented && // onClick prevented default
|
||||
event.button === 0 && // ignore everything but left clicks
|
||||
(!event.currentTarget.target || event.currentTarget.target === '_self') && // let browser handle "target=_blank" etc.
|
||||
!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) // ignore clicks with modifier keys
|
||||
) {
|
||||
event.preventDefault();
|
||||
action.execute(actionContext);
|
||||
} else {
|
||||
// let browser handle navigation
|
||||
}
|
||||
} else {
|
||||
// not a link
|
||||
action.execute(actionContext);
|
||||
}
|
||||
|
||||
closeMenu();
|
||||
};
|
||||
|
||||
if (action.getHref && action.getHref(actionContext)) {
|
||||
menuPanelItem.href = action.getHref(actionContext);
|
||||
if (action.getHref) {
|
||||
const href = await action.getHref(actionContext);
|
||||
if (href) {
|
||||
menuPanelItem.href = href;
|
||||
}
|
||||
}
|
||||
|
||||
return menuPanelItem;
|
||||
|
|
|
@ -55,13 +55,6 @@ export class TriggerInternal<T extends TriggerId> {
|
|||
action: Action<TriggerContextMapping[T]>,
|
||||
context: TriggerContextMapping[T]
|
||||
) {
|
||||
const href = action.getHref && action.getHref(context);
|
||||
|
||||
if (href) {
|
||||
window.location.href = href;
|
||||
return;
|
||||
}
|
||||
|
||||
await action.execute(context);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@ export const createSamplePanelLink = (): Action =>
|
|||
createAction<typeof SAMPLE_PANEL_LINK>({
|
||||
type: SAMPLE_PANEL_LINK,
|
||||
getDisplayName: () => 'Sample panel Link',
|
||||
execute: async () => {},
|
||||
getHref: () => 'https://example.com/kibana/test',
|
||||
execute: async () => {
|
||||
window.location.href = 'https://example.com/kibana/test';
|
||||
},
|
||||
getHref: async () => 'https://example.com/kibana/test',
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue