convert traces embeddable to serialized state only (#218667)

This commit is contained in:
Nathan Reese 2025-04-18 12:17:08 -06:00 committed by GitHub
parent d5e57af9ab
commit 6deb95d780
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 77 additions and 38 deletions

View file

@ -8,7 +8,7 @@
*/
import React, { useCallback } from 'react';
import { ReactEmbeddableRenderer } from '@kbn/embeddable-plugin/public';
import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public';
import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiTitle } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { spanTraceFields } from '../doc_viewer_span_overview/resources/fields';
@ -86,7 +86,7 @@ export const Trace = ({
<EuiFlexItem>{fieldRows}</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
<ReactEmbeddableRenderer
<EmbeddableRenderer
type="APM_TRACE_WATERFALL_EMBEDDABLE"
getParentApi={getParentApi}
hidePanelChrome={true}

View file

@ -4,12 +4,17 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { DefaultEmbeddableApi, ReactEmbeddableFactory } from '@kbn/embeddable-plugin/public';
import type { DefaultEmbeddableApi, EmbeddableFactory } from '@kbn/embeddable-plugin/public';
import type { SerializedTitles } from '@kbn/presentation-publishing';
import { initializeTitleManager, useBatchedPublishingSubjects } from '@kbn/presentation-publishing';
import {
initializeTitleManager,
titleComparators,
useBatchedPublishingSubjects,
} from '@kbn/presentation-publishing';
import React from 'react';
import { BehaviorSubject } from 'rxjs';
import { BehaviorSubject, map, merge } from 'rxjs';
import { isEmpty } from 'lodash';
import { initializeUnsavedChanges } from '@kbn/presentation-containers';
import { ApmEmbeddableContext } from '../embeddable_context';
import type { EmbeddableDeps } from '../types';
import { APM_TRACE_WATERFALL_EMBEDDABLE } from './constant';
@ -37,16 +42,13 @@ export type ApmTraceWaterfallEmbeddableProps =
| ApmTraceWaterfallEmbeddableEntryProps;
export const getApmTraceWaterfallEmbeddableFactory = (deps: EmbeddableDeps) => {
const factory: ReactEmbeddableFactory<
ApmTraceWaterfallEmbeddableProps,
const factory: EmbeddableFactory<
ApmTraceWaterfallEmbeddableProps,
DefaultEmbeddableApi<ApmTraceWaterfallEmbeddableProps>
> = {
type: APM_TRACE_WATERFALL_EMBEDDABLE,
deserializeState: (state) => {
return state.rawState as ApmTraceWaterfallEmbeddableProps;
},
buildEmbeddable: async (state, buildApi, uuid, parentApi) => {
buildEmbeddable: async ({ initialState, finalizeApi, uuid, parentApi }) => {
const state = initialState.rawState;
const titleManager = initializeTitleManager(state);
const serviceName$ = new BehaviorSubject('serviceName' in state ? state.serviceName : '');
const traceId$ = new BehaviorSubject(state.traceId);
@ -58,35 +60,72 @@ export const getApmTraceWaterfallEmbeddableFactory = (deps: EmbeddableDeps) => {
const displayLimit$ = new BehaviorSubject('displayLimit' in state ? state.displayLimit : 0);
const docId$ = new BehaviorSubject('docId' in state ? state.docId : '');
const api = buildApi(
{
...titleManager.api,
serializeState: () => {
return {
rawState: {
...titleManager.serialize(),
serviceName: serviceName$.getValue(),
traceId: traceId$.getValue(),
entryTransactionId: entryTransactionId$.getValue(),
rangeFrom: rangeFrom$.getValue(),
rangeTo: rangeTo$.getValue(),
displayLimit: displayLimit$.getValue(),
docId: docId$.getValue(),
},
};
function serializeState() {
return {
rawState: {
...titleManager.getLatestState(),
serviceName: serviceName$.getValue(),
traceId: traceId$.getValue(),
entryTransactionId: entryTransactionId$.getValue(),
rangeFrom: rangeFrom$.getValue(),
rangeTo: rangeTo$.getValue(),
displayLimit: displayLimit$.getValue(),
docId: docId$.getValue(),
},
};
}
const unsavedChangesApi = initializeUnsavedChanges<ApmTraceWaterfallEmbeddableProps>({
uuid,
parentApi,
serializeState,
anyStateChange$: merge(
titleManager.anyStateChange$,
serviceName$,
traceId$,
entryTransactionId$,
rangeFrom$,
rangeTo$,
displayLimit$,
docId$
).pipe(map(() => undefined)),
getComparators: () => {
return {
...titleComparators,
serviceName: 'referenceEquality',
traceId: 'referenceEquality',
entryTransactionId: 'referenceEquality',
rangeFrom: 'referenceEquality',
rangeTo: 'referenceEquality',
displayLimit: 'referenceEquality',
docId: 'referenceEquality',
};
},
{
...titleManager.comparators,
serviceName: [serviceName$, (value) => serviceName$.next(value)],
traceId: [traceId$, (value) => traceId$.next(value)],
entryTransactionId: [entryTransactionId$, (value) => entryTransactionId$.next(value)],
rangeFrom: [rangeFrom$, (value) => rangeFrom$.next(value)],
rangeTo: [rangeTo$, (value) => rangeFrom$.next(value)],
displayLimit: [displayLimit$, (value) => displayLimit$.next(value)],
docId: [docId$, (value) => docId$.next(value)],
}
);
onReset: (lastSaved) => {
titleManager.reinitializeState(lastSaved?.rawState);
// reset base state
traceId$.next(lastSaved?.rawState.traceId ?? '');
rangeFrom$.next(lastSaved?.rawState.rangeFrom ?? '');
rangeFrom$.next(lastSaved?.rawState.rangeTo ?? '');
// reset entry state
const entryState = lastSaved?.rawState as ApmTraceWaterfallEmbeddableEntryProps;
serviceName$.next(entryState?.serviceName ?? '');
entryTransactionId$.next(entryState?.entryTransactionId ?? '');
displayLimit$.next(entryState?.displayLimit ?? 0);
// reset focused state
const focusedState = lastSaved?.rawState as ApmTraceWaterfallEmbeddableFocusedProps;
docId$.next(focusedState?.docId ?? '');
},
});
const api = finalizeApi({
...unsavedChangesApi,
...titleManager.api,
serializeState,
});
return {
api,