diff --git a/src/platform/plugins/shared/embeddable/public/react_embeddable_system/react_embeddable_renderer.tsx b/src/platform/plugins/shared/embeddable/public/react_embeddable_system/react_embeddable_renderer.tsx index 147a8a4c92a08..a97f2709b7fe8 100644 --- a/src/platform/plugins/shared/embeddable/public/react_embeddable_system/react_embeddable_renderer.tsx +++ b/src/platform/plugins/shared/embeddable/public/react_embeddable_system/react_embeddable_renderer.tsx @@ -15,6 +15,7 @@ import { v4 as generateId } from 'uuid'; import { PhaseTracker } from './phase_tracker'; import { getReactEmbeddableFactory } from './react_embeddable_registry'; import { DefaultEmbeddableApi, EmbeddableApiRegistration } from './types'; +import { getTransforms, hasTransforms } from '../transforms_registry'; /** * Renders a component from the React Embeddable registry into a Presentation Panel. @@ -63,6 +64,7 @@ export const EmbeddableRenderer = < const buildEmbeddable = async () => { const factory = await getReactEmbeddableFactory(type); + const transforms = hasTransforms(type) ? await getTransforms(type) : null; const finalizeApi = ( apiRegistration: EmbeddableApiRegistration @@ -84,8 +86,14 @@ export const EmbeddableRenderer = < const initialState = parentApi.getSerializedStateForChild(uuid) ?? { rawState: {} as SerializedState, }; + const transformedInitialState = + transforms?.transformOut?.(initialState.rawState, initialState.references) ?? + initialState.rawState; const { api, Component } = await factory.buildEmbeddable({ - initialState, + initialState: { + ...initialState, + rawState: transformedInitialState, + }, finalizeApi, uuid, parentApi, diff --git a/x-pack/platform/plugins/shared/lens/common/transforms/index.ts b/x-pack/platform/plugins/shared/lens/common/transforms/index.ts index f294802fed3ed..1ff8685ea5ca3 100644 --- a/x-pack/platform/plugins/shared/lens/common/transforms/index.ts +++ b/x-pack/platform/plugins/shared/lens/common/transforms/index.ts @@ -6,3 +6,4 @@ */ export { ConfigBuilderStub } from './config_builder_stub'; +export type * from './types'; diff --git a/x-pack/platform/plugins/shared/lens/common/transforms/transforms.ts b/x-pack/platform/plugins/shared/lens/common/transforms/transforms.ts new file mode 100644 index 0000000000000..6b978f1f1bd4d --- /dev/null +++ b/x-pack/platform/plugins/shared/lens/common/transforms/transforms.ts @@ -0,0 +1,33 @@ +/* + * 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 { EmbeddableTransforms } from '@kbn/embeddable-plugin/common'; + +import type { LensSerializedState } from '../../public'; +import { + LENS_ITEM_VERSION as LENS_ITEM_VERSION_V1, + transformToV1LensItemAttributes, +} from '../content_management/v1'; + +export const lensTransforms = { + transformOut(state: LensSerializedState): LensSerializedState { + // skip by-ref Lens panels + if (!state.attributes) return state; + + const version = state.attributes.version ?? 0; + const newState = { ...state }; + + if (version < LENS_ITEM_VERSION_V1) { + newState.attributes = transformToV1LensItemAttributes({ + ...state.attributes, + description: state.attributes.description ?? '', + }) as LensSerializedState['attributes']; + } + + return newState; + }, +} satisfies EmbeddableTransforms; diff --git a/x-pack/platform/plugins/shared/lens/common/transforms/types.ts b/x-pack/platform/plugins/shared/lens/common/transforms/types.ts new file mode 100644 index 0000000000000..4e453a092ee41 --- /dev/null +++ b/x-pack/platform/plugins/shared/lens/common/transforms/types.ts @@ -0,0 +1,19 @@ +/* + * 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 { LensItem as LensItemV1, LensAttributesV0 } from '../content_management/v1'; +import type { LensItem } from '../content_management'; + +/** + * Any of the versioned Lens Item + */ +export type VersionLensItem = LensItem | LensItemV1; + +/** + * Any of the versioned or unversioned Lens Item + */ +export type UnknownLensItem = LensAttributesV0 | VersionLensItem; diff --git a/x-pack/platform/plugins/shared/lens/public/plugin.ts b/x-pack/platform/plugins/shared/lens/public/plugin.ts index 5c21156216210..79647fc678f12 100644 --- a/x-pack/platform/plugins/shared/lens/public/plugin.ts +++ b/x-pack/platform/plugins/shared/lens/public/plugin.ts @@ -394,6 +394,11 @@ export class LensPlugin { return createLensEmbeddableFactory(deps); }); + embeddable.registerTransforms(LENS_EMBEDDABLE_TYPE, async () => { + const { lensTransforms } = await import('../common/transforms/transforms'); + return lensTransforms; + }); + // Let Dashboard know about the Lens panel type embeddable.registerAddFromLibraryType({ onAdd: async (container, savedObject) => { diff --git a/x-pack/platform/plugins/shared/lens/server/content_management/v1/index.ts b/x-pack/platform/plugins/shared/lens/server/content_management/v1/index.ts index c8bc1e21a4a6c..303206c709a42 100644 --- a/x-pack/platform/plugins/shared/lens/server/content_management/v1/index.ts +++ b/x-pack/platform/plugins/shared/lens/server/content_management/v1/index.ts @@ -7,6 +7,7 @@ export { LENS_ITEM_VERSION } from './constants'; +export * from './transforms'; export * from './service'; export * from './schema'; export type * from './types'; diff --git a/x-pack/platform/plugins/shared/lens/server/plugin.tsx b/x-pack/platform/plugins/shared/lens/server/plugin.tsx index 531908caa722f..76a1fa1fba39f 100644 --- a/x-pack/platform/plugins/shared/lens/server/plugin.tsx +++ b/x-pack/platform/plugins/shared/lens/server/plugin.tsx @@ -31,6 +31,8 @@ import { LensAppLocatorDefinition } from '../common/locator/locator'; import { LENS_CONTENT_TYPE, LENS_ITEM_LATEST_VERSION } from '../common/constants'; import { LensStorage } from './content_management'; import { registerLensAPIRoutes } from './api/routes'; +import { lensTransforms } from '../common/transforms/transforms'; +import { LENS_EMBEDDABLE_TYPE } from '../common/constants'; export interface PluginSetupContract { taskManager?: TaskManagerSetupContract; @@ -100,6 +102,7 @@ export class LensServerPlugin this.customVisualizationMigrations ); plugins.embeddable.registerEmbeddableFactory(lensEmbeddableFactory()); + plugins.embeddable.registerTransforms(LENS_EMBEDDABLE_TYPE, lensTransforms); registerLensAPIRoutes({ http: core.http,