[ML] [AIOps] Moving uiActions code (#171771)

Moves the categorize field uiAction trigger and action and related items
to the AIOps/ML uiActions package.
ML and AIOps are adding more and more uiActions, and so it's nicer to
have them all in one package.

Also cleans up the registration of the uiActions in the AIOps plugin

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
James Gowdy 2023-11-24 13:16:20 +00:00 committed by GitHub
parent f555dbef29
commit 56c494f908
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 114 additions and 94 deletions

View file

@ -15,7 +15,5 @@ export {
visualizeGeoFieldTrigger,
ROW_CLICK_TRIGGER,
rowClickTrigger,
CATEGORIZE_FIELD_TRIGGER,
categorizeFieldTrigger,
defaultTrigger,
} from './src/triggers';

View file

@ -1,16 +0,0 @@
/*
* 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 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 or the Server
* Side Public License, v 1.
*/
import { Trigger } from './trigger';
export const CATEGORIZE_FIELD_TRIGGER = 'CATEGORIZE_FIELD_TRIGGER';
export const categorizeFieldTrigger: Trigger = {
id: CATEGORIZE_FIELD_TRIGGER,
title: 'Run pattern analysis',
description: 'Triggered when user wants to run pattern analysis on a field.',
};

View file

@ -11,4 +11,3 @@ export * from './row_click_trigger';
export * from './default_trigger';
export * from './visualize_field_trigger';
export * from './visualize_geo_field_trigger';
export * from './categorize_field_trigger';

View file

@ -6,8 +6,8 @@
* Side Public License, v 1.
*/
import type { UiActionsStart, CategorizeFieldContext } from '@kbn/ui-actions-plugin/public';
import { CATEGORIZE_FIELD_TRIGGER } from '@kbn/ui-actions-browser/src/triggers';
import type { UiActionsStart } from '@kbn/ui-actions-plugin/public';
import { CATEGORIZE_FIELD_TRIGGER, type CategorizeFieldContext } from '@kbn/ml-ui-actions';
import type { DataViewField, DataView } from '@kbn/data-views-plugin/public';
async function getCompatibleActions(

View file

@ -14,9 +14,12 @@ import { stubLogstashDataView as dataView } from '@kbn/data-views-plugin/common/
import { ActionInternal } from '@kbn/ui-actions-plugin/public';
import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks';
import { getFieldCategorizeButton } from './field_categorize_button';
import { ACTION_CATEGORIZE_FIELD, CategorizeFieldContext } from '@kbn/ui-actions-plugin/public';
import {
CATEGORIZE_FIELD_TRIGGER,
ACTION_CATEGORIZE_FIELD,
type CategorizeFieldContext,
} from '@kbn/ml-ui-actions';
import { TriggerContract } from '@kbn/ui-actions-plugin/public/triggers';
import { CATEGORIZE_FIELD_TRIGGER } from '@kbn/ui-actions-browser';
const ORIGINATING_APP = 'test';
const mockExecuteAction = jest.fn();

View file

@ -31,6 +31,7 @@
"@kbn/ebt-tools",
"@kbn/shared-ux-button-toolbar",
"@kbn/field-utils",
"@kbn/ml-ui-actions",
],
"exclude": ["target/**/*"]
}

View file

@ -31,14 +31,11 @@ export {
visualizeGeoFieldTrigger,
ROW_CLICK_TRIGGER,
rowClickTrigger,
CATEGORIZE_FIELD_TRIGGER,
categorizeFieldTrigger,
} from '@kbn/ui-actions-browser/src/triggers';
export type { VisualizeFieldContext, CategorizeFieldContext } from './types';
export type { VisualizeFieldContext } from './types';
export {
ACTION_VISUALIZE_FIELD,
ACTION_VISUALIZE_GEO_FIELD,
ACTION_VISUALIZE_LENS_FIELD,
ACTION_CATEGORIZE_FIELD,
} from './types';
export type { ActionExecutionContext, ActionExecutionMeta, ActionMenuItemProps } from './actions';

View file

