mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Context menu trigger for URL Drilldown (#81158)
* feat: 🎸 add context menu trigger to URL drilldown * fix: 🐛 translate "Drilldowns" grouping title * feat: 🎸 add dynamic action grouping to dynamic actions * fix: 🐛 add translations to trigger texts * feat: 🎸 enambe ctx menu trigger in both flyouts, move to end * fix: 🐛 show context menu event scope variable sfor ctx menu * test: 💍 add tests * fix: 🐛 use correct namespace for translation keys * docs: ✏️ update autogenerated docs Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
21615c16ef
commit
aaadbe88c5
17 changed files with 187 additions and 60 deletions
|
@ -0,0 +1,11 @@
|
|||
<!-- Do not edit this file. It is automatically generated by API Documenter. -->
|
||||
|
||||
[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [isContextMenuTriggerContext](./kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md)
|
||||
|
||||
## isContextMenuTriggerContext variable
|
||||
|
||||
<b>Signature:</b>
|
||||
|
||||
```typescript
|
||||
isContextMenuTriggerContext: (context: unknown) => context is EmbeddableContext
|
||||
```
|
|
@ -77,6 +77,7 @@
|
|||
| [contextMenuTrigger](./kibana-plugin-plugins-embeddable-public.contextmenutrigger.md) | |
|
||||
| [defaultEmbeddableFactoryProvider](./kibana-plugin-plugins-embeddable-public.defaultembeddablefactoryprovider.md) | |
|
||||
| [EmbeddableRenderer](./kibana-plugin-plugins-embeddable-public.embeddablerenderer.md) | Helper react component to render an embeddable Can be used if you have an embeddable object or an embeddable factory Supports updating input by passing <code>input</code> prop |
|
||||
| [isContextMenuTriggerContext](./kibana-plugin-plugins-embeddable-public.iscontextmenutriggercontext.md) | |
|
||||
| [isRangeSelectTriggerContext](./kibana-plugin-plugins-embeddable-public.israngeselecttriggercontext.md) | |
|
||||
| [isValueClickTriggerContext](./kibana-plugin-plugins-embeddable-public.isvalueclicktriggercontext.md) | |
|
||||
| [PANEL\_BADGE\_TRIGGER](./kibana-plugin-plugins-embeddable-public.panel_badge_trigger.md) | |
|
||||
|
|
|
@ -70,6 +70,7 @@ export {
|
|||
isSavedObjectEmbeddableInput,
|
||||
isRangeSelectTriggerContext,
|
||||
isValueClickTriggerContext,
|
||||
isContextMenuTriggerContext,
|
||||
EmbeddableStateTransfer,
|
||||
EmbeddableEditorState,
|
||||
EmbeddablePackageState,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { Datatable } from '../../../../expressions';
|
||||
import { Trigger } from '../../../../ui_actions/public';
|
||||
import { IEmbeddable } from '..';
|
||||
|
@ -53,6 +54,39 @@ export type ChartActionContext<T extends IEmbeddable = IEmbeddable> =
|
|||
| ValueClickContext<T>
|
||||
| RangeSelectContext<T>;
|
||||
|
||||
export const CONTEXT_MENU_TRIGGER = 'CONTEXT_MENU_TRIGGER';
|
||||
export const contextMenuTrigger: Trigger<'CONTEXT_MENU_TRIGGER'> = {
|
||||
id: CONTEXT_MENU_TRIGGER,
|
||||
title: i18n.translate('embeddableApi.contextMenuTrigger.title', {
|
||||
defaultMessage: 'Context menu',
|
||||
}),
|
||||
description: i18n.translate('embeddableApi.contextMenuTrigger.description', {
|
||||
defaultMessage: 'A panel top-right corner context menu click.',
|
||||
}),
|
||||
};
|
||||
|
||||
export const PANEL_BADGE_TRIGGER = 'PANEL_BADGE_TRIGGER';
|
||||
export const panelBadgeTrigger: Trigger<'PANEL_BADGE_TRIGGER'> = {
|
||||
id: PANEL_BADGE_TRIGGER,
|
||||
title: i18n.translate('embeddableApi.panelBadgeTrigger.title', {
|
||||
defaultMessage: 'Panel badges',
|
||||
}),
|
||||
description: i18n.translate('embeddableApi.panelBadgeTrigger.description', {
|
||||
defaultMessage: 'Actions appear in title bar when an embeddable loads in a panel.',
|
||||
}),
|
||||
};
|
||||
|
||||
export const PANEL_NOTIFICATION_TRIGGER = 'PANEL_NOTIFICATION_TRIGGER';
|
||||
export const panelNotificationTrigger: Trigger<'PANEL_NOTIFICATION_TRIGGER'> = {
|
||||
id: PANEL_NOTIFICATION_TRIGGER,
|
||||
title: i18n.translate('embeddableApi.panelNotificationTrigger.title', {
|
||||
defaultMessage: 'Panel notifications',
|
||||
}),
|
||||
description: i18n.translate('embeddableApi.panelNotificationTrigger.description', {
|
||||
defaultMessage: 'Actions appear in top-right corner of a panel.',
|
||||
}),
|
||||
};
|
||||
|
||||
export const isValueClickTriggerContext = (
|
||||
context: ChartActionContext
|
||||
): context is ValueClickContext => context.data && 'data' in context.data;
|
||||
|
@ -61,23 +95,8 @@ export const isRangeSelectTriggerContext = (
|
|||
context: ChartActionContext
|
||||
): context is RangeSelectContext => context.data && 'range' in context.data;
|
||||
|
||||
export const CONTEXT_MENU_TRIGGER = 'CONTEXT_MENU_TRIGGER';
|
||||
export const contextMenuTrigger: Trigger<'CONTEXT_MENU_TRIGGER'> = {
|
||||
id: CONTEXT_MENU_TRIGGER,
|
||||
title: 'Context menu',
|
||||
description: 'Triggered on top-right corner context-menu select.',
|
||||
};
|
||||
|
||||
export const PANEL_BADGE_TRIGGER = 'PANEL_BADGE_TRIGGER';
|
||||
export const panelBadgeTrigger: Trigger<'PANEL_BADGE_TRIGGER'> = {
|
||||
id: PANEL_BADGE_TRIGGER,
|
||||
title: 'Panel badges',
|
||||
description: 'Actions appear in title bar when an embeddable loads in a panel.',
|
||||
};
|
||||
|
||||
export const PANEL_NOTIFICATION_TRIGGER = 'PANEL_NOTIFICATION_TRIGGER';
|
||||
export const panelNotificationTrigger: Trigger<'PANEL_NOTIFICATION_TRIGGER'> = {
|
||||
id: PANEL_NOTIFICATION_TRIGGER,
|
||||
title: 'Panel notifications',
|
||||
description: 'Actions appear in top-right corner of a panel.',
|
||||
};
|
||||
export const isContextMenuTriggerContext = (context: unknown): context is EmbeddableContext =>
|
||||
!!context &&
|
||||
typeof context === 'object' &&
|
||||
!!(context as EmbeddableContext).embeddable &&
|
||||
typeof (context as EmbeddableContext).embeddable === 'object';
|
||||
|
|
|
@ -695,6 +695,11 @@ export interface IEmbeddable<I extends EmbeddableInput = EmbeddableInput, O exte
|
|||
updateInput(changes: Partial<I>): void;
|
||||
}
|
||||
|
||||
// Warning: (ae-missing-release-tag) "isContextMenuTriggerContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
export const isContextMenuTriggerContext: (context: unknown) => context is EmbeddableContext;
|
||||
|
||||
// Warning: (ae-missing-release-tag) "isErrorEmbeddable" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal)
|
||||
//
|
||||
// @public (undocumented)
|
||||
|
@ -884,7 +889,7 @@ export const withEmbeddableSubscription: <I extends EmbeddableInput, O extends E
|
|||
// src/plugins/embeddable/common/types.ts:59:3 - (ae-forgotten-export) The symbol "TimeRange" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/embeddable/common/types.ts:64:3 - (ae-forgotten-export) The symbol "Query" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/embeddable/common/types.ts:69:3 - (ae-forgotten-export) The symbol "Filter" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/embeddable/public/lib/triggers/triggers.ts:45:5 - (ae-forgotten-export) The symbol "Datatable" needs to be exported by the entry point index.d.ts
|
||||
// src/plugins/embeddable/public/lib/triggers/triggers.ts:46:5 - (ae-forgotten-export) The symbol "Datatable" needs to be exported by the entry point index.d.ts
|
||||
|
||||
// (No @packageDocumentation comment for this package)
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@ import {
|
|||
} from '../../../../../../../src/plugins/ui_actions/public';
|
||||
|
||||
/**
|
||||
* We know that VALUE_CLICK_TRIGGER and SELECT_RANGE_TRIGGER are also triggering APPLY_FILTER_TRIGGER
|
||||
* This function appends APPLY_FILTER_TRIGGER to list of triggers if VALUE_CLICK_TRIGGER or SELECT_RANGE_TRIGGER
|
||||
* We know that VALUE_CLICK_TRIGGER and SELECT_RANGE_TRIGGER are also triggering APPLY_FILTER_TRIGGER.
|
||||
* This function appends APPLY_FILTER_TRIGGER to the list of triggers if either VALUE_CLICK_TRIGGER
|
||||
* or SELECT_RANGE_TRIGGER was executed.
|
||||
*
|
||||
* TODO: this probably should be part of uiActions infrastructure,
|
||||
* but dynamic implementation of nested trigger doesn't allow to statically express such relations
|
||||
|
|
|
@ -129,7 +129,7 @@ describe('isCompatible', () => {
|
|||
});
|
||||
});
|
||||
|
||||
test('not compatible if no triggers intersection', async () => {
|
||||
test('not compatible if no triggers intersect', async () => {
|
||||
await assertNonCompatibility({
|
||||
actionFactoriesTriggers: [],
|
||||
});
|
||||
|
|
|
@ -10,9 +10,12 @@ import { ActionByType } from '../../../../../../../../src/plugins/ui_actions/pub
|
|||
import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public';
|
||||
import {
|
||||
isEnhancedEmbeddable,
|
||||
embeddableEnhancedContextMenuDrilldownGrouping,
|
||||
embeddableEnhancedDrilldownGrouping,
|
||||
} from '../../../../../../embeddable_enhanced/public';
|
||||
import { EmbeddableContext } from '../../../../../../../../src/plugins/embeddable/public';
|
||||
import {
|
||||
CONTEXT_MENU_TRIGGER,
|
||||
EmbeddableContext,
|
||||
} from '../../../../../../../../src/plugins/embeddable/public';
|
||||
import { StartDependencies } from '../../../../plugin';
|
||||
import { StartServicesGetter } from '../../../../../../../../src/plugins/kibana_utils/public';
|
||||
import { ensureNestedTriggers } from '../drilldown_shared';
|
||||
|
@ -27,7 +30,7 @@ export class FlyoutCreateDrilldownAction implements ActionByType<typeof OPEN_FLY
|
|||
public readonly type = OPEN_FLYOUT_ADD_DRILLDOWN;
|
||||
public readonly id = OPEN_FLYOUT_ADD_DRILLDOWN;
|
||||
public order = 12;
|
||||
public grouping = embeddableEnhancedContextMenuDrilldownGrouping;
|
||||
public grouping = embeddableEnhancedDrilldownGrouping;
|
||||
|
||||
constructor(protected readonly params: OpenFlyoutAddDrilldownParams) {}
|
||||
|
||||
|
@ -83,7 +86,7 @@ export class FlyoutCreateDrilldownAction implements ActionByType<typeof OPEN_FLY
|
|||
onClose={() => handle.close()}
|
||||
viewMode={'create'}
|
||||
dynamicActionManager={embeddable.enhancements.dynamicActions}
|
||||
triggers={ensureNestedTriggers(embeddable.supportedTriggers())}
|
||||
triggers={[...ensureNestedTriggers(embeddable.supportedTriggers()), CONTEXT_MENU_TRIGGER]}
|
||||
placeContext={{ embeddable }}
|
||||
/>
|
||||
),
|
||||
|
|
|
@ -10,12 +10,16 @@ import {
|
|||
reactToUiComponent,
|
||||
toMountPoint,
|
||||
} from '../../../../../../../../src/plugins/kibana_react/public';
|
||||
import { EmbeddableContext, ViewMode } from '../../../../../../../../src/plugins/embeddable/public';
|
||||
import {
|
||||
EmbeddableContext,
|
||||
ViewMode,
|
||||
CONTEXT_MENU_TRIGGER,
|
||||
} from '../../../../../../../../src/plugins/embeddable/public';
|
||||
import { txtDisplayName } from './i18n';
|
||||
import { MenuItem } from './menu_item';
|
||||
import {
|
||||
isEnhancedEmbeddable,
|
||||
embeddableEnhancedContextMenuDrilldownGrouping,
|
||||
embeddableEnhancedDrilldownGrouping,
|
||||
} from '../../../../../../embeddable_enhanced/public';
|
||||
import { StartDependencies } from '../../../../plugin';
|
||||
import { StartServicesGetter } from '../../../../../../../../src/plugins/kibana_utils/public';
|
||||
|
@ -31,7 +35,7 @@ export class FlyoutEditDrilldownAction implements ActionByType<typeof OPEN_FLYOU
|
|||
public readonly type = OPEN_FLYOUT_EDIT_DRILLDOWN;
|
||||
public readonly id = OPEN_FLYOUT_EDIT_DRILLDOWN;
|
||||
public order = 10;
|
||||
public grouping = embeddableEnhancedContextMenuDrilldownGrouping;
|
||||
public grouping = embeddableEnhancedDrilldownGrouping;
|
||||
|
||||
constructor(protected readonly params: FlyoutEditDrilldownParams) {}
|
||||
|
||||
|
@ -67,7 +71,7 @@ export class FlyoutEditDrilldownAction implements ActionByType<typeof OPEN_FLYOU
|
|||
onClose={() => handle.close()}
|
||||
viewMode={'manage'}
|
||||
dynamicActionManager={embeddable.enhancements.dynamicActions}
|
||||
triggers={ensureNestedTriggers(embeddable.supportedTriggers())}
|
||||
triggers={[...ensureNestedTriggers(embeddable.supportedTriggers()), CONTEXT_MENU_TRIGGER]}
|
||||
placeContext={{ embeddable }}
|
||||
/>
|
||||
),
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
|
||||
import React from 'react';
|
||||
import { reactToUiComponent } from '../../../../../../src/plugins/kibana_react/public';
|
||||
import { ChartActionContext, IEmbeddable } from '../../../../../../src/plugins/embeddable/public';
|
||||
import {
|
||||
ChartActionContext,
|
||||
CONTEXT_MENU_TRIGGER,
|
||||
IEmbeddable,
|
||||
} from '../../../../../../src/plugins/embeddable/public';
|
||||
import { CollectConfigProps as CollectConfigPropsBase } from '../../../../../../src/plugins/kibana_utils/public';
|
||||
import {
|
||||
SELECT_RANGE_TRIGGER,
|
||||
|
@ -34,7 +38,10 @@ interface UrlDrilldownDeps {
|
|||
|
||||
export type ActionContext = ChartActionContext;
|
||||
export type Config = UrlDrilldownConfig;
|
||||
export type UrlTrigger = typeof VALUE_CLICK_TRIGGER | typeof SELECT_RANGE_TRIGGER;
|
||||
export type UrlTrigger =
|
||||
| typeof CONTEXT_MENU_TRIGGER
|
||||
| typeof VALUE_CLICK_TRIGGER
|
||||
| typeof SELECT_RANGE_TRIGGER;
|
||||
export interface ActionFactoryContext extends BaseActionFactoryContext<UrlTrigger> {
|
||||
embeddable?: IEmbeddable;
|
||||
}
|
||||
|
@ -58,7 +65,7 @@ export class UrlDrilldown implements Drilldown<Config, UrlTrigger, ActionFactory
|
|||
public readonly euiIcon = 'link';
|
||||
|
||||
supportedTriggers(): UrlTrigger[] {
|
||||
return [VALUE_CLICK_TRIGGER, SELECT_RANGE_TRIGGER];
|
||||
return [VALUE_CLICK_TRIGGER, SELECT_RANGE_TRIGGER, CONTEXT_MENU_TRIGGER];
|
||||
}
|
||||
|
||||
private readonly ReactCollectConfig: React.FC<CollectConfigProps> = ({
|
||||
|
|
|
@ -87,25 +87,25 @@ describe('VALUE_CLICK_TRIGGER', () => {
|
|||
]) as ValueClickTriggerEventScope;
|
||||
expect(mockEventScope.points.length).toBeGreaterThan(3);
|
||||
expect(mockEventScope.points).toMatchInlineSnapshot(`
|
||||
Array [
|
||||
Object {
|
||||
"key": "event.points.0.key",
|
||||
"value": "event.points.0.value",
|
||||
},
|
||||
Object {
|
||||
"key": "event.points.1.key",
|
||||
"value": "event.points.1.value",
|
||||
},
|
||||
Object {
|
||||
"key": "event.points.2.key",
|
||||
"value": "event.points.2.value",
|
||||
},
|
||||
Object {
|
||||
"key": "event.points.3.key",
|
||||
"value": "event.points.3.value",
|
||||
},
|
||||
]
|
||||
`);
|
||||
Array [
|
||||
Object {
|
||||
"key": "event.points.0.key",
|
||||
"value": "event.points.0.value",
|
||||
},
|
||||
Object {
|
||||
"key": "event.points.1.key",
|
||||
"value": "event.points.1.value",
|
||||
},
|
||||
Object {
|
||||
"key": "event.points.2.key",
|
||||
"value": "event.points.2.value",
|
||||
},
|
||||
Object {
|
||||
"key": "event.points.3.key",
|
||||
"value": "event.points.3.value",
|
||||
},
|
||||
]
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -130,3 +130,12 @@ describe('VALUE_CLICK_TRIGGER', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('CONTEXT_MENU_TRIGGER', () => {
|
||||
test('getMockEventScope() results in empty scope', () => {
|
||||
const mockEventScope = getMockEventScope([
|
||||
'CONTEXT_MENU_TRIGGER',
|
||||
]) as ValueClickTriggerEventScope;
|
||||
expect(mockEventScope).toEqual({});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -14,11 +14,15 @@ import {
|
|||
IEmbeddable,
|
||||
isRangeSelectTriggerContext,
|
||||
isValueClickTriggerContext,
|
||||
isContextMenuTriggerContext,
|
||||
RangeSelectContext,
|
||||
ValueClickContext,
|
||||
} from '../../../../../../src/plugins/embeddable/public';
|
||||
import type { ActionContext, ActionFactoryContext, UrlTrigger } from './url_drilldown';
|
||||
import { SELECT_RANGE_TRIGGER } from '../../../../../../src/plugins/ui_actions/public';
|
||||
import {
|
||||
SELECT_RANGE_TRIGGER,
|
||||
VALUE_CLICK_TRIGGER,
|
||||
} from '../../../../../../src/plugins/ui_actions/public';
|
||||
|
||||
type ContextScopeInput = ActionContext | ActionFactoryContext;
|
||||
|
||||
|
@ -101,7 +105,10 @@ export function getContextScope(contextScopeInput: ContextScopeInput): UrlDrilld
|
|||
* URL drilldown event scope,
|
||||
* available as {{event.$}}
|
||||
*/
|
||||
export type UrlDrilldownEventScope = ValueClickTriggerEventScope | RangeSelectTriggerEventScope;
|
||||
export type UrlDrilldownEventScope =
|
||||
| ValueClickTriggerEventScope
|
||||
| RangeSelectTriggerEventScope
|
||||
| ContextMenuTriggerEventScope;
|
||||
export type EventScopeInput = ActionContext;
|
||||
export interface ValueClickTriggerEventScope {
|
||||
key?: string;
|
||||
|
@ -115,11 +122,15 @@ export interface RangeSelectTriggerEventScope {
|
|||
to?: string | number;
|
||||
}
|
||||
|
||||
export type ContextMenuTriggerEventScope = object;
|
||||
|
||||
export function getEventScope(eventScopeInput: EventScopeInput): UrlDrilldownEventScope {
|
||||
if (isRangeSelectTriggerContext(eventScopeInput)) {
|
||||
return getEventScopeFromRangeSelectTriggerContext(eventScopeInput);
|
||||
} else if (isValueClickTriggerContext(eventScopeInput)) {
|
||||
return getEventScopeFromValueClickTriggerContext(eventScopeInput);
|
||||
} else if (isContextMenuTriggerContext(eventScopeInput)) {
|
||||
return {};
|
||||
} else {
|
||||
throw new Error("UrlDrilldown [getEventScope] can't build scope from not supported trigger");
|
||||
}
|
||||
|
@ -169,7 +180,9 @@ export function getMockEventScope([trigger]: UrlTrigger[]): UrlDrilldownEventSco
|
|||
from: new Date(Date.now() - 15 * 60 * 1000).toISOString(), // 15 minutes ago
|
||||
to: new Date().toISOString(),
|
||||
};
|
||||
} else {
|
||||
}
|
||||
|
||||
if (trigger === VALUE_CLICK_TRIGGER) {
|
||||
// number of mock points to generate
|
||||
// should be larger or equal of any possible data points length emitted by VALUE_CLICK_TRIGGER
|
||||
const nPoints = 4;
|
||||
|
@ -184,6 +197,8 @@ export function getMockEventScope([trigger]: UrlTrigger[]): UrlDrilldownEventSco
|
|||
points,
|
||||
};
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
type Primitive = string | number | boolean | null;
|
||||
|
|
|
@ -4,15 +4,19 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { IEmbeddable } from '../../../../../src/plugins/embeddable/public';
|
||||
import { UiActionsPresentableGrouping as PresentableGrouping } from '../../../../../src/plugins/ui_actions/public';
|
||||
|
||||
export const contextMenuDrilldownGrouping: PresentableGrouping<{
|
||||
export const drilldownGrouping: PresentableGrouping<{
|
||||
embeddable?: IEmbeddable;
|
||||
}> = [
|
||||
{
|
||||
id: 'drilldowns',
|
||||
getDisplayName: () => 'Drilldowns',
|
||||
getDisplayName: () =>
|
||||
i18n.translate('xpack.embeddableEnhanced.Drilldowns', {
|
||||
defaultMessage: 'Drilldowns',
|
||||
}),
|
||||
getIconType: () => 'symlink',
|
||||
order: 25,
|
||||
},
|
||||
|
|
|
@ -20,4 +20,4 @@ export function plugin(context: PluginInitializerContext) {
|
|||
|
||||
export { EnhancedEmbeddable, EnhancedEmbeddableContext } from './types';
|
||||
export { isEnhancedEmbeddable } from './embeddables';
|
||||
export { contextMenuDrilldownGrouping as embeddableEnhancedContextMenuDrilldownGrouping } from './actions';
|
||||
export { drilldownGrouping as embeddableEnhancedDrilldownGrouping } from './actions';
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { IEmbeddable } from '../../../../../src/plugins/embeddable/public';
|
||||
import { UiActionsPresentableGrouping as PresentableGrouping } from '../../../../../src/plugins/ui_actions/public';
|
||||
|
||||
export const dynamicActionGrouping: PresentableGrouping<{
|
||||
embeddable?: IEmbeddable;
|
||||
}> = [
|
||||
{
|
||||
id: 'dynamicActions',
|
||||
getDisplayName: () =>
|
||||
i18n.translate('xpack.uiActionsEnhanced.CustomActions', {
|
||||
defaultMessage: 'Custom actions',
|
||||
}),
|
||||
getIconType: () => 'symlink',
|
||||
order: 26,
|
||||
},
|
||||
];
|
|
@ -13,6 +13,7 @@ import { UiActionsServiceEnhancements } from '../services';
|
|||
import { ActionFactoryDefinition } from './action_factory_definition';
|
||||
import { SerializedAction, SerializedEvent } from './types';
|
||||
import { licensingMock } from '../../../licensing/public/mocks';
|
||||
import { dynamicActionGrouping } from './dynamic_action_grouping';
|
||||
|
||||
const actionFactoryDefinition1: ActionFactoryDefinition = {
|
||||
id: 'ACTION_FACTORY_1',
|
||||
|
@ -294,6 +295,27 @@ describe('DynamicActionManager', () => {
|
|||
expect(manager.state.get().events.length).toBe(1);
|
||||
});
|
||||
|
||||
test('adds revived actiosn to "dynamic action" grouping', async () => {
|
||||
const { manager, uiActions, actions } = setup([]);
|
||||
const action: SerializedAction = {
|
||||
factoryId: actionFactoryDefinition1.id,
|
||||
name: 'foo',
|
||||
config: {},
|
||||
};
|
||||
|
||||
uiActions.registerActionFactory(actionFactoryDefinition1);
|
||||
|
||||
await manager.start();
|
||||
|
||||
expect(manager.state.get().events.length).toBe(0);
|
||||
|
||||
await manager.createEvent(action, ['VALUE_CLICK_TRIGGER']);
|
||||
|
||||
const createdAction = actions.values().next().value;
|
||||
|
||||
expect(createdAction.grouping).toBe(dynamicActionGrouping);
|
||||
});
|
||||
|
||||
test('optimistically adds event to UI state', async () => {
|
||||
const { manager, uiActions } = setup([]);
|
||||
const action: SerializedAction = {
|
||||
|
|
|
@ -18,6 +18,7 @@ import {
|
|||
} from '../../../../../src/plugins/kibana_utils/common';
|
||||
import { StartContract } from '../plugin';
|
||||
import { SerializedAction, SerializedEvent } from './types';
|
||||
import { dynamicActionGrouping } from './dynamic_action_grouping';
|
||||
|
||||
const compareEvents = (
|
||||
a: ReadonlyArray<{ eventId: string }>,
|
||||
|
@ -93,6 +94,7 @@ export class DynamicActionManager {
|
|||
uiActions.registerAction({
|
||||
...actionDefinition,
|
||||
id: actionId,
|
||||
grouping: dynamicActionGrouping,
|
||||
isCompatible: async (context) => {
|
||||
if (!(await isCompatible(context))) return false;
|
||||
if (!actionDefinition.isCompatible) return true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue