diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/slo_alerts_embeddable_factory.tsx b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/slo_alerts_embeddable_factory.tsx index b70e1d8e4c40a2..24c29a20f1e6fd 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/slo_alerts_embeddable_factory.tsx +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/slo_alerts_embeddable_factory.tsx @@ -21,8 +21,10 @@ import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { createBrowserHistory } from 'history'; import { Storage } from '@kbn/kibana-utils-plugin/public'; +import type { StartServicesAccessor } from '@kbn/core-lifecycle-browser'; import { SLO_ALERTS_EMBEDDABLE_ID } from './constants'; -import { SloEmbeddableDeps, SloAlertsEmbeddableState, SloAlertsApi } from './types'; +import { SloAlertsEmbeddableState, SloAlertsApi } from './types'; +import { SloPublicPluginsStart, SloPublicStart } from '../../../types'; import { SloAlertsWrapper } from './slo_alerts_wrapper'; const history = createBrowserHistory(); const queryClient = new QueryClient(); @@ -32,7 +34,10 @@ export const getAlertsPanelTitle = () => defaultMessage: 'SLO Alerts', }); -export function getAlertsEmbeddableFactory(deps: SloEmbeddableDeps, kibanaVersion: string) { +export function getAlertsEmbeddableFactory( + getStartServices: StartServicesAccessor, + kibanaVersion: string +) { const factory: ReactEmbeddableFactory< SloAlertsEmbeddableState, SloAlertsEmbeddableState, @@ -43,6 +48,23 @@ export function getAlertsEmbeddableFactory(deps: SloEmbeddableDeps, kibanaVersio return state.rawState as SloAlertsEmbeddableState; }, buildEmbeddable: async (state, buildApi, uuid, parentApi) => { + const [coreStart, pluginStart] = await getStartServices(); + const deps = { ...coreStart, ...pluginStart }; + async function onEdit() { + try { + const { openSloConfiguration } = await import('./slo_alerts_open_configuration'); + + const result = await openSloConfiguration( + coreStart, + pluginStart, + api.getSloAlertsConfig() + ); + api.updateSloAlertsConfig(result); + } catch (e) { + return Promise.reject(); + } + } + const { titlesApi, titleComparators, serializeTitles } = initializeTitles(state); const defaultTitle$ = new BehaviorSubject(getAlertsPanelTitle()); const slos$ = new BehaviorSubject(state.slos); @@ -52,6 +74,14 @@ export function getAlertsEmbeddableFactory(deps: SloEmbeddableDeps, kibanaVersio { ...titlesApi, defaultPanelTitle: defaultTitle$, + getTypeDisplayName: () => + i18n.translate('xpack.slo.editSloAlertswEmbeddable.typeDisplayName', { + defaultMessage: 'configuration', + }), + isEditingEnabled: () => true, + onEdit: async () => { + onEdit(); + }, serializeState: () => { return { rawState: { @@ -116,7 +146,7 @@ export function getAlertsEmbeddableFactory(deps: SloEmbeddableDeps, kibanaVersio void; reloadSubject: Subject; showAllGroupByInstances?: boolean; + onEdit: () => void; } export function SloAlertsWrapper({ - embeddable, slos, deps, timeRange: initialTimeRange, onRenderComplete, reloadSubject, showAllGroupByInstances, + onEdit, }: Props) { const { application: { navigateToUrl }, @@ -102,11 +99,7 @@ export function SloAlertsWrapper({ { - const trigger = deps.uiActions.getTrigger(CONTEXT_MENU_TRIGGER); - deps.uiActions.getAction(EDIT_SLO_ALERTS_ACTION).execute({ - trigger, - embeddable, - } as ActionExecutionContext); + onEdit(); }} data-test-subj="o11ySloAlertsWrapperSlOsIncludedLink" > diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/types.ts b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/types.ts index 8b660442ca7b66..7682c3f55bedfe 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/types.ts +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/alerts/types.ts @@ -24,6 +24,7 @@ import { PublishesWritablePanelTitle, PublishesPanelTitle, EmbeddableApiContext, + HasEditCapabilities, } from '@kbn/presentation-publishing'; export interface SloItem { @@ -45,7 +46,8 @@ export type SloAlertsEmbeddableState = SerializedTitles & EmbeddableSloProps; export type SloAlertsApi = DefaultEmbeddableApi & PublishesWritablePanelTitle & PublishesPanelTitle & - HasSloAlertsConfig; + HasSloAlertsConfig & + HasEditCapabilities; export interface HasSloAlertsConfig { getSloAlertsConfig: () => EmbeddableSloProps; diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/overview/slo_embeddable_factory.tsx b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/overview/slo_embeddable_factory.tsx index 861909b040e9a5..2d043e85df4d44 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/overview/slo_embeddable_factory.tsx +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/overview/slo_embeddable_factory.tsx @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n'; import React, { useEffect } from 'react'; import styled from 'styled-components'; -import { EuiFlexItem, EuiLink, EuiFlexGroup } from '@elastic/eui'; +import { EuiFlexItem, EuiFlexGroup } from '@elastic/eui'; import { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public'; import { initializeTitles, @@ -16,26 +16,22 @@ import { fetch$, } from '@kbn/presentation-publishing'; import { BehaviorSubject, Subject } from 'rxjs'; -import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; -import { ActionExecutionContext } from '@kbn/ui-actions-plugin/public'; +import type { StartServicesAccessor } from '@kbn/core-lifecycle-browser'; import { SLO_OVERVIEW_EMBEDDABLE_ID } from './constants'; import { SloCardChartList } from './slo_overview_grid'; import { SloOverview } from './slo_overview'; import { GroupSloView } from './group_view/group_view'; -import { - SloOverviewEmbeddableState, - SloEmbeddableDeps, - SloOverviewApi, - GroupSloCustomInput, -} from './types'; -import { EDIT_SLO_OVERVIEW_ACTION } from '../../../ui_actions/edit_slo_overview_panel'; +import { SloOverviewEmbeddableState, SloOverviewApi, GroupSloCustomInput } from './types'; +import { SloPublicPluginsStart, SloPublicStart } from '../../../types'; import { SloEmbeddableContext } from '../common/slo_embeddable_context'; export const getOverviewPanelTitle = () => i18n.translate('xpack.slo.sloEmbeddable.displayName', { defaultMessage: 'SLO Overview', }); -export const getOverviewEmbeddableFactory = (deps: SloEmbeddableDeps) => { +export const getOverviewEmbeddableFactory = ( + getStartServices: StartServicesAccessor +) => { const factory: ReactEmbeddableFactory< SloOverviewEmbeddableState, SloOverviewEmbeddableState, @@ -46,6 +42,22 @@ export const getOverviewEmbeddableFactory = (deps: SloEmbeddableDeps) => { return state.rawState as SloOverviewEmbeddableState; }, buildEmbeddable: async (state, buildApi, uuid, parentApi) => { + const [coreStart, pluginStart] = await getStartServices(); + const deps = { ...coreStart, ...pluginStart }; + async function onEdit() { + try { + const { openSloConfiguration } = await import('./slo_overview_open_configuration'); + + const result = await openSloConfiguration( + coreStart, + pluginStart, + api.getSloGroupOverviewConfig() + ); + api.updateSloGroupOverviewConfig(result as GroupSloCustomInput); + } catch (e) { + return Promise.reject(); + } + } const { titlesApi, titleComparators, serializeTitles } = initializeTitles(state); const defaultTitle$ = new BehaviorSubject(getOverviewPanelTitle()); const sloId$ = new BehaviorSubject(state.sloId); @@ -60,6 +72,14 @@ export const getOverviewEmbeddableFactory = (deps: SloEmbeddableDeps) => { { ...titlesApi, defaultPanelTitle: defaultTitle$, + getTypeDisplayName: () => + i18n.translate('xpack.slo.editSloOverviewEmbeddableTitle.typeDisplayName', { + defaultMessage: 'criteria', + }), + isEditingEnabled: () => api.getSloGroupOverviewConfig().overviewMode === 'groups', + onEdit: async () => { + onEdit(); + }, serializeState: () => { return { rawState: { @@ -134,42 +154,22 @@ export const getOverviewEmbeddableFactory = (deps: SloEmbeddableDeps) => { const groups = groupFilters?.groups ?? []; return ( - - - { - const trigger = deps.uiActions.getTrigger(CONTEXT_MENU_TRIGGER); - deps.uiActions.getAction(EDIT_SLO_OVERVIEW_ACTION).execute({ - trigger, - embeddable: api, - } as ActionExecutionContext); - }} - data-test-subj="o11ySloOverviewEditCriteriaLink" - > - {i18n.translate('xpack.slo.overviewEmbeddable.editCriteriaLabel', { - defaultMessage: 'Edit criteria', - })} - + + + - - - ); } else { diff --git a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/overview/types.ts b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/overview/types.ts index 8773fba3e0998a..c64faff1f110d2 100644 --- a/x-pack/plugins/observability_solution/slo/public/embeddable/slo/overview/types.ts +++ b/x-pack/plugins/observability_solution/slo/public/embeddable/slo/overview/types.ts @@ -8,6 +8,7 @@ import { SerializedTitles, PublishesWritablePanelTitle, PublishesPanelTitle, + HasEditCapabilities, } from '@kbn/presentation-publishing'; import type { EmbeddableApiContext } from '@kbn/presentation-publishing'; import { DefaultEmbeddableApi } from '@kbn/embeddable-plugin/public'; @@ -53,7 +54,8 @@ export type SloOverviewEmbeddableState = SerializedTitles & export type SloOverviewApi = DefaultEmbeddableApi & PublishesWritablePanelTitle & PublishesPanelTitle & - HasSloGroupOverviewConfig; + HasSloGroupOverviewConfig & + HasEditCapabilities; export interface HasSloGroupOverviewConfig { getSloGroupOverviewConfig: () => GroupSloCustomInput; diff --git a/x-pack/plugins/observability_solution/slo/public/plugin.ts b/x-pack/plugins/observability_solution/slo/public/plugin.ts index e387a7f85a7e3b..5bdd830830fd63 100644 --- a/x-pack/plugins/observability_solution/slo/public/plugin.ts +++ b/x-pack/plugins/observability_solution/slo/public/plugin.ts @@ -108,24 +108,21 @@ export class SloPlugin pluginsSetup.embeddable.registerReactEmbeddableFactory( SLO_OVERVIEW_EMBEDDABLE_ID, async () => { - const deps = { ...coreStart, ...pluginsStart }; const { getOverviewEmbeddableFactory } = await import( './embeddable/slo/overview/slo_embeddable_factory' ); - return getOverviewEmbeddableFactory(deps); + return getOverviewEmbeddableFactory(coreSetup.getStartServices); } ); pluginsSetup.embeddable.registerReactEmbeddableFactory( SLO_ALERTS_EMBEDDABLE_ID, async () => { - const deps = { ...coreStart, ...pluginsStart }; - const { getAlertsEmbeddableFactory } = await import( './embeddable/slo/alerts/slo_alerts_embeddable_factory' ); - return getAlertsEmbeddableFactory(deps, kibanaVersion); + return getAlertsEmbeddableFactory(coreSetup.getStartServices, kibanaVersion); } ); diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/edit_slo_alerts_panel.tsx b/x-pack/plugins/observability_solution/slo/public/ui_actions/edit_slo_alerts_panel.tsx deleted file mode 100644 index ce9b4d196ffb5b..00000000000000 --- a/x-pack/plugins/observability_solution/slo/public/ui_actions/edit_slo_alerts_panel.tsx +++ /dev/null @@ -1,75 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { ViewMode } from '@kbn/embeddable-plugin/common'; -import type { CoreSetup } from '@kbn/core/public'; -import { - apiCanAccessViewMode, - apiHasType, - apiIsOfType, - EmbeddableApiContext, - getInheritedViewMode, - CanAccessViewMode, - HasType, -} from '@kbn/presentation-publishing'; -import { type UiActionsActionDefinition } from '@kbn/ui-actions-plugin/public'; -import { SLO_ALERTS_EMBEDDABLE_ID } from '../embeddable/slo/alerts/constants'; -import { SloPublicPluginsStart, SloPublicStart } from '..'; -import { - HasSloAlertsConfig, - SloAlertsEmbeddableActionContext, -} from '../embeddable/slo/alerts/types'; -export const EDIT_SLO_ALERTS_ACTION = 'editSloAlertsPanelAction'; -type EditSloAlertsPanelApi = CanAccessViewMode & HasType & HasSloAlertsConfig; -const isEditSloAlertsPanelApi = (api: unknown): api is EditSloAlertsPanelApi => - Boolean( - apiHasType(api) && - apiIsOfType(api, SLO_ALERTS_EMBEDDABLE_ID) && - apiCanAccessViewMode(api) && - getInheritedViewMode(api) === ViewMode.EDIT - ); - -export function createEditSloAlertsPanelAction( - getStartServices: CoreSetup['getStartServices'] -): UiActionsActionDefinition { - return { - id: EDIT_SLO_ALERTS_ACTION, - type: EDIT_SLO_ALERTS_ACTION, - getIconType(): string { - return 'pencil'; - }, - getDisplayName: () => - i18n.translate('xpack.slo.actions.editSloAlertsEmbeddableTitle', { - defaultMessage: 'Edit configuration', - }), - async execute({ embeddable }) { - if (!embeddable) { - throw new Error('Not possible to execute an action without the embeddable context'); - } - - const [coreStart, pluginStart] = await getStartServices(); - - try { - const { openSloConfiguration } = await import( - '../embeddable/slo/alerts/slo_alerts_open_configuration' - ); - - const result = await openSloConfiguration( - coreStart, - pluginStart, - embeddable.getSloAlertsConfig() - ); - embeddable.updateSloAlertsConfig(result); - } catch (e) { - return Promise.reject(); - } - }, - isCompatible: async ({ embeddable }: EmbeddableApiContext) => - isEditSloAlertsPanelApi(embeddable), - }; -} diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/edit_slo_overview_panel.tsx b/x-pack/plugins/observability_solution/slo/public/ui_actions/edit_slo_overview_panel.tsx deleted file mode 100644 index 55f5c9b6feb0de..00000000000000 --- a/x-pack/plugins/observability_solution/slo/public/ui_actions/edit_slo_overview_panel.tsx +++ /dev/null @@ -1,86 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { i18n } from '@kbn/i18n'; -import { ViewMode } from '@kbn/embeddable-plugin/common'; -import type { CoreSetup } from '@kbn/core/public'; -import { - apiCanAccessViewMode, - apiHasType, - apiIsOfType, - EmbeddableApiContext, - getInheritedViewMode, - CanAccessViewMode, - HasType, -} from '@kbn/presentation-publishing'; -import { - type UiActionsActionDefinition, - IncompatibleActionError, -} from '@kbn/ui-actions-plugin/public'; -import { SLO_EMBEDDABLE } from '../embeddable/slo/constants'; -import { SloPublicPluginsStart, SloPublicStart } from '..'; -import { - GroupSloCustomInput, - HasSloGroupOverviewConfig, - SloOverviewEmbeddableActionContext, - apiHasSloGroupOverviewConfig, -} from '../embeddable/slo/overview/types'; - -export const EDIT_SLO_OVERVIEW_ACTION = 'editSloOverviewPanelAction'; -type EditSloOverviewPanelApi = CanAccessViewMode & HasType & HasSloGroupOverviewConfig; -const isEditSloOverviewPanelApi = (api: unknown): api is EditSloOverviewPanelApi => - Boolean( - apiHasType(api) && - apiIsOfType(api, SLO_EMBEDDABLE) && - apiCanAccessViewMode(api) && - getInheritedViewMode(api) === ViewMode.EDIT - ); - -export function createEditSloOverviewPanelAction( - getStartServices: CoreSetup['getStartServices'] -): UiActionsActionDefinition { - return { - id: EDIT_SLO_OVERVIEW_ACTION, - type: EDIT_SLO_OVERVIEW_ACTION, - getIconType(): string { - return 'pencil'; - }, - getDisplayName: () => - i18n.translate('xpack.slo.actions.editSloOverviewEmbeddableTitle', { - defaultMessage: 'Edit criteria', - }), - async execute(context) { - const { embeddable } = context; - if (!apiHasSloGroupOverviewConfig(embeddable)) { - throw new IncompatibleActionError(); - } - - const [coreStart, pluginStart] = await getStartServices(); - - try { - const { openSloConfiguration } = await import( - '../embeddable/slo/overview/slo_overview_open_configuration' - ); - - const result = await openSloConfiguration( - coreStart, - pluginStart, - embeddable.getSloGroupOverviewConfig() - ); - embeddable.updateSloGroupOverviewConfig(result as GroupSloCustomInput); - } catch (e) { - return Promise.reject(); - } - }, - isCompatible: async ({ embeddable }: EmbeddableApiContext) => { - return ( - isEditSloOverviewPanelApi(embeddable) && - embeddable.getSloGroupOverviewConfig().overviewMode === 'groups' - ); - }, - }; -} diff --git a/x-pack/plugins/observability_solution/slo/public/ui_actions/index.ts b/x-pack/plugins/observability_solution/slo/public/ui_actions/index.ts index 76862a3afe90d8..61c1569f1a9d7c 100644 --- a/x-pack/plugins/observability_solution/slo/public/ui_actions/index.ts +++ b/x-pack/plugins/observability_solution/slo/public/ui_actions/index.ts @@ -6,10 +6,7 @@ */ import type { UiActionsSetup } from '@kbn/ui-actions-plugin/public'; -import { CONTEXT_MENU_TRIGGER } from '@kbn/embeddable-plugin/public'; import type { CoreSetup } from '@kbn/core/public'; -import { createEditSloAlertsPanelAction } from './edit_slo_alerts_panel'; -import { createEditSloOverviewPanelAction } from './edit_slo_overview_panel'; import { createOverviewPanelAction } from './create_overview_panel_action'; import { createAddErrorBudgetPanelAction } from './create_error_budget_action'; import { createAddAlertsPanelAction } from './create_alerts_panel_action'; @@ -20,15 +17,11 @@ export function registerSloUiActions( core: CoreSetup ) { // Initialize actions - const editSloAlertsPanelAction = createEditSloAlertsPanelAction(core.getStartServices); - const editSloOverviewPanelAction = createEditSloOverviewPanelAction(core.getStartServices); const addOverviewPanelAction = createOverviewPanelAction(core.getStartServices); const addErrorBudgetPanelAction = createAddErrorBudgetPanelAction(core.getStartServices); const addAlertsPanelAction = createAddAlertsPanelAction(core.getStartServices); // Assign triggers - uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, editSloAlertsPanelAction); - uiActions.addTriggerAction(CONTEXT_MENU_TRIGGER, editSloOverviewPanelAction); uiActions.addTriggerAction('ADD_PANEL_TRIGGER', addOverviewPanelAction); uiActions.addTriggerAction('ADD_PANEL_TRIGGER', addErrorBudgetPanelAction); uiActions.addTriggerAction('ADD_PANEL_TRIGGER', addAlertsPanelAction);