@ -9,7 +9,6 @@
import { CoreStart, CoreSetup, Plugin, PluginInitializerContext } from '@kbn/core/public';
import { PublicMethodsOf } from '@kbn/utility-types';
import {
categorizeFieldTrigger,
rowClickTrigger,
visualizeFieldTrigger,
visualizeGeoFieldTrigger,
@ -39,7 +38,6 @@ export class UiActionsPlugin implements Plugin<UiActionsSetup, UiActionsStart> {
this.service.registerTrigger(rowClickTrigger);
this.service.registerTrigger(visualizeFieldTrigger);
this.service.registerTrigger(visualizeGeoFieldTrigger);
this.service.registerTrigger(categorizeFieldTrigger);
return this.service;
}

View file

@ -7,7 +7,7 @@
*/
import type { DatatableColumn } from '@kbn/expressions-plugin/common';
import type { AggregateQuery } from '@kbn/es-query';
import type { DataViewField, DataViewSpec, DataView } from '@kbn/data-views-plugin/public';
import type { DataViewSpec } from '@kbn/data-views-plugin/public';
import { ActionInternal } from './actions/action_internal';
import { TriggerInternal } from './triggers/trigger_internal';
@ -24,13 +24,6 @@ export interface VisualizeFieldContext {
query?: AggregateQuery;
}
export interface CategorizeFieldContext {
field: DataViewField;
dataView: DataView;
originatingApp: string;
}
export const ACTION_VISUALIZE_FIELD = 'ACTION_VISUALIZE_FIELD';
export const ACTION_VISUALIZE_GEO_FIELD = 'ACTION_VISUALIZE_GEO_FIELD';
export const ACTION_VISUALIZE_LENS_FIELD = 'ACTION_VISUALIZE_LENS_FIELD';
export const ACTION_CATEGORIZE_FIELD = 'ACTION_CATEGORIZE_FIELD';

View file

@ -59,6 +59,7 @@
"packages/ml/date_picker",
"packages/ml/trained_models_utils",
"packages/ml/category_validator",
"packages/ml/ui_actions",
"plugins/ml"
],
"xpack.monitoring": ["plugins/monitoring"],

View file

@ -9,4 +9,11 @@ export {
CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_ACTION,
CREATE_PATTERN_ANALYSIS_TO_ML_AD_JOB_TRIGGER,
type CreateCategorizationADJobContext,
} from './src/ui_actions';
} from './src/ml/ui_actions';
export {
ACTION_CATEGORIZE_FIELD,
CATEGORIZE_FIELD_TRIGGER,
categorizeFieldTrigger,
type CategorizeFieldContext,
} from './src/aiops/ui_actions';

View file

@ -0,0 +1,34 @@
/*
* 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.
*/
import type { DataView, DataViewField } from '@kbn/data-views-plugin/common';
import { i18n } from '@kbn/i18n';
import type { Trigger } from '@kbn/ui-actions-plugin/public';
export interface CategorizeFieldContext {
field: DataViewField;
dataView: DataView;
originatingApp: string;
additionalFilter?: {
from: number;
to: number;
field?: { name: string; value: string };
};
}
export const ACTION_CATEGORIZE_FIELD = 'ACTION_CATEGORIZE_FIELD';
export const CATEGORIZE_FIELD_TRIGGER = 'CATEGORIZE_FIELD_TRIGGER';
export const categorizeFieldTrigger: Trigger = {
id: CATEGORIZE_FIELD_TRIGGER,
title: i18n.translate('xpack.ml.actions.runPatternAnalysis.title', {
defaultMessage: 'Run pattern analysis',
}),
description: i18n.translate('xpack.ml.actions.runPatternAnalysis.description', {
defaultMessage: 'Triggered when user wants to run pattern analysis on a field.',
}),
};

View file

@ -16,5 +16,7 @@
"kbn_references": [
"@kbn/data-views-plugin",
"@kbn/es-query",
"@kbn/ui-actions-plugin",
"@kbn/i18n",
]
}

View file

