[Embeddable] SLO Alerts embeddable to serialized state only (#218349)

_This PR does not need to be reviewed by external teams. This PR merges
into a feature branch that Kibana presentation team is working on to
convert the embeddable framework to only expose serialized state. Your
team will be pinged for review once the work is complete and the final
PR opens that merges the feature branch into main._

Converts the SLO alerts embeddable to serialized state only.

## Testing this PR

Create an SLO using the "How to Test" section in the description of
[this PR](https://github.com/elastic/kibana/pull/179147).

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Nick Peihl 2025-04-16 10:07:10 -04:00 committed by GitHub
parent c3b1acaa56
commit 95c3453ddf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 69 additions and 59 deletions

View file

@ -12,6 +12,6 @@
"@kbn/expressions-plugin",
"@kbn/core-execution-context-common",
"@kbn/content-management-utils",
"@kbn/utility-types",
"@kbn/utility-types"
]
}

View file

@ -6,14 +6,16 @@
*/
import type { CoreStart } from '@kbn/core-lifecycle-browser';
import { ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public';
import { EmbeddableFactory } from '@kbn/embeddable-plugin/public';
import { i18n } from '@kbn/i18n';
import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public';
import { Storage } from '@kbn/kibana-utils-plugin/public';
import {
FetchContext,
fetch$,
initializeStateManager,
initializeTitleManager,
titleComparators,
useBatchedPublishingSubjects,
useFetchContext,
} from '@kbn/presentation-publishing';
@ -21,12 +23,13 @@ import { Router } from '@kbn/shared-ux-router';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { createBrowserHistory } from 'history';
import React, { useEffect } from 'react';
import { BehaviorSubject, Subject } from 'rxjs';
import { BehaviorSubject, Subject, merge } from 'rxjs';
import { initializeUnsavedChanges } from '@kbn/presentation-containers';
import { PluginContext } from '../../../context/plugin_context';
import { SLOPublicPluginsStart, SLORepositoryClient } from '../../../types';
import { SLO_ALERTS_EMBEDDABLE_ID } from './constants';
import { SloAlertsWrapper } from './slo_alerts_wrapper';
import { SloAlertsApi, SloAlertsEmbeddableState } from './types';
import { EmbeddableSloProps, SloAlertsApi, SloAlertsEmbeddableState } from './types';
import { openSloConfiguration } from './slo_alerts_open_configuration';
const history = createBrowserHistory();
const queryClient = new QueryClient();
@ -47,16 +50,9 @@ export function getAlertsEmbeddableFactory({
sloClient: SLORepositoryClient;
kibanaVersion: string;
}) {
const factory: ReactEmbeddableFactory<
SloAlertsEmbeddableState,
SloAlertsEmbeddableState,
SloAlertsApi
> = {
const factory: EmbeddableFactory<SloAlertsEmbeddableState, SloAlertsApi> = {
type: SLO_ALERTS_EMBEDDABLE_ID,
deserializeState: (state) => {
return state.rawState as SloAlertsEmbeddableState;
},
buildEmbeddable: async (state, buildApi, uuid, parentApi) => {
buildEmbeddable: async ({ initialState, finalizeApi, uuid, parentApi }) => {
const deps = { ...coreStart, ...pluginsStart };
async function onEdit() {
try {
@ -72,52 +68,66 @@ export function getAlertsEmbeddableFactory({
}
}
const titleManager = initializeTitleManager(state);
const defaultTitle$ = new BehaviorSubject<string | undefined>(getAlertsPanelTitle());
const slos$ = new BehaviorSubject(state.slos);
const showAllGroupByInstances$ = new BehaviorSubject(state.showAllGroupByInstances);
const reload$ = new Subject<FetchContext>();
const api = buildApi(
const titleManager = initializeTitleManager(initialState.rawState);
const sloAlertsStateManager = initializeStateManager<EmbeddableSloProps>(
initialState.rawState,
{
...titleManager.api,
defaultTitle$,
getTypeDisplayName: () =>
i18n.translate('xpack.slo.editSloAlertswEmbeddable.typeDisplayName', {
defaultMessage: 'configuration',
}),
isEditingEnabled: () => true,
onEdit: async () => {
onEdit();
},
serializeState: () => {
return {
rawState: {
...titleManager.serialize(),
slos: slos$.getValue(),
showAllGroupByInstances: showAllGroupByInstances$.getValue(),
},
};
},
getSloAlertsConfig: () => {
return {
slos: slos$.getValue(),
showAllGroupByInstances: showAllGroupByInstances$.getValue(),
};
},
updateSloAlertsConfig: (update) => {
slos$.next(update.slos);
showAllGroupByInstances$.next(update.showAllGroupByInstances);
},
},
{
slos: [slos$, (value) => slos$.next(value)],
showAllGroupByInstances: [
showAllGroupByInstances$,
(value) => showAllGroupByInstances$.next(value),
],
...titleManager.comparators,
slos: [],
showAllGroupByInstances: false,
}
);
const defaultTitle$ = new BehaviorSubject<string | undefined>(getAlertsPanelTitle());
const reload$ = new Subject<FetchContext>();
function serializeState() {
return {
rawState: {
...titleManager.getLatestState(),
...sloAlertsStateManager.getLatestState(),
},
};
}
const unsavedChangesApi = initializeUnsavedChanges({
uuid,
parentApi,
serializeState,
anyStateChange$: merge(titleManager.anyStateChange$, sloAlertsStateManager.anyStateChange$),
getComparators: () => ({
...titleComparators,
slos: 'referenceEquality',
showAllGroupByInstances: 'referenceEquality',
}),
onReset: (lastSaved) => {
titleManager.reinitializeState(lastSaved?.rawState);
sloAlertsStateManager.reinitializeState(lastSaved?.rawState);
},
});
const api = finalizeApi({
...titleManager.api,
...unsavedChangesApi,
defaultTitle$,
getTypeDisplayName: () =>
i18n.translate('xpack.slo.editSloAlertswEmbeddable.typeDisplayName', {
defaultMessage: 'configuration',
}),
isEditingEnabled: () => true,
onEdit: async () => {
onEdit();
},
serializeState,
getSloAlertsConfig: () => {
return {
slos: sloAlertsStateManager.api.slos$.getValue(),
showAllGroupByInstances: sloAlertsStateManager.api.showAllGroupByInstances$.getValue(),
};
},
updateSloAlertsConfig: (update) => {
sloAlertsStateManager.api.setSlos(update.slos);
sloAlertsStateManager.api.setShowAllGroupByInstances(update.showAllGroupByInstances);
},
});
const fetchSubscription = fetch$(api)
.pipe()
@ -129,8 +139,8 @@ export function getAlertsEmbeddableFactory({
api,
Component: () => {
const [slos, showAllGroupByInstances] = useBatchedPublishingSubjects(
slos$,
showAllGroupByInstances$
sloAlertsStateManager.api.slos$,
sloAlertsStateManager.api.showAllGroupByInstances$
);
const fetchContext = useFetchContext(api);
const I18nContext = deps.i18n.Context;

View file

@ -42,7 +42,7 @@ export function createAddAlertsPanelAction(
embeddable.addNewPanel(
{
panelType: SLO_ALERTS_EMBEDDABLE_ID,
initialState,
serializedState: { rawState: initialState },
},
true
);