diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index bd14d7cb205b3..0109b256fd942 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -44,7 +44,7 @@ pageLoadAssetSize: dataVisualizer: 32727 developerToolbar: 4467 devTools: 8109 - discover: 31186 + discover: 30501 discoverEnhanced: 5509 discoverShared: 2322 elasticAssistant: 301540 @@ -115,7 +115,7 @@ pageLoadAssetSize: maps: 45917 mapsEms: 6734 metricsDataAccess: 44950 - ml: 89000 + ml: 102091 mockIdpPlugin: 7463 monitoring: 28983 navigation: 11814 @@ -184,7 +184,7 @@ pageLoadAssetSize: timelines: 131503 transform: 16515 triggersActionsUi: 123512 - uiActions: 35278 + uiActions: 35180 unifiedDocViewer: 15000 unifiedSearch: 19500 upgradeAssistant: 6898 diff --git a/src/platform/plugins/shared/discover/public/context_awareness/hooks/use_additional_cell_actions.test.tsx b/src/platform/plugins/shared/discover/public/context_awareness/hooks/use_additional_cell_actions.test.tsx index fd18f11876d05..0d5184f91e8a0 100644 --- a/src/platform/plugins/shared/discover/public/context_awareness/hooks/use_additional_cell_actions.test.tsx +++ b/src/platform/plugins/shared/discover/public/context_awareness/hooks/use_additional_cell_actions.test.tsx @@ -19,11 +19,7 @@ import { discoverServiceMock } from '../../__mocks__/services'; import React from 'react'; import { createEsqlDataSource } from '../../../common/data_sources'; import { dataViewWithTimefieldMock } from '../../__mocks__/data_view_with_timefield'; -import type { - Action, - ActionDefinition, - ActionExecutionContext, -} from '@kbn/ui-actions-plugin/public/actions'; +import type { ActionExecutionContext } from '@kbn/ui-actions-plugin/public/actions'; import { type AdditionalCellAction, type DiscoverCellActionExecutionContext } from '../types'; import { createContextAwarenessMocks } from '../__mocks__'; import { type ScopedProfilesManager } from '../profiles_manager'; @@ -38,12 +34,11 @@ let mockUuid = 0; jest.mock('uuid', () => ({ ...jest.requireActual('uuid'), v4: jest.fn() })); -const mockActions: Array> = []; +const mockActions: string[] = []; const mockTriggerActions: Record = { [DISCOVER_CELL_ACTIONS_TRIGGER_ID]: [] }; -jest.spyOn(discoverServiceMock.uiActions, 'registerAction').mockImplementation((action) => { - mockActions.push(action as ActionDefinition); - return action as Action; +jest.spyOn(discoverServiceMock.uiActions, 'registerActionAsync').mockImplementation((actionId) => { + mockActions.push(actionId); }); jest @@ -54,7 +49,7 @@ jest jest.spyOn(discoverServiceMock.uiActions, 'unregisterAction').mockImplementation((id) => { mockActions.splice( - mockActions.findIndex((action) => action.id === id), + mockActions.findIndex((actionId) => actionId === id), 1 ); }); diff --git a/src/platform/plugins/shared/discover/public/context_awareness/hooks/use_additional_cell_actions.ts b/src/platform/plugins/shared/discover/public/context_awareness/hooks/use_additional_cell_actions.ts index 60203c20050df..68981bea307ef 100644 --- a/src/platform/plugins/shared/discover/public/context_awareness/hooks/use_additional_cell_actions.ts +++ b/src/platform/plugins/shared/discover/public/context_awareness/hooks/use_additional_cell_actions.ts @@ -57,7 +57,7 @@ export const useAdditionalCellActions = ({ ); actions.forEach((action) => { - uiActions.registerAction(action); + uiActions.registerActionAsync(action.id, async () => action); uiActions.attachAction(DISCOVER_CELL_ACTIONS_TRIGGER_ID, action.id); }); diff --git a/src/platform/plugins/shared/ui_actions/public/mocks.ts b/src/platform/plugins/shared/ui_actions/public/mocks.ts index 5e695fb5f71f9..0937bfca56c49 100644 --- a/src/platform/plugins/shared/ui_actions/public/mocks.ts +++ b/src/platform/plugins/shared/ui_actions/public/mocks.ts @@ -18,11 +18,9 @@ export type Start = jest.Mocked; const createSetupContract = (): Setup => { const setupContract: Setup = { - addTriggerAction: jest.fn(), addTriggerActionAsync: jest.fn(), attachAction: jest.fn(), detachAction: jest.fn(), - registerAction: jest.fn(), registerActionAsync: jest.fn(), unregisterAction: jest.fn(), }; @@ -33,7 +31,6 @@ const createStartContract = (): Start => { const startContract: Start = { attachAction: jest.fn(), unregisterAction: jest.fn(), - addTriggerAction: jest.fn(), addTriggerActionAsync: jest.fn(), clear: jest.fn(), detachAction: jest.fn(), @@ -50,7 +47,6 @@ const createStartContract = (): Start => { async (triggerId: string, context: object) => [] as Array> ), - registerAction: jest.fn(), registerActionAsync: jest.fn(), }; diff --git a/src/platform/plugins/shared/ui_actions/public/plugin.ts b/src/platform/plugins/shared/ui_actions/public/plugin.ts index 051daf24f6ea3..5bd9074c4faea 100644 --- a/src/platform/plugins/shared/ui_actions/public/plugin.ts +++ b/src/platform/plugins/shared/ui_actions/public/plugin.ts @@ -14,11 +14,9 @@ import { setAnalytics, setI18n, setNotifications, setTheme, setUserProfile } fro export type UiActionsPublicSetup = Pick< UiActionsService, - | 'addTriggerAction' | 'addTriggerActionAsync' | 'attachAction' | 'detachAction' - | 'registerAction' | 'registerActionAsync' | 'unregisterAction' >; diff --git a/src/platform/plugins/shared/ui_actions/public/service/ui_actions_service.test.ts b/src/platform/plugins/shared/ui_actions/public/service/ui_actions_service.test.ts index 913a3cbcf9915..abb786cc3fe77 100644 --- a/src/platform/plugins/shared/ui_actions/public/service/ui_actions_service.test.ts +++ b/src/platform/plugins/shared/ui_actions/public/service/ui_actions_service.test.ts @@ -15,6 +15,7 @@ import type { ActionRegistry } from '../types'; import { coreMock } from '@kbn/core/public/mocks'; import { ON_OPEN_PANEL_MENU } from '../../common/trigger_ids'; import { triggers } from '../triggers'; +import { ACTION_HELLO_WORLD } from '../tests/test_samples/hello_world_action'; const testAction1: ActionDefinition = { id: 'action1', @@ -62,29 +63,14 @@ describe('UiActionsService', () => { describe('.registerAction()', () => { test('can register an action', () => { const service = new UiActionsService(); - service.registerAction({ + service.registerActionAsync('test', async () => ({ id: 'test', execute: async () => {}, getDisplayName: () => 'test', getIconType: () => '', isCompatible: async () => true, type: 'test', - }); - }); - - test('return action instance', () => { - const service = new UiActionsService(); - const action = service.registerAction({ - id: 'test', - execute: async () => {}, - getDisplayName: () => 'test', - getIconType: () => '', - isCompatible: async () => true, - type: 'test', - }); - - expect(action).toBeInstanceOf(ActionInternal); - expect(action.id).toBe('test'); + })); }); }); @@ -111,21 +97,21 @@ describe('UiActionsService', () => { test('returns actions set on trigger', async () => { const service = new UiActionsService(); - service.registerAction(action1); - service.registerAction(action2); + service.registerActionAsync('action1', async () => action1); + service.registerActionAsync('action2', async () => action2); const list0 = await service.getTriggerActions(ON_OPEN_PANEL_MENU); expect(list0).toHaveLength(0); - service.addTriggerAction(ON_OPEN_PANEL_MENU, action1); + service.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action1', async () => action1); const list1 = await service.getTriggerActions(ON_OPEN_PANEL_MENU); expect(list1).toHaveLength(1); expect(list1[0]).toBeInstanceOf(ActionInternal); expect(list1[0].id).toBe(action1.id); - service.addTriggerAction(ON_OPEN_PANEL_MENU, action2); + service.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action2', async () => action2); const list2 = await service.getTriggerActions(ON_OPEN_PANEL_MENU); expect(list2).toHaveLength(2); @@ -143,7 +129,7 @@ describe('UiActionsService', () => { const helloWorldAction = createHelloWorldAction(coreStart); const length = actions.size; - service.registerAction(helloWorldAction); + service.registerActionAsync(ACTION_HELLO_WORLD, async () => helloWorldAction); expect(actions.size - length).toBe(1); const action = await actions.get(helloWorldAction.id)?.(); @@ -154,9 +140,13 @@ describe('UiActionsService', () => { const service = new UiActionsService(); const helloWorldAction = createHelloWorldAction(coreStart); - service.registerAction(helloWorldAction); + service.registerActionAsync(ACTION_HELLO_WORLD, async () => helloWorldAction); - service.addTriggerAction(ON_OPEN_PANEL_MENU, helloWorldAction); + service.addTriggerActionAsync( + ON_OPEN_PANEL_MENU, + ACTION_HELLO_WORLD, + async () => helloWorldAction + ); const compatibleActions = await service.getTriggerCompatibleActions(ON_OPEN_PANEL_MENU, { hi: 'there', @@ -175,9 +165,9 @@ describe('UiActionsService', () => { execute: () => Promise.resolve(), }; - service.registerAction(action); + service.registerActionAsync('test', async () => action); - service.addTriggerAction(ON_OPEN_PANEL_MENU, action); + service.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test', async () => action); const compatibleActions1 = await service.getTriggerCompatibleActions(ON_OPEN_PANEL_MENU, { accept: true, @@ -221,8 +211,8 @@ describe('UiActionsService', () => { test('forked service preserves trigger-to-actions mapping', async () => { const service1 = new UiActionsService(); - service1.registerAction(testAction1); - service1.addTriggerAction(ON_OPEN_PANEL_MENU, testAction1); + service1.registerActionAsync('action1', async () => testAction1); + service1.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action1', async () => testAction1); const service2 = service1.fork(); @@ -238,16 +228,16 @@ describe('UiActionsService', () => { test('new attachments in fork do not appear in original service', async () => { const service1 = new UiActionsService(); - service1.registerAction(testAction1); - service1.registerAction(testAction2); - service1.addTriggerAction(ON_OPEN_PANEL_MENU, testAction1); + service1.registerActionAsync('action1', async () => testAction1); + service1.registerActionAsync('action2', async () => testAction2); + service1.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action1', async () => testAction1); const service2 = service1.fork(); expect(await service1.getTriggerActions(ON_OPEN_PANEL_MENU)).toHaveLength(1); expect(await service2.getTriggerActions(ON_OPEN_PANEL_MENU)).toHaveLength(1); - service2.addTriggerAction(ON_OPEN_PANEL_MENU, testAction2); + service2.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action2', async () => testAction2); expect(await service1.getTriggerActions(ON_OPEN_PANEL_MENU)).toHaveLength(1); expect(await service2.getTriggerActions(ON_OPEN_PANEL_MENU)).toHaveLength(2); @@ -256,16 +246,16 @@ describe('UiActionsService', () => { test('new attachments in original service do not appear in fork', async () => { const service1 = new UiActionsService(); - service1.registerAction(testAction1); - service1.registerAction(testAction2); - service1.addTriggerAction(ON_OPEN_PANEL_MENU, testAction1); + service1.registerActionAsync('action1', async () => testAction1); + service1.registerActionAsync('action2', async () => testAction2); + service1.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action1', async () => testAction1); const service2 = service1.fork(); expect(await service1.getTriggerActions(ON_OPEN_PANEL_MENU)).toHaveLength(1); expect(await service2.getTriggerActions(ON_OPEN_PANEL_MENU)).toHaveLength(1); - service1.addTriggerAction(ON_OPEN_PANEL_MENU, testAction2); + service1.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action2', async () => testAction2); expect(await service1.getTriggerActions(ON_OPEN_PANEL_MENU)).toHaveLength(2); expect(await service2.getTriggerActions(ON_OPEN_PANEL_MENU)).toHaveLength(1); @@ -273,16 +263,18 @@ describe('UiActionsService', () => { }); describe('registries', () => { - const ACTION_HELLO_WORLD = 'ACTION_HELLO_WORLD'; - test('can register action', async () => { const actions: ActionRegistry = new Map(); const service = new UiActionsService({ actions }); - service.registerAction({ - id: ACTION_HELLO_WORLD, - order: 13, - } as unknown as ActionDefinition); + service.registerActionAsync( + ACTION_HELLO_WORLD, + async () => + ({ + id: ACTION_HELLO_WORLD, + order: 13, + } as unknown as ActionDefinition) + ); expect(await actions.get(ACTION_HELLO_WORLD)?.()).toMatchObject({ id: ACTION_HELLO_WORLD, @@ -298,7 +290,7 @@ describe('UiActionsService', () => { order: 25, } as unknown as ActionDefinition; - service.addTriggerAction(ON_OPEN_PANEL_MENU, action); + service.addTriggerActionAsync(ON_OPEN_PANEL_MENU, ACTION_HELLO_WORLD, async () => action); const actions = await service.getTriggerActions(ON_OPEN_PANEL_MENU); @@ -314,8 +306,8 @@ describe('UiActionsService', () => { order: 25, } as unknown as ActionDefinition; - service.registerAction(action); - service.addTriggerAction(ON_OPEN_PANEL_MENU, action); + service.registerActionAsync(ACTION_HELLO_WORLD, async () => action); + service.addTriggerActionAsync(ON_OPEN_PANEL_MENU, ACTION_HELLO_WORLD, async () => action); service.detachAction(ON_OPEN_PANEL_MENU, action.id); const actions2 = await service.getTriggerActions(ON_OPEN_PANEL_MENU); @@ -330,7 +322,7 @@ describe('UiActionsService', () => { order: 25, } as unknown as ActionDefinition; - service.registerAction(action); + service.registerActionAsync(ACTION_HELLO_WORLD, async () => action); expect(() => service.detachAction('i do not exist', ACTION_HELLO_WORLD)).toThrowError( 'No trigger [triggerId = i do not exist] exists, for detaching action [actionId = ACTION_HELLO_WORLD].' ); @@ -344,8 +336,10 @@ describe('UiActionsService', () => { order: 25, } as unknown as ActionDefinition; - service.registerAction(action); - expect(() => service.addTriggerAction('i do not exist', action)).toThrowError( + service.registerActionAsync(ACTION_HELLO_WORLD, async () => action); + expect(() => + service.addTriggerActionAsync('i do not exist', ACTION_HELLO_WORLD, async () => action) + ).toThrowError( 'No trigger [triggerId = i do not exist] exists, for attaching action [actionId = ACTION_HELLO_WORLD].' ); }); @@ -358,10 +352,10 @@ describe('UiActionsService', () => { order: 25, } as unknown as ActionDefinition; - service.registerAction(action); - expect(() => service.registerAction(action)).toThrowError( - 'Action [action.id = ACTION_HELLO_WORLD] already registered.' - ); + service.registerActionAsync(ACTION_HELLO_WORLD, async () => action); + expect(() => + service.registerActionAsync(ACTION_HELLO_WORLD, async () => action) + ).toThrowError('Action [action.id = ACTION_HELLO_WORLD] already registered.'); }); }); }); diff --git a/src/platform/plugins/shared/ui_actions/public/service/ui_actions_service.ts b/src/platform/plugins/shared/ui_actions/public/service/ui_actions_service.ts index b4744416c6913..b28c344b67382 100644 --- a/src/platform/plugins/shared/ui_actions/public/service/ui_actions_service.ts +++ b/src/platform/plugins/shared/ui_actions/public/service/ui_actions_service.ts @@ -43,25 +43,6 @@ export class UiActionsService { return trigger; }; - /** - * @deprecated - * - * Use `plugins.uiActions.registerActionAsync` instead. - */ - public readonly registerAction = ( - definition: ActionDefinition - ): Action => { - if (this.actions.has(definition.id)) { - throw new Error(`Action [action.id = ${definition.id}] already registered.`); - } - - const action = new ActionInternal(definition); - - this.actions.set(action.id, async () => action as unknown as ActionInternal); - - return action; - }; - public readonly registerActionAsync = ( id: string, getDefinition: () => Promise> @@ -122,17 +103,7 @@ export class UiActionsService { }; /** - * @deprecated - * - * Use `plugins.uiActions.addTriggerActionAsync` instead. - */ - public readonly addTriggerAction = (triggerId: string, action: ActionDefinition): void => { - if (!this.actions.has(action.id)) this.registerAction(action); - this.attachAction(triggerId, action.id); - }; - - /** - * `addTriggerAction` is similar to `attachAction` as it attaches action to a + * `addTriggerActionAsync` is similar to `attachAction` as it attaches action to a * trigger, but it also registers the action, if it has not been registered, yet. */ public readonly addTriggerActionAsync = ( diff --git a/src/platform/plugins/shared/ui_actions/public/tests/execute_trigger_actions.test.ts b/src/platform/plugins/shared/ui_actions/public/tests/execute_trigger_actions.test.ts index 2b45100812594..f3ff119e463fb 100644 --- a/src/platform/plugins/shared/ui_actions/public/tests/execute_trigger_actions.test.ts +++ b/src/platform/plugins/shared/ui_actions/public/tests/execute_trigger_actions.test.ts @@ -46,7 +46,7 @@ test('executes a single action mapped to a trigger', async () => { const { setup, doStart } = uiActions; const action = createTestAction('test1', () => true); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test1', async () => action); const context = {}; const start = doStart(); @@ -74,7 +74,7 @@ test('does not execute an incompatible action', async () => { ({ name }: { name: string }) => name === 'executeme' ); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test1', async () => action); const start = doStart(); const context = { @@ -93,8 +93,8 @@ test('shows a context menu when more than one action is mapped to a trigger', as const action1 = createTestAction('test1', () => true); const action2 = createTestAction('test2', () => true); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action1); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action2); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test1', async () => action1); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test2', async () => action2); expect(openContextMenu).toHaveBeenCalledTimes(0); @@ -115,7 +115,7 @@ test('shows a context menu when there is only one action mapped to a trigger and const action1 = createTestAction('test1', () => true); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action1); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test1', async () => action1); expect(openContextMenu).toHaveBeenCalledTimes(0); @@ -139,7 +139,7 @@ test('passes whole action context to isCompatible()', async () => { return true; }); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test', async () => action); const start = doStart(); @@ -154,8 +154,8 @@ test("doesn't show a context menu for auto executable actions", async () => { const action1 = createTestAction('test1', () => true, true); const action2 = createTestAction('test2', () => true, false); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action1); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action2); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test1', async () => action1); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test2', async () => action2); expect(openContextMenu).toHaveBeenCalledTimes(0); @@ -176,7 +176,7 @@ test('passes trigger into execute', async () => { const action = createTestAction<{ foo: string }>('test', () => true); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'test', async () => action); const start = doStart(); diff --git a/src/platform/plugins/shared/ui_actions/public/tests/get_trigger_actions.test.ts b/src/platform/plugins/shared/ui_actions/public/tests/get_trigger_actions.test.ts index 8e4993ff51b92..bc5fb49bfceb7 100644 --- a/src/platform/plugins/shared/ui_actions/public/tests/get_trigger_actions.test.ts +++ b/src/platform/plugins/shared/ui_actions/public/tests/get_trigger_actions.test.ts @@ -28,22 +28,22 @@ const action2: ActionDefinition = { test('returns actions set on trigger', async () => { const { setup, doStart } = uiActionsPluginMock.createPlugin(); - setup.registerAction(action1); - setup.registerAction(action2); + setup.registerActionAsync('action1', async () => action1); + setup.registerActionAsync('action2', async () => action2); const start = doStart(); const list0 = await start.getTriggerActions(ON_OPEN_PANEL_MENU); expect(list0).toHaveLength(0); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action1); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action1', async () => action1); const list1 = await start.getTriggerActions(ON_OPEN_PANEL_MENU); expect(list1).toHaveLength(1); expect(list1[0]).toBeInstanceOf(ActionInternal); expect(list1[0].id).toBe(action1.id); - setup.addTriggerAction(ON_OPEN_PANEL_MENU, action2); + setup.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'action2', async () => action2); const list2 = await start.getTriggerActions(ON_OPEN_PANEL_MENU); expect(list2).toHaveLength(2); diff --git a/src/platform/plugins/shared/ui_actions/public/tests/get_trigger_compatible_actions.test.ts b/src/platform/plugins/shared/ui_actions/public/tests/get_trigger_compatible_actions.test.ts index c5722c831608b..097fbeb3cad61 100644 --- a/src/platform/plugins/shared/ui_actions/public/tests/get_trigger_compatible_actions.test.ts +++ b/src/platform/plugins/shared/ui_actions/public/tests/get_trigger_compatible_actions.test.ts @@ -17,6 +17,7 @@ import { ON_CLICK_ROW, ON_CLICK_VALUE, } from '../../common/trigger_ids'; +import { ACTION_HELLO_WORLD } from './test_samples/hello_world_action'; const coreStart = coreMock.createStart(); let action: ActionDefinition<{ name: string }>; @@ -29,25 +30,29 @@ beforeEach(() => { execute: () => Promise.resolve(), }; - uiActions.setup.registerAction(action as ActionDefinition); + uiActions.setup.registerActionAsync('test', async () => action as ActionDefinition); - uiActions.setup.addTriggerAction(ON_OPEN_PANEL_MENU, action as ActionDefinition); + uiActions.setup.addTriggerActionAsync( + ON_OPEN_PANEL_MENU, + 'test', + async () => action as ActionDefinition + ); }); test('can register action', async () => { const { setup } = uiActions; const helloWorldAction = createHelloWorldAction(coreStart); - setup.registerAction(helloWorldAction); + setup.registerActionAsync(ACTION_HELLO_WORLD, async () => helloWorldAction); }); test('getTriggerCompatibleActions returns attached actions', async () => { const { setup, doStart } = uiActions; const helloWorldAction = createHelloWorldAction(coreStart); - setup.registerAction(helloWorldAction); + setup.registerActionAsync(ACTION_HELLO_WORLD, async () => helloWorldAction); - setup.addTriggerAction(ON_CLICK_VALUE, helloWorldAction); + setup.addTriggerActionAsync(ON_CLICK_VALUE, ACTION_HELLO_WORLD, async () => helloWorldAction); const start = doStart(); const actions = await start.getTriggerCompatibleActions(ON_CLICK_VALUE, {}); @@ -67,8 +72,8 @@ test('filters out actions not applicable based on the context', async () => { execute: () => Promise.resolve(), }; - setup.registerAction(action1); - setup.addTriggerAction(ON_CLICK_ROW, action1); + setup.registerActionAsync('test1', async () => action1); + setup.addTriggerActionAsync(ON_CLICK_ROW, 'test1', async () => action1); const start = doStart(); let actions = await start.getTriggerCompatibleActions(ON_CLICK_ROW, { accept: true }); diff --git a/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/constants.ts b/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/constants.ts new file mode 100644 index 0000000000000..62403813014b7 --- /dev/null +++ b/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/constants.ts @@ -0,0 +1,11 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export const SAMPLE_PANEL_ACTION = 'samplePanelAction'; +export const SAMPLE_PANEL_LINK = 'samplePanelLink'; diff --git a/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/plugin.ts b/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/plugin.ts index 20b5c2992ee9b..7ba11f3e536b8 100644 --- a/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/plugin.ts +++ b/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/plugin.ts @@ -10,18 +10,20 @@ import type { CoreSetup, Plugin } from '@kbn/core/public'; import type { UiActionsSetup } from '@kbn/ui-actions-plugin/public'; import { ON_OPEN_PANEL_MENU } from '@kbn/ui-actions-plugin/common/trigger_ids'; -import { createSamplePanelAction } from './sample_panel_action'; -import { createSamplePanelLink } from './sample_panel_link'; +import { SAMPLE_PANEL_ACTION, SAMPLE_PANEL_LINK } from './constants'; export class SampelPanelActionTestPlugin implements Plugin { public setup(core: CoreSetup, { uiActions }: { uiActions: UiActionsSetup }) { - const samplePanelAction = createSamplePanelAction(core.getStartServices); - const samplePanelLink = createSamplePanelLink(); - - uiActions.addTriggerAction(ON_OPEN_PANEL_MENU, samplePanelAction); - uiActions.addTriggerAction(ON_OPEN_PANEL_MENU, samplePanelLink); + uiActions.addTriggerActionAsync(ON_OPEN_PANEL_MENU, SAMPLE_PANEL_ACTION, async () => { + const { createSamplePanelAction } = await import('./sample_panel_action'); + return createSamplePanelAction(core.getStartServices); + }); + uiActions.addTriggerActionAsync(ON_OPEN_PANEL_MENU, SAMPLE_PANEL_LINK, async () => { + const { createSamplePanelLink } = await import('./sample_panel_link'); + return createSamplePanelLink(); + }); return {}; } diff --git a/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_action.tsx b/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_action.tsx index 5c3843e657413..dbf252544f6d0 100644 --- a/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_action.tsx +++ b/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_action.tsx @@ -14,8 +14,7 @@ import React from 'react'; import type { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public'; import { createAction } from '@kbn/ui-actions-plugin/public'; import { toMountPoint } from '@kbn/react-kibana-mount'; - -export const SAMPLE_PANEL_ACTION = 'samplePanelAction'; +import { SAMPLE_PANEL_ACTION } from './constants'; export interface SamplePanelActionContext { embeddable: DefaultEmbeddableApi; diff --git a/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_link.ts b/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_link.ts index a334358bff3c2..10cb1dea79377 100644 --- a/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_link.ts +++ b/src/platform/test/plugin_functional/plugins/kbn_sample_panel_action/public/sample_panel_link.ts @@ -9,8 +9,7 @@ import type { Action } from '@kbn/ui-actions-plugin/public'; import { createAction } from '@kbn/ui-actions-plugin/public'; - -export const SAMPLE_PANEL_LINK = 'samplePanelLink'; +import { SAMPLE_PANEL_LINK } from './constants'; export const createSamplePanelLink = (): Action => createAction({ diff --git a/x-pack/platform/plugins/shared/ml/public/plugin.ts b/x-pack/platform/plugins/shared/ml/public/plugin.ts index 4646138247912..fb6000821ed0d 100644 --- a/x-pack/platform/plugins/shared/ml/public/plugin.ts +++ b/x-pack/platform/plugins/shared/ml/public/plugin.ts @@ -84,6 +84,7 @@ import { MlManagementLocatorInternal } from './locator/ml_management_locator'; import { TelemetryService } from './application/services/telemetry/telemetry_service'; import type { ITelemetryClient } from './application/services/telemetry/types'; import { registerEmbeddables } from './embeddables'; +import { registerMlUiActions } from './ui_actions'; export interface MlStartDependencies { cases?: CasesPublicStart; @@ -279,8 +280,13 @@ export class MlPlugin implements Plugin { registerEmbeddables(pluginsSetup.embeddable, core, pluginsSetup.usageCollection); } - const { registerMlUiActions, registerSearchLinks, registerCasesAttachments } = - await import('./register_helper'); + if (fullLicense && mlCapabilities.canGetMlInfo) { + registerMlUiActions(pluginsSetup.uiActions, core); + } + + const { registerSearchLinks, registerCasesAttachments } = await import( + './register_helper' + ); registerSearchLinks( this.appUpdater$, fullLicense, @@ -308,8 +314,6 @@ export class MlPlugin implements Plugin { } if (fullLicense && mlCapabilities.canGetMlInfo) { - registerMlUiActions(pluginsSetup.uiActions, core); - if (this.enabledFeatures.ad) { if (pluginsSetup.cases) { registerCasesAttachments( diff --git a/x-pack/platform/plugins/shared/ml/public/register_helper/index.ts b/x-pack/platform/plugins/shared/ml/public/register_helper/index.ts index 5ce31f4104513..b565814cb12e5 100644 --- a/x-pack/platform/plugins/shared/ml/public/register_helper/index.ts +++ b/x-pack/platform/plugins/shared/ml/public/register_helper/index.ts @@ -7,6 +7,5 @@ // These register helper functions have no async imports themselves, so they // can be bundled together for a single async chunk. -export { registerMlUiActions } from '../ui_actions'; export { registerSearchLinks } from './register_search_links'; export { registerCasesAttachments } from '../cases'; diff --git a/x-pack/platform/plugins/shared/ml/public/ui_actions/async_module.ts b/x-pack/platform/plugins/shared/ml/public/ui_actions/async_module.ts new file mode 100644 index 0000000000000..74788fe87ea0b --- /dev/null +++ b/x-pack/platform/plugins/shared/ml/public/ui_actions/async_module.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { createApplyEntityFieldFiltersAction } from './apply_entity_filters_action'; +export { createApplyInfluencerFiltersAction } from './apply_influencer_filters_action'; +export { createApplyTimeRangeSelectionAction } from './apply_time_range_action'; +export { createClearSelectionAction } from './clear_selection_action'; +export { createAddSwimlanePanelAction } from './create_swim_lane'; +export { createAddSingleMetricViewerPanelAction } from './create_single_metric_viewer'; +export { createCategorizationADJobAction } from './open_create_categorization_job_action'; +export { createOpenInExplorerAction } from './open_in_anomaly_explorer_action'; +export { createOpenInSingleMetricViewerAction } from './open_in_single_metric_viewer_action'; +export { createVisToADJobAction } from './open_vis_in_ml_action'; +export { createAddAnomalyChartsPanelAction } from './create_anomaly_chart'; diff --git a/x-pack/platform/plugins/shared/ml/public/ui_actions/index.ts b/x-pack/platform/plugins/shared/ml/public/ui_actions/index.ts index 8b175d03bc140..344e631638c1f 100644 --- a/x-pack/platform/plugins/shared/ml/public/ui_actions/index.ts +++ b/x-pack/platform/plugins/shared/ml/public/ui_actions/index.ts @@ -16,21 +16,6 @@ import { SWIM_LANE_SELECTION_TRIGGER, } from '@kbn/ui-actions-plugin/common/trigger_ids'; import type { MlPluginStart, MlStartDependencies } from '../plugin'; -import { createApplyEntityFieldFiltersAction } from './apply_entity_filters_action'; -import { createApplyInfluencerFiltersAction } from './apply_influencer_filters_action'; -import { createApplyTimeRangeSelectionAction } from './apply_time_range_action'; -import { createClearSelectionAction } from './clear_selection_action'; -import { createAddSwimlanePanelAction } from './create_swim_lane'; -import { createAddSingleMetricViewerPanelAction } from './create_single_metric_viewer'; -import { createCategorizationADJobAction } from './open_create_categorization_job_action'; -import { createOpenInExplorerAction } from './open_in_anomaly_explorer_action'; -import { createOpenInSingleMetricViewerAction } from './open_in_single_metric_viewer_action'; -import { createVisToADJobAction } from './open_vis_in_ml_action'; -import { createAddAnomalyChartsPanelAction } from './create_anomaly_chart'; -export { APPLY_INFLUENCER_FILTERS_ACTION } from './apply_influencer_filters_action'; -export { APPLY_TIME_RANGE_SELECTION_ACTION } from './apply_time_range_action'; -export { OPEN_IN_ANOMALY_EXPLORER_ACTION } from './open_in_anomaly_explorer_action'; -export { CREATE_LENS_VIS_TO_ML_AD_JOB_ACTION } from './open_vis_in_ml_action'; import { CONTROLLED_BY_SINGLE_METRIC_VIEWER_FILTER } from './constants'; /** * Register ML UI actions @@ -39,56 +24,98 @@ export function registerMlUiActions( uiActions: UiActionsSetup, core: CoreSetup ) { - // Initialize actions - const addSingleMetricViewerPanelAction = createAddSingleMetricViewerPanelAction( - core.getStartServices - ); - const addSwimlanePanelAction = createAddSwimlanePanelAction(core.getStartServices); - const openInExplorerAction = createOpenInExplorerAction(core.getStartServices); - const openInSingleMetricViewerAction = createOpenInSingleMetricViewerAction( - core.getStartServices - ); - const applyInfluencerFiltersAction = createApplyInfluencerFiltersAction(core.getStartServices); - const applyEntityFieldFilterAction = createApplyEntityFieldFiltersAction(core.getStartServices); - const smvApplyEntityFieldFilterAction = createApplyEntityFieldFiltersAction( - core.getStartServices, - CONTROLLED_BY_SINGLE_METRIC_VIEWER_FILTER - ); - const applyTimeRangeSelectionAction = createApplyTimeRangeSelectionAction(core.getStartServices); - const clearSelectionAction = createClearSelectionAction(core.getStartServices); - const visToAdJobAction = createVisToADJobAction(core.getStartServices); - const categorizationADJobAction = createCategorizationADJobAction(core.getStartServices); - - const addAnomalyChartsPanelAction = createAddAnomalyChartsPanelAction(core.getStartServices); - - // Register actions - uiActions.registerAction(applyEntityFieldFilterAction); - uiActions.registerAction(smvApplyEntityFieldFilterAction); - uiActions.registerAction(applyTimeRangeSelectionAction); - uiActions.registerAction(categorizationADJobAction); - uiActions.registerAction(addAnomalyChartsPanelAction); - // Assign triggers - uiActions.addTriggerAction(ADD_PANEL_TRIGGER, addSingleMetricViewerPanelAction); - uiActions.addTriggerAction(ADD_PANEL_TRIGGER, addSwimlanePanelAction); - uiActions.addTriggerAction(ADD_PANEL_TRIGGER, addAnomalyChartsPanelAction); + uiActions.addTriggerActionAsync(ADD_PANEL_TRIGGER, 'create-single-metric-viewer', async () => { + const { createAddSingleMetricViewerPanelAction } = await import('./async_module'); + return createAddSingleMetricViewerPanelAction(core.getStartServices); + }); + uiActions.addTriggerActionAsync(ADD_PANEL_TRIGGER, 'create-anomaly-swimlane', async () => { + const { createAddSwimlanePanelAction } = await import('./async_module'); + return createAddSwimlanePanelAction(core.getStartServices); + }); + uiActions.addTriggerActionAsync(ADD_PANEL_TRIGGER, 'create-anomaly-charts', async () => { + const { createAddAnomalyChartsPanelAction } = await import('./async_module'); + return createAddAnomalyChartsPanelAction(core.getStartServices); + }); - uiActions.addTriggerAction(ON_OPEN_PANEL_MENU, openInExplorerAction); - uiActions.attachAction(ON_OPEN_PANEL_MENU, openInSingleMetricViewerAction.id); + uiActions.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'open-in-anomaly-explorer', async () => { + const { createOpenInExplorerAction } = await import('./async_module'); + return createOpenInExplorerAction(core.getStartServices); + }); + uiActions.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'open-in-single-metric-viewer', async () => { + const { createOpenInSingleMetricViewerAction } = await import('./async_module'); + return createOpenInSingleMetricViewerAction(core.getStartServices); + }); - uiActions.addTriggerAction(SWIM_LANE_SELECTION_TRIGGER, applyInfluencerFiltersAction); - uiActions.addTriggerAction(SWIM_LANE_SELECTION_TRIGGER, applyTimeRangeSelectionAction); - uiActions.addTriggerAction(SWIM_LANE_SELECTION_TRIGGER, openInExplorerAction); - uiActions.addTriggerAction(SWIM_LANE_SELECTION_TRIGGER, openInSingleMetricViewerAction); - uiActions.addTriggerAction(SWIM_LANE_SELECTION_TRIGGER, clearSelectionAction); - uiActions.addTriggerAction(EXPLORER_ENTITY_FIELD_SELECTION_TRIGGER, applyEntityFieldFilterAction); - uiActions.addTriggerAction( + uiActions.addTriggerActionAsync( + SWIM_LANE_SELECTION_TRIGGER, + 'apply-to-current-view', + async () => { + const { createApplyInfluencerFiltersAction } = await import('./async_module'); + return createApplyInfluencerFiltersAction(core.getStartServices); + } + ); + uiActions.addTriggerActionAsync( + SWIM_LANE_SELECTION_TRIGGER, + 'apply-time-range-selection', + async () => { + const { createApplyTimeRangeSelectionAction } = await import('./async_module'); + return createApplyTimeRangeSelectionAction(core.getStartServices); + } + ); + uiActions.addTriggerActionAsync( + SWIM_LANE_SELECTION_TRIGGER, + 'open-in-anomaly-explorer', + async () => { + const { createOpenInExplorerAction } = await import('./async_module'); + return createOpenInExplorerAction(core.getStartServices); + } + ); + uiActions.addTriggerActionAsync( + SWIM_LANE_SELECTION_TRIGGER, + 'open-in-single-metric-viewer', + async () => { + const { createOpenInSingleMetricViewerAction } = await import('./async_module'); + return createOpenInSingleMetricViewerAction(core.getStartServices); + } + ); + uiActions.addTriggerActionAsync( + SWIM_LANE_SELECTION_TRIGGER, + 'clear-selection-action', + async () => { + const { createClearSelectionAction } = await import('./async_module'); + return createClearSelectionAction(core.getStartServices); + } + ); + uiActions.addTriggerActionAsync( + EXPLORER_ENTITY_FIELD_SELECTION_TRIGGER, + 'apply-entity-field-filters', + async () => { + const { createApplyEntityFieldFiltersAction } = await import('./async_module'); + return createApplyEntityFieldFiltersAction(core.getStartServices); + } + ); + uiActions.addTriggerActionAsync( SINGLE_METRIC_VIEWER_ENTITY_FIELD_SELECTION_TRIGGER, - smvApplyEntityFieldFilterAction + 'smv-apply-entity-field-filters', + async () => { + const { createApplyEntityFieldFiltersAction } = await import('./async_module'); + return createApplyEntityFieldFiltersAction( + core.getStartServices, + CONTROLLED_BY_SINGLE_METRIC_VIEWER_FILTER + ); + } ); - uiActions.addTriggerAction(ON_OPEN_PANEL_MENU, visToAdJobAction); - uiActions.addTriggerAction( + uiActions.addTriggerActionAsync(ON_OPEN_PANEL_MENU, 'create-ml-ad-job-action', async () => { + const { createVisToADJobAction } = await import('./async_module'); + return createVisToADJobAction(core.getStartServices); + }); + uiActions.addTriggerActionAsync( CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER, - categorizationADJobAction + 'create-ml-categorization-ad-job-action', + async () => { + const { createCategorizationADJobAction } = await import('./async_module'); + return createCategorizationADJobAction(core.getStartServices); + } ); } diff --git a/x-pack/solutions/security/plugins/security_solution/public/app/actions/register.ts b/x-pack/solutions/security/plugins/security_solution/public/app/actions/register.ts index 32eb668a86803..d84eb6594bad8 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/app/actions/register.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/app/actions/register.ts @@ -65,16 +65,32 @@ const registerLensEmbeddableActions = (store: SecurityAppStore, services: StartS const { uiActions } = services; const filterInLegendActions = createFilterInLensAction({ store, order: 2, services }); - uiActions.addTriggerAction(CELL_VALUE_TRIGGER, filterInLegendActions); + uiActions.addTriggerActionAsync( + CELL_VALUE_TRIGGER, + filterInLegendActions.id, + async () => filterInLegendActions + ); const filterOutLegendActions = createFilterOutLensAction({ store, order: 3, services }); - uiActions.addTriggerAction(CELL_VALUE_TRIGGER, filterOutLegendActions); + uiActions.addTriggerActionAsync( + CELL_VALUE_TRIGGER, + filterOutLegendActions.id, + async () => filterOutLegendActions + ); const addToTimelineAction = createAddToTimelineLensAction({ store, order: 4 }); - uiActions.addTriggerAction(CELL_VALUE_TRIGGER, addToTimelineAction); + uiActions.addTriggerActionAsync( + CELL_VALUE_TRIGGER, + addToTimelineAction.id, + async () => addToTimelineAction + ); const copyToClipboardAction = createCopyToClipboardLensAction({ order: 5 }); - uiActions.addTriggerAction(CELL_VALUE_TRIGGER, copyToClipboardAction); + uiActions.addTriggerActionAsync( + CELL_VALUE_TRIGGER, + copyToClipboardAction.id, + async () => copyToClipboardAction + ); }; const registerDiscoverCellActions = (store: SecurityAppStore, services: StartServices) => { @@ -96,7 +112,11 @@ const registerDiscoverCellActions = (store: SecurityAppStore, services: StartSer if (actionFactory) { const action = actionFactory({ id: `${triggerId}-${actionName}`, order }); const actionWithTelemetry = enhanceActionWithTelemetry(action, services); - uiActions.addTriggerAction(triggerId, actionWithTelemetry); + uiActions.addTriggerActionAsync( + triggerId, + actionWithTelemetry.id, + async () => actionWithTelemetry + ); } }); }; @@ -137,7 +157,11 @@ const registerCellActions = ( if (actionFactory) { const action = actionFactory({ id: `${triggerId}-${actionName}`, order }); const actionWithTelemetry = enhanceActionWithTelemetry(action, services); - uiActions.addTriggerAction(triggerId, actionWithTelemetry); + uiActions.addTriggerActionAsync( + triggerId, + actionWithTelemetry.id, + async () => actionWithTelemetry + ); } }); }; diff --git a/x-pack/solutions/security/plugins/security_solution/public/app/actions/register_discover_histogram_actions.ts b/x-pack/solutions/security/plugins/security_solution/public/app/actions/register_discover_histogram_actions.ts index 796c848a4117b..86460f344d652 100644 --- a/x-pack/solutions/security/plugins/security_solution/public/app/actions/register_discover_histogram_actions.ts +++ b/x-pack/solutions/security/plugins/security_solution/public/app/actions/register_discover_histogram_actions.ts @@ -27,7 +27,7 @@ const createDiscoverHistogramCustomFilterAction = async ( EsqlInTimelineAction.VIS_FILTER_ACTION, EsqlInTimelineAction.VIS_FILTER_ACTION ); - services.uiActions.registerAction(histogramApplyFilter); + services.uiActions.registerActionAsync(histogramApplyFilter.id, async () => histogramApplyFilter); return histogramApplyFilter; };