@ -6,22 +6,19 @@
*/
import { i18n } from '@kbn/i18n';
import {
createAction,
ACTION_CATEGORIZE_FIELD,
type CategorizeFieldContext,
} from '@kbn/ui-actions-plugin/public';
import { createAction } from '@kbn/ui-actions-plugin/public';
import type { CoreStart } from '@kbn/core/public';
import { ACTION_CATEGORIZE_FIELD, type CategorizeFieldContext } from '@kbn/ml-ui-actions';
import { AiopsPluginStartDeps } from '../../types';
import { showCategorizeFlyout } from './show_flyout';
export const categorizeFieldAction = (coreStart: CoreStart, plugins: AiopsPluginStartDeps) =>
export const createCategorizeFieldAction = (coreStart: CoreStart, plugins: AiopsPluginStartDeps) =>
createAction<CategorizeFieldContext>({
type: ACTION_CATEGORIZE_FIELD,
id: ACTION_CATEGORIZE_FIELD,
getDisplayName: () =>
i18n.translate('xpack.aiops.categorizeFieldAction.displayName', {
defaultMessage: 'Categorize field',
defaultMessage: 'Pattern analysis',
}),
isCompatible: async ({ field }: CategorizeFieldContext) => {
return field.esTypes?.includes('text') === true;

View file

@ -7,7 +7,7 @@
export type { LogCategorizationAppStateProps } from './log_categorization_app_state';
import { LogCategorizationAppState } from './log_categorization_app_state';
export { categorizeFieldAction } from './categorize_field_actions';
export { createCategorizeFieldAction } from './categorize_field_actions';
// required for dynamic import using React.lazy()
// eslint-disable-next-line import/no-default-export

View file

@ -25,49 +25,38 @@ export class AiopsPlugin
core: AiopsCoreSetup,
{ embeddable, cases, licensing, uiActions }: AiopsPluginSetupDeps
) {
firstValueFrom(licensing.license$).then(async (license) => {
if (license.hasAtLeast('platinum')) {
if (embeddable) {
const { registerEmbeddable } = await import('./embeddable/register_embeddable');
registerEmbeddable(core, embeddable);
}
Promise.all([
firstValueFrom(licensing.license$),
import('./embeddable/register_embeddable'),
import('./ui_actions'),
import('./cases/register_change_point_charts_attachment'),
core.getStartServices(),
]).then(
([
license,
{ registerEmbeddable },
{ registerAiopsUiActions },
{ registerChangePointChartsAttachment },
[coreStart, pluginStart],
]) => {
if (license.hasAtLeast('platinum')) {
if (embeddable) {
registerEmbeddable(core, embeddable);
}
if (uiActions) {
const { registerAiopsUiActions } = await import('./ui_actions');
registerAiopsUiActions(uiActions, core);
}
if (uiActions) {
registerAiopsUiActions(uiActions, coreStart, pluginStart);
}
if (cases) {
const [coreStart, pluginStart] = await core.getStartServices();
const { registerChangePointChartsAttachment } = await import(
'./cases/register_change_point_charts_attachment'
);
registerChangePointChartsAttachment(cases, coreStart, pluginStart);
if (cases) {
registerChangePointChartsAttachment(cases, coreStart, pluginStart);
}
}
}
});
);
}
public start(core: CoreStart, plugins: AiopsPluginStartDeps): AiopsPluginStart {
// importing async to keep the aiops plugin size to a minimum
Promise.all([
import('@kbn/ui-actions-plugin/public'),
import('./components/log_categorization'),
firstValueFrom(plugins.licensing.license$),
]).then(([uiActionsImports, { categorizeFieldAction }, license]) => {
if (license.hasAtLeast('platinum')) {
const { ACTION_CATEGORIZE_FIELD, CATEGORIZE_FIELD_TRIGGER } = uiActionsImports;
if (plugins.uiActions.hasAction(ACTION_CATEGORIZE_FIELD)) {
plugins.uiActions.unregisterAction(ACTION_CATEGORIZE_FIELD);
}
plugins.uiActions.addTriggerAction(
CATEGORIZE_FIELD_TRIGGER,
categorizeFieldAction(core, plugins)
);
}
});
return {
EmbeddableChangePointChart: getEmbeddableChangePointChart(core, plugins),
};

View file

@ -8,14 +8,16 @@
import type { UiActionsActionDefinition } from '@kbn/ui-actions-plugin/public';
import { i18n } from '@kbn/i18n';
import { ViewMode } from '@kbn/embeddable-plugin/common';
import type { CoreStart } from '@kbn/core/public';
import { EMBEDDABLE_CHANGE_POINT_CHART_TYPE } from '../../common/constants';
import type { EditChangePointChartsPanelContext } from '../embeddable/types';
import type { AiopsCoreSetup } from '../plugin';
import type { AiopsPluginStartDeps } from '../types';
export const EDIT_CHANGE_POINT_CHARTS_ACTION = 'editChangePointChartsPanelAction';
export function createEditChangePointChartsPanelAction(
getStartServices: AiopsCoreSetup['getStartServices']
coreStart: CoreStart,
pluginStart: AiopsPluginStartDeps
): UiActionsActionDefinition<EditChangePointChartsPanelContext> {
return {
id: 'edit-change-point-charts',
@ -32,8 +34,6 @@ export function createEditChangePointChartsPanelAction(
throw new Error('Not possible to execute an action without the embeddable context');
}
const [coreStart, pluginStart] = await getStartServices();
try {
const { resolveEmbeddableChangePointUserInput } = await import(
'../embeddable/handle_explicit_input'

View file

@ -7,16 +7,33 @@
import type { UiActionsSetup } from '@kbn/ui-actions-plugin/public';
import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public';
import { createEditChangePointChartsPanelAction } from './edit_change_point_charts_panel';
import type { AiopsCoreSetup } from '../plugin';
import {
categorizeFieldTrigger,
CATEGORIZE_FIELD_TRIGGER,
} from '@kbn/ml-ui-actions/src/aiops/ui_actions';
export function registerAiopsUiActions(uiActions: UiActionsSetup, core: AiopsCoreSetup) {
import type { CoreStart } from '@kbn/core/public';
import type { AiopsPluginStartDeps } from '../types';
import { createEditChangePointChartsPanelAction } from './edit_change_point_charts_panel';
import { createCategorizeFieldAction } from '../components/log_categorization';
export function registerAiopsUiActions(
uiActions: UiActionsSetup,
coreStart: CoreStart,
pluginStart: AiopsPluginStartDeps
) {
// Initialize actions
const editChangePointChartPanelAction = createEditChangePointChartsPanelAction(
core.getStartServices
coreStart,
pluginStart
);
// // Register actions and triggers
uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, editChangePointChartPanelAction);
uiActions.registerTrigger(categorizeFieldTrigger);
uiActions.addTriggerAction(
CATEGORIZE_FIELD_TRIGGER,
createCategorizeFieldAction(coreStart, pluginStart)
);
// Register actions
uiActions.registerAction(editChangePointChartPanelAction);
// Assign and register triggers
uiActions.attachAction(CONTEXT_MENU_TRIGGER, editChangePointChartPanelAction.id);
}