diff --git a/src/platform/packages/shared/kbn-lens-common/embeddable/constants.ts b/src/platform/packages/shared/kbn-lens-common/embeddable/constants.ts new file mode 100644 index 0000000000000..fd30601847fb1 --- /dev/null +++ b/src/platform/packages/shared/kbn-lens-common/embeddable/constants.ts @@ -0,0 +1,10 @@ +/* + * 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +export const LENS_EMBEDDABLE_TYPE = 'vis'; diff --git a/src/platform/packages/shared/kbn-lens-common/index.ts b/src/platform/packages/shared/kbn-lens-common/index.ts index 0588c65b67fce..c7a5574c5b05e 100644 --- a/src/platform/packages/shared/kbn-lens-common/index.ts +++ b/src/platform/packages/shared/kbn-lens-common/index.ts @@ -415,3 +415,4 @@ export { export { DRAG_DROP_EXTRA_TARGETS_WIDTH, DRAG_DROP_EXTRA_TARGETS_PADDING } from './editor/constants'; export { LENS_DATASOURCE_ID } from './embeddable/types'; export type { LensDatasourceId } from './embeddable/types'; +export { LENS_EMBEDDABLE_TYPE } from './embeddable/constants'; diff --git a/src/platform/packages/shared/kbn-visualizations-common/constants.ts b/src/platform/packages/shared/kbn-visualizations-common/constants.ts index 08ed51c089328..3ae106c0e6e24 100644 --- a/src/platform/packages/shared/kbn-visualizations-common/constants.ts +++ b/src/platform/packages/shared/kbn-visualizations-common/constants.ts @@ -10,7 +10,7 @@ export const VISUALIZE_APP_NAME = 'visualize'; export const SAVED_OBJECTS_LIMIT_SETTING = 'savedObjects:listingLimit'; export const SAVED_OBJECTS_PER_PAGE_SETTING = 'savedObjects:perPage'; -export const VISUALIZE_EMBEDDABLE_TYPE = 'visualization'; +export const VISUALIZE_EMBEDDABLE_TYPE = 'legacy_vis'; export const VISUALIZE_SAVED_OBJECT_TYPE = 'visualization'; export const STATE_STORAGE_KEY = '_a'; diff --git a/src/platform/plugins/shared/dashboard/moon.yml b/src/platform/plugins/shared/dashboard/moon.yml index 4941b54a783dd..1f6a98d029ef2 100644 --- a/src/platform/plugins/shared/dashboard/moon.yml +++ b/src/platform/plugins/shared/dashboard/moon.yml @@ -125,6 +125,7 @@ dependsOn: - '@kbn/core-http-common' - '@kbn/core-http-server-mocks' - '@kbn/core-http-browser' + - '@kbn/lens-common' tags: - plugin - prod diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_app/hooks/use_observability_ai_assistant_context.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_app/hooks/use_observability_ai_assistant_context.tsx index 71e24a4f2ee26..7d1bfbbbd8bb6 100644 --- a/src/platform/plugins/shared/dashboard/public/dashboard_app/hooks/use_observability_ai_assistant_context.tsx +++ b/src/platform/plugins/shared/dashboard/public/dashboard_app/hooks/use_observability_ai_assistant_context.tsx @@ -25,6 +25,7 @@ import { } from '@kbn/lens-embeddable-utils/config_builder'; import type { LensEmbeddableInput } from '@kbn/lens-plugin/public'; import { useEffect } from 'react'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import type { DashboardApi } from '../../dashboard_api/types'; import { dataService, observabilityAssistantService } from '../../services/kibana_services'; @@ -357,7 +358,7 @@ export function useObservabilityAIAssistantContext({ return dashboardApi .addNewPanel({ - panelType: 'lens', + panelType: LENS_EMBEDDABLE_TYPE, serializedState: { embeddableInput, }, diff --git a/src/platform/plugins/shared/dashboard/public/dashboard_app/no_data/dashboard_app_no_data.tsx b/src/platform/plugins/shared/dashboard/public/dashboard_app/no_data/dashboard_app_no_data.tsx index 5626ae8e7ebb3..ba4d54e34712a 100644 --- a/src/platform/plugins/shared/dashboard/public/dashboard_app/no_data/dashboard_app_no_data.tsx +++ b/src/platform/plugins/shared/dashboard/public/dashboard_app/no_data/dashboard_app_no_data.tsx @@ -20,6 +20,7 @@ import { withSuspense } from '@kbn/shared-ux-utility'; import type { LensSerializedState } from '@kbn/lens-plugin/public'; import { getLensAttributesFromSuggestion } from '@kbn/visualization-utils'; import { AbortReason } from '@kbn/kibana-utils-plugin/common'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import { coreServices, dataService, @@ -103,7 +104,7 @@ export const DashboardAppNoDataPage = ({ .navigateToWithEmbeddablePackages('dashboards', { state: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, serializedState: { attributes: getLensAttributesFromSuggestion({ filters: [], diff --git a/src/platform/plugins/shared/dashboard/server/api/transforms/in/transform_panels_in.ts b/src/platform/plugins/shared/dashboard/server/api/transforms/in/transform_panels_in.ts index 648e3d3ab692c..f3d74c5acc76e 100644 --- a/src/platform/plugins/shared/dashboard/server/api/transforms/in/transform_panels_in.ts +++ b/src/platform/plugins/shared/dashboard/server/api/transforms/in/transform_panels_in.ts @@ -10,6 +10,7 @@ import { v4 as uuidv4 } from 'uuid'; import type { SavedObjectReference } from '@kbn/core/server'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import { isDashboardSection, prefixReferencesFromPanel } from '../../../../common'; import type { DashboardSavedObjectAttributes, @@ -84,7 +85,9 @@ function transformPanelIn( // Temporary escape hatch for lens as code // TODO remove when lens as code transforms are ready for production const transformType = - panel.type === 'lens' && isDashboardAppRequest ? 'lens-dashboard-app' : panel.type; + panel.type === LENS_EMBEDDABLE_TYPE && isDashboardAppRequest + ? 'lens-dashboard-app' + : panel.type; const transforms = embeddableService?.getTransforms(transformType); // Dashboard application routes do not validate panel.config at route level diff --git a/src/platform/plugins/shared/dashboard/server/api/transforms/out/transform_panels_out.ts b/src/platform/plugins/shared/dashboard/server/api/transforms/out/transform_panels_out.ts index 8382089913e87..e6ae29c6e1f27 100644 --- a/src/platform/plugins/shared/dashboard/server/api/transforms/out/transform_panels_out.ts +++ b/src/platform/plugins/shared/dashboard/server/api/transforms/out/transform_panels_out.ts @@ -10,6 +10,7 @@ import type { SavedObjectReference } from '@kbn/core/server'; import { transformTimeRangeOut, transformTitlesOut } from '@kbn/presentation-publishing'; import { flow } from 'lodash'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import type { SavedDashboardPanel, SavedDashboardSection } from '../../../dashboard_saved_object'; import type { DashboardState, DashboardPanel, DashboardSection } from '../../types'; import { embeddableService } from '../../../kibana_services'; @@ -101,7 +102,8 @@ function transformPanel( // Temporary escape hatch for lens as code // TODO remove when lens as code transforms are ready for production - const transformType = type === 'lens' && isDashboardAppRequest ? 'lens-dashboard-app' : type; + const transformType = + type === LENS_EMBEDDABLE_TYPE && isDashboardAppRequest ? 'lens-dashboard-app' : type; const transforms = embeddableService?.getTransforms(transformType); const transformedPanelConfig = diff --git a/src/platform/plugins/shared/dashboard/tsconfig.json b/src/platform/plugins/shared/dashboard/tsconfig.json index 2f5d316ff054d..4525789f59648 100644 --- a/src/platform/plugins/shared/dashboard/tsconfig.json +++ b/src/platform/plugins/shared/dashboard/tsconfig.json @@ -123,6 +123,7 @@ "@kbn/core-http-common", "@kbn/core-http-server-mocks", "@kbn/core-http-browser", + "@kbn/lens-common" ], "exclude": ["target/**/*"] } diff --git a/src/platform/plugins/shared/embeddable/common/bwc/transform_type.ts b/src/platform/plugins/shared/embeddable/common/bwc/transform_type.ts index df3549a3538b7..166c2129e346f 100644 --- a/src/platform/plugins/shared/embeddable/common/bwc/transform_type.ts +++ b/src/platform/plugins/shared/embeddable/common/bwc/transform_type.ts @@ -8,6 +8,14 @@ */ export function transformType(type: string) { + if (type === 'lens') { + return 'vis'; + } + + if (type === 'visualization') { + return 'legacy_vis'; + } + if (type === 'DASHBOARD_MARKDOWN') { return 'markdown'; } diff --git a/src/platform/plugins/shared/unified_doc_viewer/moon.yml b/src/platform/plugins/shared/unified_doc_viewer/moon.yml index e9432bb3937d8..008487a547356 100644 --- a/src/platform/plugins/shared/unified_doc_viewer/moon.yml +++ b/src/platform/plugins/shared/unified_doc_viewer/moon.yml @@ -63,6 +63,7 @@ dependsOn: - '@kbn/deeplinks-analytics' - '@kbn/lens-embeddable-utils' - '@kbn/restorable-state' + - '@kbn/lens-common' tags: - plugin - prod diff --git a/src/platform/plugins/shared/unified_doc_viewer/public/components/doc_viewer_logs_overview/sub_components/similar_errors/similar_errors_occurrences_chart/index.tsx b/src/platform/plugins/shared/unified_doc_viewer/public/components/doc_viewer_logs_overview/sub_components/similar_errors/similar_errors_occurrences_chart/index.tsx index ebeae9ba2efb3..d42b278699d24 100644 --- a/src/platform/plugins/shared/unified_doc_viewer/public/components/doc_viewer_logs_overview/sub_components/similar_errors/similar_errors_occurrences_chart/index.tsx +++ b/src/platform/plugins/shared/unified_doc_viewer/public/components/doc_viewer_logs_overview/sub_components/similar_errors/similar_errors_occurrences_chart/index.tsx @@ -20,6 +20,7 @@ import type { LensAttributes } from '@kbn/lens-embeddable-utils/config_builder'; import { EuiCallOut, EuiLoadingChart, EuiFlexGroup, EuiFlexItem, useEuiTheme } from '@elastic/eui'; import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public'; import { fieldConstants } from '@kbn/discover-utils'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import { useDataSourcesContext } from '../../../../../hooks/use_data_sources'; import { getUnifiedDocViewerServices } from '../../../../../plugin'; import { ContentFrameworkChart } from '../../../../content_framework/chart'; @@ -196,9 +197,11 @@ export function SimilarErrorsOccurrencesChart({ return (
- {/* TODO update the string with LENS_EMBEDDABLE_TYPE once is moved to @kbn/lens-common - https://github.com/elastic/kibana/issues/245192 */} - +
); }, [getParentApi, lensAttributes]); diff --git a/src/platform/plugins/shared/unified_doc_viewer/public/components/doc_viewer_logs_overview/sub_components/similar_errors/similar_errors_occurrences_chart/similar_errors_occurrences_chart.test.tsx b/src/platform/plugins/shared/unified_doc_viewer/public/components/doc_viewer_logs_overview/sub_components/similar_errors/similar_errors_occurrences_chart/similar_errors_occurrences_chart.test.tsx index 1e24b96a33205..614cf7b096ab7 100644 --- a/src/platform/plugins/shared/unified_doc_viewer/public/components/doc_viewer_logs_overview/sub_components/similar_errors/similar_errors_occurrences_chart/similar_errors_occurrences_chart.test.tsx +++ b/src/platform/plugins/shared/unified_doc_viewer/public/components/doc_viewer_logs_overview/sub_components/similar_errors/similar_errors_occurrences_chart/similar_errors_occurrences_chart.test.tsx @@ -126,7 +126,7 @@ describe('SimilarErrorsOccurrencesChart', () => { expect(screen.getByTestId('lensEmbeddableSimilarErrorsChart')).toBeInTheDocument(); }); - expect(screen.getByText('Lens Chart (type: lens)')).toBeInTheDocument(); + expect(screen.getByText('Lens Chart (type: vis)')).toBeInTheDocument(); }); it('shows error message when build fails', async () => { diff --git a/src/platform/plugins/shared/unified_doc_viewer/tsconfig.json b/src/platform/plugins/shared/unified_doc_viewer/tsconfig.json index 9532fa9268922..0e53345dc02d5 100644 --- a/src/platform/plugins/shared/unified_doc_viewer/tsconfig.json +++ b/src/platform/plugins/shared/unified_doc_viewer/tsconfig.json @@ -58,6 +58,7 @@ "@kbn/deeplinks-analytics", "@kbn/lens-embeddable-utils", "@kbn/restorable-state", + "@kbn/lens-common", ], "exclude": ["target/**/*"] } diff --git a/src/platform/plugins/shared/visualizations/public/actions/edit_in_lens_action.tsx b/src/platform/plugins/shared/visualizations/public/actions/edit_in_lens_action.tsx index 635a1c74ed3f3..143136e4770b0 100644 --- a/src/platform/plugins/shared/visualizations/public/actions/edit_in_lens_action.tsx +++ b/src/platform/plugins/shared/visualizations/public/actions/edit_in_lens_action.tsx @@ -32,8 +32,6 @@ import { apiHasVisualizeConfig, type HasVisualizeConfig, } from '../embeddable/interfaces/has_visualize_config'; -import type { HasExpressionVariables } from '../embeddable/interfaces/has_expression_variables'; -import { apiHasExpressionVariables } from '../embeddable/interfaces/has_expression_variables'; import { getApplication, getCapabilities, @@ -65,7 +63,7 @@ const MenuItem: React.FC = () => { type EditInLensActionApi = HasUniqueId & HasVisualizeConfig & CanAccessViewMode & - Partial; + Partial; const compatibilityCheck = (api: EmbeddableApiContext['embeddable']): api is EditInLensActionApi => apiHasUniqueId(api) && apiCanAccessViewMode(api) && apiHasVisualizeConfig(api); @@ -150,10 +148,7 @@ export class EditInLensAction implements Action { } // determine whether navigation to lens is available - if ( - apiHasExpressionVariables(embeddable) && - embeddable.getExpressionVariables()?.canNavigateToLens - ) { + if (embeddable.getExpressionVariables?.()?.canNavigateToLens) { return true; } return Boolean(await vis.type.navigateToLens?.(vis, this.timefilter)); diff --git a/src/platform/plugins/shared/visualizations/public/embeddable/embeddable_module.ts b/src/platform/plugins/shared/visualizations/public/embeddable/embeddable_module.ts index 84073fb4f65dc..ddf52b272a845 100644 --- a/src/platform/plugins/shared/visualizations/public/embeddable/embeddable_module.ts +++ b/src/platform/plugins/shared/visualizations/public/embeddable/embeddable_module.ts @@ -8,4 +8,4 @@ */ export { getTransformOut } from '../../common/embeddable/transforms/get_transform_out'; -export { getVisualizeEmbeddableFactory } from './visualize_embeddable'; +export { visualizeEmbeddableFactory } from './visualize_embeddable'; diff --git a/src/platform/plugins/shared/visualizations/public/embeddable/interfaces/has_expression_variables.ts b/src/platform/plugins/shared/visualizations/public/embeddable/interfaces/has_expression_variables.ts deleted file mode 100644 index 3555d6688edc2..0000000000000 --- a/src/platform/plugins/shared/visualizations/public/embeddable/interfaces/has_expression_variables.ts +++ /dev/null @@ -1,30 +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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public - * License v3.0 only", or the "Server Side Public License, v 1". - */ - -import { type HasType, apiIsOfType } from '@kbn/presentation-publishing'; -import type { Observable } from 'rxjs'; - -type ExpressionVariables = Record | undefined; - -export type HasExpressionVariables = HasType<'visualization'> & { - getExpressionVariables: () => ExpressionVariables; - getExpressionVariables$: () => Observable; -}; - -export const apiHasExpressionVariables = (api: unknown): api is HasExpressionVariables => { - const maybeHasExpressionVariables = api as HasExpressionVariables; - return Boolean( - api && - apiIsOfType(api, 'visualization') && - maybeHasExpressionVariables.getExpressionVariables && - typeof maybeHasExpressionVariables.getExpressionVariables === 'function' && - maybeHasExpressionVariables.getExpressionVariables$ && - typeof maybeHasExpressionVariables.getExpressionVariables$ === 'function' - ); -}; diff --git a/src/platform/plugins/shared/visualizations/public/embeddable/interfaces/has_visualize_config.ts b/src/platform/plugins/shared/visualizations/public/embeddable/interfaces/has_visualize_config.ts index e82f49b87d5e5..755c7cfd159e8 100644 --- a/src/platform/plugins/shared/visualizations/public/embeddable/interfaces/has_visualize_config.ts +++ b/src/platform/plugins/shared/visualizations/public/embeddable/interfaces/has_visualize_config.ts @@ -8,17 +8,19 @@ */ import type { HasType } from '@kbn/presentation-publishing'; +import { VISUALIZE_EMBEDDABLE_TYPE } from '@kbn/visualizations-common'; import type { VisParams } from '../../types'; import type Vis from '../../vis'; -export type HasVisualizeConfig = HasType<'visualization'> & { +export type HasVisualizeConfig = HasType & { getVis: () => Vis; + getExpressionVariables?: () => Record | undefined; }; export const apiHasVisualizeConfig = (api: unknown): api is HasVisualizeConfig => { return Boolean( api && - (api as HasType)?.type === 'visualization' && + (api as HasType)?.type === VISUALIZE_EMBEDDABLE_TYPE && typeof (api as HasVisualizeConfig).getVis === 'function' ); }; diff --git a/src/platform/plugins/shared/visualizations/public/embeddable/visualize_embeddable.tsx b/src/platform/plugins/shared/visualizations/public/embeddable/visualize_embeddable.tsx index bbfd26651b70a..3ff346bfcb80a 100644 --- a/src/platform/plugins/shared/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/platform/plugins/shared/visualizations/public/embeddable/visualize_embeddable.tsx @@ -10,7 +10,7 @@ import { EuiEmptyPrompt, EuiFlexGroup, EuiLoadingChart, EuiText } from '@elastic/eui'; import { isChartSizeEvent } from '@kbn/chart-expressions-common'; import type { DataView } from '@kbn/data-views-plugin/public'; -import type { EmbeddableStart, EmbeddableFactory } from '@kbn/embeddable-plugin/public'; +import type { EmbeddableFactory } from '@kbn/embeddable-plugin/public'; import type { ExpressionRendererParams } from '@kbn/expressions-plugin/public'; import { useExpressionRenderer } from '@kbn/expressions-plugin/public'; import { i18n } from '@kbn/i18n'; @@ -57,495 +57,500 @@ import type { VisualizeApi } from './types'; import { initializeEditApi } from './initialize_edit_api'; import { checkForDuplicateTitle } from '../utils/saved_objects_utils'; -export const getVisualizeEmbeddableFactory: (deps: { - embeddableStart: EmbeddableStart; -}) => EmbeddableFactory = ({ embeddableStart }) => ({ - type: VISUALIZE_EMBEDDABLE_TYPE, - buildEmbeddable: async ({ - initializeDrilldownsManager, - initialState, - finalizeApi, - parentApi, - uuid, - }) => { - // Runtime state may contain title loaded from saved object - // Initialize titleManager with serialized state - // to avoid tracking runtime state title as serialized state title - const titleManager = initializeTitleManager(initialState); - - // Initialize dynamic actions - const drilldownsManager = await initializeDrilldownsManager(uuid, initialState); - - const runtimeState = await deserializeState(initialState); - - // Count renders; mostly used for testing. - const renderCount$ = new BehaviorSubject(0); - const hasRendered$ = new BehaviorSubject(false); - - // Track vis data and initialize it into a vis instance - const serializedVis$ = new BehaviorSubject(runtimeState.serializedVis); - const initialVisInstance = await createVisInstance(runtimeState.serializedVis); - const vis$ = new BehaviorSubject(initialVisInstance); - - let initialProjectRoutingOverrides: ProjectRoutingOverrides; - if (initialVisInstance.type.getProjectRoutingOverrides) { - initialProjectRoutingOverrides = await initialVisInstance.type.getProjectRoutingOverrides( - initialVisInstance.params +export const visualizeEmbeddableFactory: EmbeddableFactory = + { + type: VISUALIZE_EMBEDDABLE_TYPE, + buildEmbeddable: async ({ + initializeDrilldownsManager, + initialState, + finalizeApi, + parentApi, + uuid, + }) => { + // Runtime state may contain title loaded from saved object + // Initialize titleManager with serialized state + // to avoid tracking runtime state title as serialized state title + const titleManager = initializeTitleManager(initialState); + + // Initialize dynamic actions + const drilldownsManager = await initializeDrilldownsManager(uuid, initialState); + + const runtimeState = await deserializeState(initialState); + + // Count renders; mostly used for testing. + const renderCount$ = new BehaviorSubject(0); + const hasRendered$ = new BehaviorSubject(false); + + // Track vis data and initialize it into a vis instance + const serializedVis$ = new BehaviorSubject(runtimeState.serializedVis); + const initialVisInstance = await createVisInstance(runtimeState.serializedVis); + const vis$ = new BehaviorSubject(initialVisInstance); + + let initialProjectRoutingOverrides: ProjectRoutingOverrides; + if (initialVisInstance.type.getProjectRoutingOverrides) { + initialProjectRoutingOverrides = await initialVisInstance.type.getProjectRoutingOverrides( + initialVisInstance.params + ); + } + const projectRoutingOverrides$ = new BehaviorSubject( + initialProjectRoutingOverrides ); - } - const projectRoutingOverrides$ = new BehaviorSubject( - initialProjectRoutingOverrides - ); - - // Track UI state - const onUiStateChange = () => serializedVis$.next(vis$.getValue().serialize()); - - // When the serialized vis changes, update the vis instance - const serializedVisSubscription = serializedVis$ - .pipe( - switchMap(async (serializedVis) => { - const currentVis = vis$.getValue(); - if (currentVis) currentVis.uiState.off('change', onUiStateChange); - const vis = await createVisInstance(serializedVis); - vis.uiState.on('change', onUiStateChange); - vis$.next(vis); - - // Update project routing overrides when vis changes - if (vis.type.getProjectRoutingOverrides) { - const newOverrides = await vis.type.getProjectRoutingOverrides(vis.params); - if (!isEqual(projectRoutingOverrides$.getValue(), newOverrides)) { - projectRoutingOverrides$.next(newOverrides); + + // Track UI state + const onUiStateChange = () => serializedVis$.next(vis$.getValue().serialize()); + + // When the serialized vis changes, update the vis instance + const serializedVisSubscription = serializedVis$ + .pipe( + switchMap(async (serializedVis) => { + const currentVis = vis$.getValue(); + if (currentVis) currentVis.uiState.off('change', onUiStateChange); + const vis = await createVisInstance(serializedVis); + vis.uiState.on('change', onUiStateChange); + vis$.next(vis); + + // Update project routing overrides when vis changes + if (vis.type.getProjectRoutingOverrides) { + const newOverrides = await vis.type.getProjectRoutingOverrides(vis.params); + if (!isEqual(projectRoutingOverrides$.getValue(), newOverrides)) { + projectRoutingOverrides$.next(newOverrides); + } } - } - const { params, abortController } = await getExpressionParams(); - return { params, abortController }; - }) - ) - .subscribe(({ params, abortController }) => { - if (params) expressionParams$.next(params); - expressionAbortController$.next(abortController); - }); + const { params, abortController } = await getExpressionParams(); + return { params, abortController }; + }) + ) + .subscribe(({ params, abortController }) => { + if (params) expressionParams$.next(params); + expressionAbortController$.next(abortController); + }); - // Track visualizations linked to a saved object in the library - const savedObjectId$ = new BehaviorSubject( - runtimeState.savedObjectId ?? runtimeState.serializedVis.id - ); - const linkedToLibrary = Boolean(runtimeState.savedObjectId); + // Track visualizations linked to a saved object in the library + const savedObjectId$ = new BehaviorSubject( + runtimeState.savedObjectId ?? runtimeState.serializedVis.id + ); + const linkedToLibrary = Boolean(runtimeState.savedObjectId); - // Track the vis expression - const expressionParams$ = new BehaviorSubject({ - expression: '', - }); + // Track the vis expression + const expressionParams$ = new BehaviorSubject({ + expression: '', + }); - const expressionAbortController$ = new BehaviorSubject(new AbortController()); - let getExpressionParams: () => ReturnType = async () => ({ - params: expressionParams$.getValue(), - abortController: expressionAbortController$.getValue(), - }); + const expressionAbortController$ = new BehaviorSubject( + new AbortController() + ); + let getExpressionParams: () => ReturnType = async () => ({ + params: expressionParams$.getValue(), + abortController: expressionAbortController$.getValue(), + }); - const timeRangeManager = initializeTimeRangeManager(runtimeState); + const timeRangeManager = initializeTimeRangeManager(runtimeState); - const searchSessionId$ = new BehaviorSubject(''); + const searchSessionId$ = new BehaviorSubject(''); - const executionContext = apiHasExecutionContext(parentApi) - ? parentApi.executionContext - : undefined; + const executionContext = apiHasExecutionContext(parentApi) + ? parentApi.executionContext + : undefined; - const disableTriggers = apiHasDisableTriggers(parentApi) - ? parentApi.disableTriggers - : undefined; + const disableTriggers = apiHasDisableTriggers(parentApi) + ? parentApi.disableTriggers + : undefined; - const inspectorAdapters$ = new BehaviorSubject>({}); + const inspectorAdapters$ = new BehaviorSubject>({}); - // Track data views - let initialDataViews: DataView[] | undefined = []; - if (initialVisInstance.data.indexPattern) - initialDataViews = [initialVisInstance.data.indexPattern]; - if (initialVisInstance.type.getUsedIndexPattern) { - initialDataViews = await initialVisInstance.type.getUsedIndexPattern( - initialVisInstance.params - ); - } - - const dataLoading$ = new BehaviorSubject(true); - - const defaultTitle$ = new BehaviorSubject(initialVisInstance.title); - - const serializeVisualizeEmbeddable = ( - savedObjectId: string | undefined, - linkedToLibraryArg: boolean - ) => { - return serializeState({ - serializedVis: vis$.getValue().serialize(), - titles: titleManager.getLatestState(), - id: savedObjectId, - linkedToLibrary: linkedToLibraryArg, - ...(runtimeState.savedObjectProperties - ? { savedObjectProperties: runtimeState.savedObjectProperties } - : {}), - drilldowns: drilldownsManager.getLatestState(), - ...timeRangeManager.getLatestState(), - }); - }; + // Track data views + let initialDataViews: DataView[] | undefined = []; + if (initialVisInstance.data.indexPattern) + initialDataViews = [initialVisInstance.data.indexPattern]; + if (initialVisInstance.type.getUsedIndexPattern) { + initialDataViews = await initialVisInstance.type.getUsedIndexPattern( + initialVisInstance.params + ); + } - const unsavedChangesApi = initializeUnsavedChanges({ - uuid, - parentApi, - serializeState: () => { - return serializeVisualizeEmbeddable(savedObjectId$.getValue(), linkedToLibrary); - }, - anyStateChange$: merge( - drilldownsManager.anyStateChange$, - savedObjectId$, - serializedVis$, - titleManager.anyStateChange$, - timeRangeManager.anyStateChange$ - ).pipe(map(() => undefined)), - getComparators: () => { - return { - ...drilldownsManager.comparators, - ...titleComparators, - ...timeRangeComparators, - savedObjectId: 'skip', - uiState: linkedToLibrary ? 'deepEquality' : 'skip', - savedVis: linkedToLibrary - ? 'skip' - : (a, b) => { - function deepOmitBy(value: any) { - if (value && !Array.isArray(value) && typeof value === 'object') { - const keys = Object.keys(value); - if (!keys.length) return; - - const cleanedValue: Record = {}; - keys.forEach((key) => { - const cleanedSubvalue = deepOmitBy(value[key]); - if (cleanedSubvalue) { - cleanedValue[key] = cleanedSubvalue; - } - }); - return cleanedValue; - } + const dataLoading$ = new BehaviorSubject(true); - return value; - } + const defaultTitle$ = new BehaviorSubject(initialVisInstance.title); - return isEqual(deepOmitBy(a), deepOmitBy(b)); - }, - }; - }, - onReset: async (lastSaved) => { - drilldownsManager.reinitializeState(lastSaved ?? {}); - timeRangeManager.reinitializeState(lastSaved); - titleManager.reinitializeState(lastSaved); - - if (!lastSaved) return; - const lastSavedRuntimeState = await deserializeState(lastSaved); - serializedVis$.next(lastSavedRuntimeState.serializedVis); - }, - }); - - const api = finalizeApi({ - ...timeRangeManager.api, - ...titleManager.api, - ...drilldownsManager.api, - ...unsavedChangesApi, - defaultTitle$, - dataLoading$, - dataViews$: new BehaviorSubject(initialDataViews), - projectRoutingOverrides$, - rendered$: hasRendered$, - supportedTriggers: () => [ - ON_OPEN_PANEL_MENU, - ACTION_CONVERT_TO_LENS, - ON_APPLY_FILTER, - ON_SELECT_RANGE, - ], - serializeState: () => { - // In the visualize editor, linkedToLibrary should always be false to force the full state to be serialized, - // instead of just passing a reference to the linked saved object. Other contexts like dashboards should - // serialize the state with just the savedObjectId so that the current revision of the vis is always used - const forcedLinkedToLibrary = apiIsOfType(parentApi, VISUALIZE_APP_NAME) - ? false - : linkedToLibrary; - return serializeVisualizeEmbeddable(savedObjectId$.getValue(), forcedLinkedToLibrary); - }, - getVis: () => vis$.getValue(), - getInspectorAdapters: () => inspectorAdapters$.getValue(), - ...initializeEditApi({ - customTimeRange$: timeRangeManager.api.timeRange$, - description$: titleManager.api.description$, - parentApi, - savedObjectId$, - searchSessionId$, - title$: titleManager.api.title$, - vis$, - uuid, - }), - updateVis: async (visUpdates) => { - const currentSerializedVis = vis$.getValue().serialize(); - serializedVis$.next({ - ...currentSerializedVis, - ...visUpdates, - params: { - ...currentSerializedVis.params, - ...visUpdates.params, - }, - data: { - ...currentSerializedVis.data, - ...visUpdates.data, - }, - } as SerializedVis); - if (visUpdates.title) { - titleManager.api.setTitle(visUpdates.title); - } - }, - openInspector: () => { - const adapters = inspectorAdapters$.getValue(); - if (!adapters) return; - const inspector = getInspector(); - if (!inspector.isAvailable(adapters)) return; - return getInspector().open(adapters, { - title: - titleManager.api.title$?.getValue() || - i18n.translate('visualizations.embeddable.inspectorTitle', { - defaultMessage: 'Inspector', - }), - }); - }, - // Library transforms - saveToLibrary: (newTitle: string) => { - titleManager.api.setTitle(newTitle); - return saveToLibrary({ - description: titleManager.api.description$.value, + const serializeVisualizeEmbeddable = ( + savedObjectId: string | undefined, + linkedToLibraryArg: boolean + ) => { + return serializeState({ serializedVis: vis$.getValue().serialize(), - title: newTitle, - uiState: vis$.getValue().uiState, + titles: titleManager.getLatestState(), + id: savedObjectId, + linkedToLibrary: linkedToLibraryArg, + ...(runtimeState.savedObjectProperties + ? { savedObjectProperties: runtimeState.savedObjectProperties } + : {}), + drilldowns: drilldownsManager.getLatestState(), + ...timeRangeManager.getLatestState(), }); - }, - canLinkToLibrary: () => Promise.resolve(!linkedToLibrary), - canUnlinkFromLibrary: () => Promise.resolve(linkedToLibrary), - checkForDuplicateTitle: async ( - newTitle: string, - isTitleDuplicateConfirmed: boolean, - onTitleDuplicate: () => void - ) => { - await checkForDuplicateTitle( - { title: newTitle, lastSavedTitle: '' }, - false, - isTitleDuplicateConfirmed, - onTitleDuplicate - ); - }, - getSerializedStateByValue: () => serializeVisualizeEmbeddable(undefined, false), - getSerializedStateByReference: (libraryId) => serializeVisualizeEmbeddable(libraryId, true), - }); - - const fetchSubscription = fetch$(api) - .pipe( - switchMap(async (data) => { - const unifiedSearch = apiPublishesUnifiedSearch(parentApi) - ? { - query: data.query, - filters: data.filters, - } - : {}; - const projectRouting = apiPublishesProjectRouting(parentApi) - ? data.projectRouting - : undefined; - const searchSessionId = apiPublishesSearchSession(parentApi) ? data.searchSessionId : ''; - searchSessionId$.next(searchSessionId); - const settings = apiPublishesSettings(parentApi) - ? { - syncColors: parentApi.settings.syncColors$.getValue(), - syncCursor: parentApi.settings.syncCursor$.getValue(), - syncTooltips: parentApi.settings.syncTooltips$.getValue(), - } - : {}; + }; + + const unsavedChangesApi = initializeUnsavedChanges({ + uuid, + parentApi, + serializeState: () => { + return serializeVisualizeEmbeddable(savedObjectId$.getValue(), linkedToLibrary); + }, + anyStateChange$: merge( + drilldownsManager.anyStateChange$, + savedObjectId$, + serializedVis$, + titleManager.anyStateChange$, + timeRangeManager.anyStateChange$ + ).pipe(map(() => undefined)), + getComparators: () => { + return { + ...drilldownsManager.comparators, + ...titleComparators, + ...timeRangeComparators, + savedObjectId: 'skip', + uiState: linkedToLibrary ? 'deepEquality' : 'skip', + savedVis: linkedToLibrary + ? 'skip' + : (a, b) => { + function deepOmitBy(value: any) { + if (value && !Array.isArray(value) && typeof value === 'object') { + const keys = Object.keys(value); + if (!keys.length) return; + + const cleanedValue: Record = {}; + keys.forEach((key) => { + const cleanedSubvalue = deepOmitBy(value[key]); + if (cleanedSubvalue) { + cleanedValue[key] = cleanedSubvalue; + } + }); + return cleanedValue; + } + + return value; + } - dataLoading$.next(true); + return isEqual(deepOmitBy(a), deepOmitBy(b)); + }, + }; + }, + onReset: async (lastSaved) => { + drilldownsManager.reinitializeState(lastSaved ?? {}); + timeRangeManager.reinitializeState(lastSaved); + titleManager.reinitializeState(lastSaved); + + if (!lastSaved) return; + const lastSavedRuntimeState = await deserializeState(lastSaved); + serializedVis$.next(lastSavedRuntimeState.serializedVis); + }, + }); - const timeslice = apiPublishesTimeslice(parentApi) - ? parentApi.timeslice$.getValue() - : undefined; + const api = finalizeApi({ + ...timeRangeManager.api, + ...titleManager.api, + ...drilldownsManager.api, + ...unsavedChangesApi, + defaultTitle$, + dataLoading$, + dataViews$: new BehaviorSubject(initialDataViews), + projectRoutingOverrides$, + rendered$: hasRendered$, + supportedTriggers: () => [ + ON_OPEN_PANEL_MENU, + ACTION_CONVERT_TO_LENS, + ON_APPLY_FILTER, + ON_SELECT_RANGE, + ], + serializeState: () => { + // In the visualize editor, linkedToLibrary should always be false to force the full state to be serialized, + // instead of just passing a reference to the linked saved object. Other contexts like dashboards should + // serialize the state with just the savedObjectId so that the current revision of the vis is always used + const forcedLinkedToLibrary = apiIsOfType(parentApi, VISUALIZE_APP_NAME) + ? false + : linkedToLibrary; + return serializeVisualizeEmbeddable(savedObjectId$.getValue(), forcedLinkedToLibrary); + }, + getVis: () => vis$.getValue(), + getInspectorAdapters: () => inspectorAdapters$.getValue(), + ...initializeEditApi({ + customTimeRange$: timeRangeManager.api.timeRange$, + description$: titleManager.api.description$, + parentApi, + savedObjectId$, + searchSessionId$, + title$: titleManager.api.title$, + vis$, + uuid, + }), + updateVis: async (visUpdates) => { + const currentSerializedVis = vis$.getValue().serialize(); + serializedVis$.next({ + ...currentSerializedVis, + ...visUpdates, + params: { + ...currentSerializedVis.params, + ...visUpdates.params, + }, + data: { + ...currentSerializedVis.data, + ...visUpdates.data, + }, + } as SerializedVis); + if (visUpdates.title) { + titleManager.api.setTitle(visUpdates.title); + } + }, + openInspector: () => { + const adapters = inspectorAdapters$.getValue(); + if (!adapters) return; + const inspector = getInspector(); + if (!inspector.isAvailable(adapters)) return; + return getInspector().open(adapters, { + title: + titleManager.api.title$?.getValue() || + i18n.translate('visualizations.embeddable.inspectorTitle', { + defaultMessage: 'Inspector', + }), + }); + }, + // Library transforms + saveToLibrary: (newTitle: string) => { + titleManager.api.setTitle(newTitle); + return saveToLibrary({ + description: titleManager.api.description$.value, + serializedVis: vis$.getValue().serialize(), + title: newTitle, + uiState: vis$.getValue().uiState, + }); + }, + canLinkToLibrary: () => Promise.resolve(!linkedToLibrary), + canUnlinkFromLibrary: () => Promise.resolve(linkedToLibrary), + checkForDuplicateTitle: async ( + newTitle: string, + isTitleDuplicateConfirmed: boolean, + onTitleDuplicate: () => void + ) => { + await checkForDuplicateTitle( + { title: newTitle, lastSavedTitle: '' }, + false, + isTitleDuplicateConfirmed, + onTitleDuplicate + ); + }, + getSerializedStateByValue: () => serializeVisualizeEmbeddable(undefined, false), + getSerializedStateByReference: (libraryId) => serializeVisualizeEmbeddable(libraryId, true), + }); - const customTimeRange = timeRangeManager.api.timeRange$.getValue(); - const parentTimeRange = apiPublishesTimeRange(parentApi) ? data.timeRange : undefined; - const timesliceTimeRange = timeslice - ? { - from: new Date(timeslice[0]).toISOString(), - to: new Date(timeslice[1]).toISOString(), - mode: 'absolute' as 'absolute', - } - : undefined; - - // Precedence should be: - // custom time range from state > - // timeslice time range > - // parent API time range from e.g. unified search - const timeRangeToRender = customTimeRange ?? timesliceTimeRange ?? parentTimeRange; - - getExpressionParams = async () => { - return await getExpressionRendererProps({ - unifiedSearch, - projectRouting, - vis: vis$.getValue(), - settings, - disableTriggers, - searchSessionId, - parentExecutionContext: executionContext, - abortController: expressionAbortController$.getValue(), - timeRange: timeRangeToRender, - onRender: async (renderCount) => { - if (renderCount === renderCount$.getValue()) return; - renderCount$.next(renderCount); - const visInstance = vis$.getValue(); - const visTypeName = visInstance.type.name; - - let telemetryVisTypeName = visTypeName; - if (visTypeName === 'metrics') { - telemetryVisTypeName = 'legacy_metric'; - } - if (visTypeName === 'pie' && visInstance.params.isDonut) { - telemetryVisTypeName = 'donut'; + const fetchSubscription = fetch$(api) + .pipe( + switchMap(async (data) => { + const unifiedSearch = apiPublishesUnifiedSearch(parentApi) + ? { + query: data.query, + filters: data.filters, } - if ( - visTypeName === 'area' && - visInstance.params.seriesParams.some( - (seriesParams: { mode: string }) => seriesParams.mode === 'stacked' - ) - ) { - telemetryVisTypeName = 'area_stacked'; + : {}; + const projectRouting = apiPublishesProjectRouting(parentApi) + ? data.projectRouting + : undefined; + const searchSessionId = apiPublishesSearchSession(parentApi) + ? data.searchSessionId + : ''; + searchSessionId$.next(searchSessionId); + const settings = apiPublishesSettings(parentApi) + ? { + syncColors: parentApi.settings.syncColors$.getValue(), + syncCursor: parentApi.settings.syncCursor$.getValue(), + syncTooltips: parentApi.settings.syncTooltips$.getValue(), } + : {}; - getUsageCollection().reportUiCounter( - executionContext?.type ?? '', - 'count', - `render_agg_based_${telemetryVisTypeName}` - ); - - if (hasRendered$.getValue() === true) return; - hasRendered$.next(true); - }, - onEvent: async (event) => { - // Visualize doesn't respond to sizing events, so ignore. - if (isChartSizeEvent(event)) { - return; + dataLoading$.next(true); + + const timeslice = apiPublishesTimeslice(parentApi) + ? parentApi.timeslice$.getValue() + : undefined; + + const customTimeRange = timeRangeManager.api.timeRange$.getValue(); + const parentTimeRange = apiPublishesTimeRange(parentApi) ? data.timeRange : undefined; + const timesliceTimeRange = timeslice + ? { + from: new Date(timeslice[0]).toISOString(), + to: new Date(timeslice[1]).toISOString(), + mode: 'absolute' as 'absolute', } - const currentVis = vis$.getValue(); - if (!disableTriggers) { - const triggerId: string = get( - VIS_EVENT_TO_TRIGGER, - event.name, - VIS_EVENT_TO_TRIGGER.filter - ); - let context; - - if (triggerId === VIS_EVENT_TO_TRIGGER.applyFilter) { - context = { - embeddable: api, - timeFieldName: currentVis.data.indexPattern?.timeFieldName!, - ...event.data, - }; - } else { - context = { - embeddable: api, - data: { - timeFieldName: currentVis.data.indexPattern?.timeFieldName!, - ...event.data, - }, - }; + : undefined; + + // Precedence should be: + // custom time range from state > + // timeslice time range > + // parent API time range from e.g. unified search + const timeRangeToRender = customTimeRange ?? timesliceTimeRange ?? parentTimeRange; + + getExpressionParams = async () => { + return await getExpressionRendererProps({ + unifiedSearch, + projectRouting, + vis: vis$.getValue(), + settings, + disableTriggers, + searchSessionId, + parentExecutionContext: executionContext, + abortController: expressionAbortController$.getValue(), + timeRange: timeRangeToRender, + onRender: async (renderCount) => { + if (renderCount === renderCount$.getValue()) return; + renderCount$.next(renderCount); + const visInstance = vis$.getValue(); + const visTypeName = visInstance.type.name; + + let telemetryVisTypeName = visTypeName; + if (visTypeName === 'metrics') { + telemetryVisTypeName = 'legacy_metric'; + } + if (visTypeName === 'pie' && visInstance.params.isDonut) { + telemetryVisTypeName = 'donut'; + } + if ( + visTypeName === 'area' && + visInstance.params.seriesParams.some( + (seriesParams: { mode: string }) => seriesParams.mode === 'stacked' + ) + ) { + telemetryVisTypeName = 'area_stacked'; } - await getUiActions().executeTriggerActions(triggerId, context); - } - }, - onData: (_, inspectorAdapters) => { - inspectorAdapters$.next( - typeof inspectorAdapters === 'function' ? inspectorAdapters() : inspectorAdapters - ); - dataLoading$.next(false); - }, - }); - }; - return await getExpressionParams(); - }) - ) - .subscribe(({ params, abortController }) => { - if (params) expressionParams$.next(params); - expressionAbortController$.next(abortController); - }); - return { - api, - Component: () => { - const expressionParams = useStateFromPublishingSubject(expressionParams$); - const renderCount = useStateFromPublishingSubject(renderCount$); - const hasRendered = useStateFromPublishingSubject(hasRendered$); - const [hideTitle, title, defaultTitle] = useBatchedPublishingSubjects( - api.hideTitle$, - api.title$, - api.defaultTitle$ - ); - const domNode = useRef(null); - const { error, isLoading } = useExpressionRenderer(domNode, expressionParams); - const errorTextStyle = useErrorTextStyle(); - - const dataTitle = useMemo(() => { - if (hideTitle) return ''; - return title ?? defaultTitle ?? ''; - }, [hideTitle, title, defaultTitle]); - - useEffect(() => { - return () => { - drilldownsManager.cleanup(); - fetchSubscription.unsubscribe(); - serializedVisSubscription.unsubscribe(); - }; - }, []); + getUsageCollection().reportUiCounter( + executionContext?.type ?? '', + 'count', + `render_agg_based_${telemetryVisTypeName}` + ); - useEffect(() => { - if (hasRendered && domNode.current) { - dispatchRenderComplete(domNode.current); - } - }, [hasRendered]); - - return ( -
- {/* Replicate the loading state for the expression renderer to avoid FOUC */} - - {isLoading && } - {!isLoading && error && ( - - {i18n.translate('visualizations.embeddable.errorTitle', { - defaultMessage: 'Unable to load visualization ', - })} - + if (hasRendered$.getValue() === true) return; + hasRendered$.next(true); + }, + onEvent: async (event) => { + // Visualize doesn't respond to sizing events, so ignore. + if (isChartSizeEvent(event)) { + return; } - body={ - - {error.name}: {error.message} - + const currentVis = vis$.getValue(); + if (!disableTriggers) { + const triggerId: string = get( + VIS_EVENT_TO_TRIGGER, + event.name, + VIS_EVENT_TO_TRIGGER.filter + ); + let context; + + if (triggerId === VIS_EVENT_TO_TRIGGER.applyFilter) { + context = { + embeddable: api, + timeFieldName: currentVis.data.indexPattern?.timeFieldName!, + ...event.data, + }; + } else { + context = { + embeddable: api, + data: { + timeFieldName: currentVis.data.indexPattern?.timeFieldName!, + ...event.data, + }, + }; + } + await getUiActions().executeTriggerActions(triggerId, context); } - /> - )} - -
- ); - }, - }; - }, -}); + }, + onData: (_, inspectorAdapters) => { + inspectorAdapters$.next( + typeof inspectorAdapters === 'function' + ? inspectorAdapters() + : inspectorAdapters + ); + dataLoading$.next(false); + }, + }); + }; + return await getExpressionParams(); + }) + ) + .subscribe(({ params, abortController }) => { + if (params) expressionParams$.next(params); + expressionAbortController$.next(abortController); + }); + + return { + api, + Component: () => { + const expressionParams = useStateFromPublishingSubject(expressionParams$); + const renderCount = useStateFromPublishingSubject(renderCount$); + const hasRendered = useStateFromPublishingSubject(hasRendered$); + const [hideTitle, title, defaultTitle] = useBatchedPublishingSubjects( + api.hideTitle$, + api.title$, + api.defaultTitle$ + ); + const domNode = useRef(null); + const { error, isLoading } = useExpressionRenderer(domNode, expressionParams); + const errorTextStyle = useErrorTextStyle(); + + const dataTitle = useMemo(() => { + if (hideTitle) return ''; + return title ?? defaultTitle ?? ''; + }, [hideTitle, title, defaultTitle]); + + useEffect(() => { + return () => { + drilldownsManager.cleanup(); + fetchSubscription.unsubscribe(); + serializedVisSubscription.unsubscribe(); + }; + }, []); + + useEffect(() => { + if (hasRendered && domNode.current) { + dispatchRenderComplete(domNode.current); + } + }, [hasRendered]); + + return ( +
+ {/* Replicate the loading state for the expression renderer to avoid FOUC */} + + {isLoading && } + {!isLoading && error && ( + + {i18n.translate('visualizations.embeddable.errorTitle', { + defaultMessage: 'Unable to load visualization ', + })} + + } + body={ + + {error.name}: {error.message} + + } + /> + )} + +
+ ); + }, + }; + }, + }; diff --git a/src/platform/plugins/shared/visualizations/public/plugin.ts b/src/platform/plugins/shared/visualizations/public/plugin.ts index 3e6c47cbb74f4..a172cfb7c18ef 100644 --- a/src/platform/plugins/shared/visualizations/public/plugin.ts +++ b/src/platform/plugins/shared/visualizations/public/plugin.ts @@ -480,12 +480,8 @@ export class VisualizationsPlugin expressions.registerFunction(visDimensionExpressionFunction); expressions.registerFunction(xyDimensionExpressionFunction); embeddable.registerReactEmbeddableFactory(VISUALIZE_EMBEDDABLE_TYPE, async () => { - const { - plugins: { embeddable: embeddableStart }, - } = start(); - - const { getVisualizeEmbeddableFactory } = await import('./embeddable/embeddable_module'); - return getVisualizeEmbeddableFactory({ embeddableStart }); + const { visualizeEmbeddableFactory } = await import('./embeddable/embeddable_module'); + return visualizeEmbeddableFactory; }); embeddable.registerAddFromLibraryType({ onAdd: async (container, savedObject) => { diff --git a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/from_attachment.ts b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/from_attachment.ts index b992c52a86063..d5ed16426636e 100644 --- a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/from_attachment.ts +++ b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/from_attachment.ts @@ -12,6 +12,7 @@ import type { } from '@kbn/dashboard-plugin/server'; import { LensConfigBuilder } from '@kbn/lens-embeddable-utils/config_builder'; import { isLensAPIFormat } from '@kbn/lens-embeddable-utils/config_builder/utils'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import type { AttachmentPanel, DashboardSection as AgentDashboardSection, @@ -19,9 +20,6 @@ import type { } from '../types'; import { isSection } from '../types'; -// TODO: update this when LENS_EMBEDDABLE_TYPE is moved to @kbn/lens-common -const LENS_EMBEDDABLE_TYPE = 'lens'; - /** * Converts an AttachmentPanel to a DashboardPanel. * For Lens panels with API format attributes, converts to internal format. diff --git a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/normalize_panel.ts b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/normalize_panel.ts index 1e2e5f8139392..cc2eeca16e53c 100644 --- a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/normalize_panel.ts +++ b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/normalize_panel.ts @@ -6,10 +6,9 @@ */ import { v4 as uuidv4 } from 'uuid'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import type { AttachmentPanel } from '../types'; -const LENS_EMBEDDABLE_TYPE = 'lens'; - export interface VisualizationContent { type: string; config: Record; diff --git a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/to_attachment.ts b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/to_attachment.ts index 6aec7f3e57f2b..b93b227be6697 100644 --- a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/to_attachment.ts +++ b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/converters/to_attachment.ts @@ -15,6 +15,7 @@ import { type LensApiSchemaType, type LensAttributes, } from '@kbn/lens-embeddable-utils/config_builder'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import type { AttachmentPanel, DashboardSection as DashboardAttachmentSection } from '../types'; import type { DashboardAttachmentData } from '../types'; @@ -33,8 +34,7 @@ export const isLensAttributes = ( * For Lens panels with internal attributes format, converts to API format. */ export const toAttachmentPanel = (panel: DashboardPanel): AttachmentPanel | undefined => { - // TODO: update this when LENS_EMBEDDABLE_TYPE is moved to @kbn/lens-common - if (panel.type === 'lens') { + if (panel.type === LENS_EMBEDDABLE_TYPE) { const panelConfig = panel.config as | { attributes?: LensApiSchemaType | LensAttributes } | undefined; diff --git a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/moon.yml b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/moon.yml index e173dc0b21e43..32ab2049ba057 100644 --- a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/moon.yml +++ b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/moon.yml @@ -21,6 +21,7 @@ dependsOn: - '@kbn/zod' - '@kbn/dashboard-plugin' - '@kbn/lens-embeddable-utils' + - '@kbn/lens-common' tags: - shared-common - package diff --git a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/tsconfig.json b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/tsconfig.json index d4aab18537c64..288369170965e 100644 --- a/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/tsconfig.json +++ b/x-pack/platform/packages/shared/dashboard-agent/dashboard-agent-common/tsconfig.json @@ -17,6 +17,7 @@ "@kbn/agent-builder-common", "@kbn/zod", "@kbn/dashboard-plugin", - "@kbn/lens-embeddable-utils" + "@kbn/lens-embeddable-utils", + "@kbn/lens-common" ] } diff --git a/x-pack/platform/plugins/private/canvas/canvas_plugin_src/expression_types/embeddable.ts b/x-pack/platform/plugins/private/canvas/canvas_plugin_src/expression_types/embeddable.ts index abcfe35380084..cc5c55fb93889 100644 --- a/x-pack/platform/plugins/private/canvas/canvas_plugin_src/expression_types/embeddable.ts +++ b/x-pack/platform/plugins/private/canvas/canvas_plugin_src/expression_types/embeddable.ts @@ -6,10 +6,8 @@ */ import type { ExpressionTypeDefinition } from '@kbn/expressions-plugin/common'; -import { EmbeddableTypes } from './embeddable_types'; export const EmbeddableExpressionType = 'embeddable'; -export { EmbeddableTypes }; export interface EmbeddableExpression { /** diff --git a/x-pack/platform/plugins/private/canvas/canvas_plugin_src/expression_types/embeddable_types.ts b/x-pack/platform/plugins/private/canvas/canvas_plugin_src/expression_types/embeddable_types.ts deleted file mode 100644 index 8f61cecbeec13..0000000000000 --- a/x-pack/platform/plugins/private/canvas/canvas_plugin_src/expression_types/embeddable_types.ts +++ /dev/null @@ -1,23 +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 { MAP_SAVED_OBJECT_TYPE } from '@kbn/maps-plugin/common'; -import { VISUALIZE_EMBEDDABLE_TYPE } from '@kbn/visualizations-common'; -import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-plugin/common/constants'; -import { SEARCH_EMBEDDABLE_TYPE } from '@kbn/discover-utils'; - -export const EmbeddableTypes: { - lens: string; - map: string; - search: string; - visualization: string; -} = { - lens: LENS_EMBEDDABLE_TYPE, - map: MAP_SAVED_OBJECT_TYPE, - search: SEARCH_EMBEDDABLE_TYPE, - visualization: VISUALIZE_EMBEDDABLE_TYPE, -}; diff --git a/x-pack/platform/plugins/private/canvas/kibana.jsonc b/x-pack/platform/plugins/private/canvas/kibana.jsonc index f5f777feb1d58..b7e5bb8873297 100644 --- a/x-pack/platform/plugins/private/canvas/kibana.jsonc +++ b/x-pack/platform/plugins/private/canvas/kibana.jsonc @@ -38,7 +38,6 @@ "requiredBundles": [ "kibanaReact", "kibanaUtils", - "lens", "maps", "fieldFormats", "savedSearch" diff --git a/x-pack/platform/plugins/private/canvas/moon.yml b/x-pack/platform/plugins/private/canvas/moon.yml index e8100fbf9c723..99bff441196e1 100644 --- a/x-pack/platform/plugins/private/canvas/moon.yml +++ b/x-pack/platform/plugins/private/canvas/moon.yml @@ -31,7 +31,6 @@ dependsOn: - '@kbn/ui-actions-plugin' - '@kbn/usage-collection-plugin' - '@kbn/features-plugin' - - '@kbn/lens-plugin' - '@kbn/maps-plugin' - '@kbn/reporting-plugin' - '@kbn/spaces-plugin' diff --git a/x-pack/platform/plugins/private/canvas/server/embeddable/ensure_library_reference.ts b/x-pack/platform/plugins/private/canvas/server/embeddable/ensure_library_reference.ts index 5559694ecc5bc..2219b2363aa70 100644 --- a/x-pack/platform/plugins/private/canvas/server/embeddable/ensure_library_reference.ts +++ b/x-pack/platform/plugins/private/canvas/server/embeddable/ensure_library_reference.ts @@ -6,13 +6,15 @@ */ import type { SavedObjectReference } from '@kbn/core/server'; +import { SEARCH_EMBEDDABLE_TYPE } from '@kbn/discover-utils'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; +import { VISUALIZE_EMBEDDABLE_TYPE, VISUALIZE_SAVED_OBJECT_TYPE } from '@kbn/visualizations-common'; const BY_REF_LIBRARY_TYPES = ['search', 'visualization', 'lens', 'map']; export function ensureLibraryReference( references: SavedObjectReference[], - // pre-translated embeddable type. i.e. "search" not translated version "discover_session" - storedEmbeddableType: string, + embeddableType: string, panelRefName: string ) { let libraryRef: SavedObjectReference | undefined; @@ -36,12 +38,26 @@ export function ensureLibraryReference( if (!libraryRef) { libraryRef = { id: panelRefName, - // No mapping between embeddable type and library type is needed - // stored embeddable types are identical to respective library types - type: storedEmbeddableType, // happenstance that storedEmbeddableType is the library type + type: getLibraryType(embeddableType), name: 'savedObjectRef', }; } return [libraryRef, ...restOfRefs]; } + +function getLibraryType(embeddableType: string) { + if (embeddableType === LENS_EMBEDDABLE_TYPE) { + return 'lens'; + } + + if (embeddableType === VISUALIZE_EMBEDDABLE_TYPE) { + return VISUALIZE_SAVED_OBJECT_TYPE; + } + + if (embeddableType === SEARCH_EMBEDDABLE_TYPE) { + return 'search'; + } + + return embeddableType; +} diff --git a/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_in.test.ts b/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_in.test.ts index 7b4e3085fff72..6064945480de0 100644 --- a/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_in.test.ts +++ b/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_in.test.ts @@ -11,8 +11,9 @@ import { encode } from '../../common/lib/embeddable_dataurl'; import { transformWorkpadIn } from './transform_workpad_in'; import { embeddableService, logger } from '../kibana_services'; import { getDecodedConfig, makeWorkpad } from './fixtures'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; -const mockLensTransformIn = jest.fn((config: any) => { +const mockTransformIn = jest.fn((config: any) => { const { savedObjectId, ...remainingConfig } = config; return { state: remainingConfig, @@ -22,38 +23,12 @@ const mockLensTransformIn = jest.fn((config: any) => { }; }); -const mockVisualizationTransformIn = jest.fn((config: any) => { - const { savedObjectId, ...remainingConfig } = config; - return { - state: remainingConfig, - references: [ - { id: savedObjectId, name: 'savedObjectRef', type: 'visualization' }, - ] as SavedObjectReference[], - }; -}); - -const mockMapTransformIn = jest.fn((config: any) => { - const { savedObjectId, ...remainingConfig } = config; - return { - state: remainingConfig, - references: [ - { id: savedObjectId, name: 'savedObjectRef', type: 'map' }, - ] as SavedObjectReference[], - }; -}); jest.mock('../kibana_services', () => ({ embeddableService: { getTransforms: jest.fn((type: string) => { - switch (type) { - case 'lens-dashboard-app': - return { transformIn: mockLensTransformIn }; - case 'visualization': - return { transformIn: mockVisualizationTransformIn }; - case 'map': - return { transformIn: mockMapTransformIn }; - default: - return; - } + return { + transformIn: mockTransformIn, + }; }), }, logger: { @@ -62,9 +37,9 @@ jest.mock('../kibana_services', () => ({ })); describe('transformWorkpadIn', () => { - it('transforms embeddable with lens config from stored state to REST API state', () => { + it('transforms REST API embeddable state to stored state', () => { const workpad = makeWorkpad( - `embeddable type="lens" config="${encode({ + `embeddable type="${LENS_EMBEDDABLE_TYPE}" config="${encode({ title: 'Test lens embeddable', savedObjectId: 'test-id', })}"` @@ -82,67 +57,12 @@ describe('transformWorkpadIn', () => { }, ]); - expect(embeddableService?.getTransforms).toHaveBeenCalledWith('lens-dashboard-app'); - expect(mockLensTransformIn).toHaveBeenCalledWith({ + expect(mockTransformIn).toHaveBeenCalledWith({ savedObjectId: 'test-id', title: 'Test lens embeddable', }); }); - it('transforms embeddable with visualization config from stored state to REST API state', () => { - const workpad = makeWorkpad( - `embeddable type="visualization" config="${encode({ - title: 'Test visualization embeddable', - savedObjectId: 'test-id', - })}"` - ); - - const { attributes, references } = transformWorkpadIn(workpad); - expect(getDecodedConfig(attributes)).toEqual({ - title: 'Test visualization embeddable', - }); - expect(references).toEqual([ - { - id: 'test-id', - name: 'element-id:savedObjectRef', - type: 'visualization', - }, - ]); - - expect(embeddableService?.getTransforms).toHaveBeenCalledWith('visualization'); - expect(mockVisualizationTransformIn).toHaveBeenCalledWith({ - savedObjectId: 'test-id', - title: 'Test visualization embeddable', - }); - }); - - it('transforms embeddable with map config from stored state to REST API state', () => { - const workpad = makeWorkpad( - `embeddable type="map" config="${encode({ - title: 'Test map embeddable', - savedObjectId: 'test-id', - })}"` - ); - - const { attributes, references } = transformWorkpadIn(workpad); - expect(getDecodedConfig(attributes)).toEqual({ - title: 'Test map embeddable', - }); - expect(references).toEqual([ - { - id: 'test-id', - name: 'element-id:savedObjectRef', - type: 'map', - }, - ]); - - expect(embeddableService?.getTransforms).toHaveBeenCalledWith('map'); - expect(mockMapTransformIn).toHaveBeenCalledWith({ - savedObjectId: 'test-id', - title: 'Test map embeddable', - }); - }); - it('logs warnings when transformation fails and returns the original embeddable config and no references', () => { (embeddableService.getTransforms as jest.Mock).mockReturnValue({ transformIn: jest.fn(() => { diff --git a/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_in.ts b/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_in.ts index e0ba3cf0bf918..a08091135c773 100644 --- a/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_in.ts +++ b/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_in.ts @@ -7,6 +7,7 @@ import { fromExpression, toExpression } from '@kbn/interpreter'; import type { SavedObjectReference } from '@kbn/core/server'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import { encode, decode } from '../../common/lib/embeddable_dataurl'; import type { WorkpadAttributes } from '../routes/workpad/workpad_attributes'; import { embeddableService, logger } from '../kibana_services'; @@ -30,7 +31,8 @@ export const transformWorkpadIn = ( const embeddableType = fn.arguments.type[0] as string; // Temporary escape hatch for lens as code // TODO remove when lens as code transforms are ready for production - const transformType = embeddableType === 'lens' ? 'lens-dashboard-app' : embeddableType; + const transformType = + embeddableType === LENS_EMBEDDABLE_TYPE ? 'lens-dashboard-app' : embeddableType; const transforms = embeddableService.getTransforms(transformType); try { diff --git a/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_out.test.ts b/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_out.test.ts index 7a45b99959ba8..f0201b80a9dde 100644 --- a/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_out.test.ts +++ b/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_out.test.ts @@ -13,6 +13,7 @@ import { embeddableService, logger } from '../kibana_services'; import { transformWorkpadOut } from './transform_workpad_out'; import { makeWorkpad, getDecodedConfig, getExpressionFunctionName } from './fixtures'; +import { VISUALIZE_EMBEDDABLE_TYPE } from '@kbn/visualizations-common'; const mockLensTransforms = { transformOut: jest.fn((config: any, references: SavedObjectReference[]) => { @@ -38,7 +39,7 @@ jest.mock('../kibana_services', () => ({ switch (type) { case 'lens-dashboard-app': return mockLensTransforms; - case 'visualization': + case 'legacy_vis': return mockVisualizationTransforms; case 'map': return mockMapTransforms; @@ -101,7 +102,7 @@ describe('transformWorkpadOut', () => { timeRange: DEFAULT_TIME_RANGE, savedObjectId: 'embeddable-id', }); - expect(embeddableService.getTransforms).toHaveBeenCalledWith('visualization'); + expect(embeddableService.getTransforms).toHaveBeenCalledWith(VISUALIZE_EMBEDDABLE_TYPE); expect(mockVisualizationTransforms.transformOut).toHaveBeenCalledWith( { timeRange: DEFAULT_TIME_RANGE, savedObjectId: 'embeddable-id' }, [ @@ -232,7 +233,7 @@ describe('legacy expressions', () => { timeRange: DEFAULT_TIME_RANGE, savedObjectId: 'vis-id', }); - expect(embeddableService.getTransforms).toHaveBeenCalledWith('visualization'); + expect(embeddableService.getTransforms).toHaveBeenCalledWith(VISUALIZE_EMBEDDABLE_TYPE); expect(mockVisualizationTransforms.transformOut).toHaveBeenCalledWith( { timeRange: DEFAULT_TIME_RANGE, savedObjectId: 'savedVisualization.id' }, [{ id: 'vis-id', name: 'savedObjectRef', type: 'visualization' }] @@ -253,7 +254,7 @@ describe('legacy expressions', () => { title: 'My Viz', savedObjectId: 'vis-id', }); - expect(embeddableService.getTransforms).toHaveBeenCalledWith('visualization'); + expect(embeddableService.getTransforms).toHaveBeenCalledWith(VISUALIZE_EMBEDDABLE_TYPE); expect(mockVisualizationTransforms.transformOut).toHaveBeenCalledWith( { timeRange: DEFAULT_TIME_RANGE, title: 'My Viz', savedObjectId: 'savedVisualization.id' }, [{ id: 'vis-id', name: 'savedObjectRef', type: 'visualization' }] @@ -273,7 +274,7 @@ describe('legacy expressions', () => { expect(getDecodedConfig(transformedWorkpad)).toEqual( expect.objectContaining({ timeRange: { from: 'now-7d', to: 'now' } }) ); - expect(embeddableService.getTransforms).toHaveBeenCalledWith('visualization'); + expect(embeddableService.getTransforms).toHaveBeenCalledWith(VISUALIZE_EMBEDDABLE_TYPE); expect(mockVisualizationTransforms.transformOut).toHaveBeenCalledWith( { timeRange: { from: 'now-7d', to: 'now' }, savedObjectId: 'savedVisualization.id' }, [{ id: 'vis-id', name: 'savedObjectRef', type: 'visualization' }] @@ -296,7 +297,7 @@ describe('legacy expressions', () => { legendOpen: false, }, }); - expect(embeddableService.getTransforms).toHaveBeenCalledWith('visualization'); + expect(embeddableService.getTransforms).toHaveBeenCalledWith(VISUALIZE_EMBEDDABLE_TYPE); expect(mockVisualizationTransforms.transformOut).toHaveBeenCalledWith( { timeRange: DEFAULT_TIME_RANGE, @@ -320,7 +321,7 @@ describe('legacy expressions', () => { timeRange: DEFAULT_TIME_RANGE, savedObjectId: 'vis-id', }); - expect(embeddableService.getTransforms).toHaveBeenCalledWith('visualization'); + expect(embeddableService.getTransforms).toHaveBeenCalledWith(VISUALIZE_EMBEDDABLE_TYPE); expect(mockVisualizationTransforms.transformOut).toHaveBeenCalledWith( { timeRange: DEFAULT_TIME_RANGE, savedObjectId: 'savedVisualization.id' }, [{ id: 'vis-id', name: 'savedObjectRef', type: 'visualization' }] @@ -338,7 +339,7 @@ describe('legacy expressions', () => { timeRange: DEFAULT_TIME_RANGE, savedObjectId: 'vis-id', }); - expect(embeddableService.getTransforms).toHaveBeenCalledWith('visualization'); + expect(embeddableService.getTransforms).toHaveBeenCalledWith(VISUALIZE_EMBEDDABLE_TYPE); expect(mockVisualizationTransforms.transformOut).toHaveBeenCalledWith( { timeRange: DEFAULT_TIME_RANGE, savedObjectId: 'vis-id' }, [ diff --git a/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_out.ts b/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_out.ts index cbf653df85997..4ba7e94207263 100644 --- a/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_out.ts +++ b/x-pack/platform/plugins/private/canvas/server/embeddable/transform_workpad_out.ts @@ -10,7 +10,9 @@ import { fromExpression, toExpression } from '@kbn/interpreter'; import type { SavedObjectReference } from '@kbn/core/server'; import type { TimeRange } from '@kbn/es-query'; import { transformType } from '@kbn/embeddable-plugin/server'; -import { EmbeddableTypes } from '../../canvas_plugin_src/expression_types'; +import { MAP_SAVED_OBJECT_TYPE } from '@kbn/maps-plugin/common'; +import { VISUALIZE_EMBEDDABLE_TYPE } from '@kbn/visualizations-common'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import { DEFAULT_TIME_RANGE } from '../../common/lib'; import { encode, decode } from '../../common/lib/embeddable_dataurl'; import type { WorkpadAttributes } from '../routes/workpad/workpad_attributes'; @@ -77,7 +79,7 @@ export function transformWorkpadOut( fn.function = 'embeddable'; fn.arguments = { config: [encode(lensConfig)], - type: [EmbeddableTypes.lens], + type: [LENS_EMBEDDABLE_TYPE], }; break; } @@ -97,7 +99,7 @@ export function transformWorkpadOut( fn.function = 'embeddable'; fn.arguments = { config: [encode(visualizationConfig)], - type: [EmbeddableTypes.visualization], + type: [VISUALIZE_EMBEDDABLE_TYPE], }; break; } @@ -115,20 +117,19 @@ export function transformWorkpadOut( fn.function = 'embeddable'; fn.arguments = { config: [encode(mapConfig)], - type: [EmbeddableTypes.map], + type: [MAP_SAVED_OBJECT_TYPE], }; break; } } const embeddableConfig = decode(fn.arguments.config[0] as string); - const storedEmbeddableType = fn.arguments.type[0] as string; - const embeddableType = transformType(storedEmbeddableType); + const embeddableType = transformType(fn.arguments.type[0] as string); fn.arguments.type[0] = embeddableType; // Temporary escape hatch for lens as code // TODO remove when lens as code transforms are ready for production const transforms = embeddableService.getTransforms( - embeddableType === 'lens' ? 'lens-dashboard-app' : embeddableType + embeddableType === LENS_EMBEDDABLE_TYPE ? 'lens-dashboard-app' : embeddableType ); try { @@ -137,7 +138,7 @@ export function transformWorkpadOut( if (embeddableConfig.savedObjectId) { referencesForElement = ensureLibraryReference( referencesForElement, - storedEmbeddableType, + embeddableType, embeddableConfig.savedObjectId ); } diff --git a/x-pack/platform/plugins/private/canvas/server/get_embeddable_expression.ts b/x-pack/platform/plugins/private/canvas/server/get_embeddable_expression.ts new file mode 100644 index 0000000000000..1fec1c76430eb --- /dev/null +++ b/x-pack/platform/plugins/private/canvas/server/get_embeddable_expression.ts @@ -0,0 +1,6 @@ +/* + * 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. + */ diff --git a/x-pack/platform/plugins/private/canvas/server/workpad_route_context.test.ts b/x-pack/platform/plugins/private/canvas/server/workpad_route_context.test.ts index 7e9fadc75b25c..72d5578ffdfc3 100644 --- a/x-pack/platform/plugins/private/canvas/server/workpad_route_context.test.ts +++ b/x-pack/platform/plugins/private/canvas/server/workpad_route_context.test.ts @@ -38,13 +38,13 @@ jest.mock('./kibana_services', () => ({ }, })); -const runtimeExpression = `embeddable type="lens" +const runtimeExpression = `embeddable type="vis" config="${encode({ title: 'Test lens embeddable', savedObjectId: 'test-id', })}"`; -const storedExpression = `embeddable type="lens" config="${encode({ +const storedExpression = `embeddable type="vis" config="${encode({ title: 'Test lens embeddable', })}"`; @@ -200,12 +200,12 @@ describe('workpad route context', () => { references, }); - const updatedRuntimeExpression = `embeddable type="lens" + const updatedRuntimeExpression = `embeddable type="vis" config="${encode({ savedObjectId: 'test-id', title: 'Test lens embeddable with a new title', })}"`; - const updatedStoredExpression = `embeddable type="lens" config="${encode({ + const updatedStoredExpression = `embeddable type="vis" config="${encode({ title: 'Test lens embeddable with a new title', })}"`; diff --git a/x-pack/platform/plugins/private/canvas/tsconfig.json b/x-pack/platform/plugins/private/canvas/tsconfig.json index e8e87e93f560f..a317ad827c16e 100644 --- a/x-pack/platform/plugins/private/canvas/tsconfig.json +++ b/x-pack/platform/plugins/private/canvas/tsconfig.json @@ -39,7 +39,6 @@ "@kbn/ui-actions-plugin", "@kbn/usage-collection-plugin", "@kbn/features-plugin", - "@kbn/lens-plugin", "@kbn/maps-plugin", "@kbn/reporting-plugin", "@kbn/spaces-plugin", diff --git a/x-pack/platform/plugins/private/discover_enhanced/kibana.jsonc b/x-pack/platform/plugins/private/discover_enhanced/kibana.jsonc index 9e498080d6f21..2127ea8380079 100644 --- a/x-pack/platform/plugins/private/discover_enhanced/kibana.jsonc +++ b/x-pack/platform/plugins/private/discover_enhanced/kibana.jsonc @@ -23,8 +23,7 @@ "usageCollection" ], "requiredBundles": [ - "kibanaUtils", - "lens" + "kibanaUtils" ] } } \ No newline at end of file diff --git a/x-pack/platform/plugins/private/discover_enhanced/moon.yml b/x-pack/platform/plugins/private/discover_enhanced/moon.yml index f13c8476b417b..2c37e7e12310e 100644 --- a/x-pack/platform/plugins/private/discover_enhanced/moon.yml +++ b/x-pack/platform/plugins/private/discover_enhanced/moon.yml @@ -21,7 +21,6 @@ dependsOn: - '@kbn/discover-plugin' - '@kbn/share-plugin' - '@kbn/kibana-utils-plugin' - - '@kbn/lens-plugin' - '@kbn/usage-collection-plugin' - '@kbn/embeddable-plugin' - '@kbn/ui-actions-plugin' diff --git a/x-pack/platform/plugins/private/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts b/x-pack/platform/plugins/private/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts index 5180d4198786f..5db64a9a8dd55 100644 --- a/x-pack/platform/plugins/private/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts +++ b/x-pack/platform/plugins/private/discover_enhanced/public/actions/explore_data/abstract_explore_data_action.ts @@ -10,7 +10,6 @@ import type { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common'; import type { DiscoverStart } from '@kbn/discover-plugin/public'; import { i18n } from '@kbn/i18n'; import type { StartServicesGetter } from '@kbn/kibana-utils-plugin/public'; -import { DOC_TYPE as LENS_DOC_TYPE } from '@kbn/lens-plugin/common/constants'; import type { CanAccessViewMode, EmbeddableApiContext, @@ -27,7 +26,6 @@ import { getInheritedViewMode, } from '@kbn/presentation-publishing'; import type { KibanaLocation } from '@kbn/share-plugin/public'; - import * as shared from './shared'; export const ACTION_EXPLORE_DATA = 'ACTION_EXPLORE_DATA'; @@ -51,7 +49,10 @@ const isApiCompatible = (api: unknown | null): api is AbstractExploreDataActionA const compatibilityCheck = (api: EmbeddableApiContext['embeddable']) => { return ( - isApiCompatible(api) && getInheritedViewMode(api) === 'view' && !apiIsOfType(api, LENS_DOC_TYPE) + isApiCompatible(api) && + getInheritedViewMode(api) === 'view' && + // TODO use LENS_EMBEDDABLE_TYPE, issue with build distribution + !apiIsOfType(api, 'vis') ); }; diff --git a/x-pack/platform/plugins/private/discover_enhanced/tsconfig.json b/x-pack/platform/plugins/private/discover_enhanced/tsconfig.json index 8f4c992163e20..d8376c0a3e57c 100644 --- a/x-pack/platform/plugins/private/discover_enhanced/tsconfig.json +++ b/x-pack/platform/plugins/private/discover_enhanced/tsconfig.json @@ -9,7 +9,6 @@ "@kbn/discover-plugin", "@kbn/share-plugin", "@kbn/kibana-utils-plugin", - "@kbn/lens-plugin", "@kbn/usage-collection-plugin", "@kbn/embeddable-plugin", "@kbn/ui-actions-plugin", diff --git a/x-pack/platform/plugins/shared/dashboard_agent/moon.yml b/x-pack/platform/plugins/shared/dashboard_agent/moon.yml index b952bf4cb9c9c..0bbd069fdb593 100644 --- a/x-pack/platform/plugins/shared/dashboard_agent/moon.yml +++ b/x-pack/platform/plugins/shared/dashboard_agent/moon.yml @@ -35,6 +35,7 @@ dependsOn: - '@kbn/css-utils' - '@kbn/logging' - '@kbn/core-elasticsearch-server' + - '@kbn/lens-common' - '@kbn/presentation-publishing' - '@kbn/core-saved-objects-api-server' tags: diff --git a/x-pack/platform/plugins/shared/dashboard_agent/server/sml_types/dashboard.test.ts b/x-pack/platform/plugins/shared/dashboard_agent/server/sml_types/dashboard.test.ts index 0a007120f2bcd..eab84f4ff516b 100644 --- a/x-pack/platform/plugins/shared/dashboard_agent/server/sml_types/dashboard.test.ts +++ b/x-pack/platform/plugins/shared/dashboard_agent/server/sml_types/dashboard.test.ts @@ -13,13 +13,14 @@ import { attachmentDataToDashboardState, } from '@kbn/dashboard-agent-common'; import { createDashboardSmlType } from './dashboard'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; const dashboardAttachmentData: DashboardAttachmentData = { title: 'System Overview', description: 'Main dashboard for key metrics', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, id: 'panel-1', grid: { x: 0, y: 0, w: 24, h: 15 }, config: { @@ -61,7 +62,7 @@ const dashboardStateWithLensApi = { description: 'Dashboard with API-format lens panel', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, id: 'panel-3', grid: { x: 0, y: 0, w: 24, h: 12 }, config: { @@ -234,7 +235,7 @@ describe('dashboardSmlType', () => { expect.arrayContaining([ expect.objectContaining({ id: 'panel-1', - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, }), expect.objectContaining({ id: 'section-1', @@ -293,7 +294,7 @@ describe('dashboardSmlType', () => { expect(attachmentData?.panels).toEqual([ expect.objectContaining({ id: 'panel-3', - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: expect.objectContaining({ attributes: expect.objectContaining({ type: 'lnsXY', diff --git a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/inline_visualization.test.ts b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/inline_visualization.test.ts index 19209df303139..4ac1d996ae064 100644 --- a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/inline_visualization.test.ts +++ b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/inline_visualization.test.ts @@ -10,6 +10,7 @@ import type { ModelProvider, ToolEventEmitter } from '@kbn/agent-builder-server' import type { IScopedClusterClient } from '@kbn/core-elasticsearch-server'; import type { Logger } from '@kbn/logging'; import { createVisualizationResolver } from './inline_visualization'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; jest.mock('@kbn/agent-builder-genai-utils', () => ({ buildVisualizationConfig: jest.fn(), @@ -65,7 +66,7 @@ describe('createVisualizationResolver', () => { expect(result).toEqual({ type: 'success', visContent: { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric' }, }, }); @@ -94,7 +95,7 @@ describe('createVisualizationResolver', () => { nlQuery: 'turn this into a line chart', existingPanel: { id: 'panel-1', - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { type: 'bar' } }, grid: { w: 24, h: 12, x: 0, y: 0 }, }, diff --git a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/inline_visualization.ts b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/inline_visualization.ts index 0b8aa0698dad0..7d0fa0deeae35 100644 --- a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/inline_visualization.ts +++ b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/inline_visualization.ts @@ -15,6 +15,7 @@ import { type AttachmentPanel, type VisualizationContent, } from '@kbn/dashboard-agent-common'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import type { VisualizationFailure } from './utils'; import { getErrorMessage } from './utils'; @@ -75,7 +76,7 @@ export const createVisualizationResolver = ({ }): ResolveVisualizationConfig => { return async ({ operationType, identifier, nlQuery, index, chartType, esql, existingPanel }) => { try { - if (existingPanel && existingPanel.type !== 'lens') { + if (existingPanel && existingPanel.type !== LENS_EMBEDDABLE_TYPE) { return createVisualizationFailureResult( operationType, identifier, @@ -84,7 +85,7 @@ export const createVisualizationResolver = ({ } const existingConfig = - existingPanel?.type === 'lens' + existingPanel?.type === LENS_EMBEDDABLE_TYPE ? (fromEmbeddablePanel(existingPanel).config as VisualizationConfig) : undefined; @@ -106,7 +107,7 @@ export const createVisualizationResolver = ({ return { type: 'success', visContent: { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: result.validatedConfig, }, }; diff --git a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/operations.test.ts b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/operations.test.ts index f52331fd2ead9..f32949049703f 100644 --- a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/operations.test.ts +++ b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/operations.test.ts @@ -16,6 +16,7 @@ import { MARKDOWN_EMBEDDABLE_TYPE } from '@kbn/dashboard-markdown/server'; import type { ResolveVisualizationConfig, VisualizationAttempt } from './inline_visualization'; import type { VisualizationContent } from '@kbn/dashboard-agent-common'; import { executeDashboardOperations, type DashboardOperation } from './operations'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; const createMockLogger = (): Logger => ({ @@ -45,7 +46,7 @@ const getPanelsOnly = (panels: DashboardAttachmentData['panels']): AttachmentPan describe('executeDashboardOperations', () => { const logger = createMockLogger(); const createLensPanel = (id: string, gridY = 0): AttachmentPanel => ({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, id, config: { type: 'metric' }, grid: { x: 0, y: gridY, w: 24, h: 9 }, @@ -74,7 +75,7 @@ describe('executeDashboardOperations', () => { ): ResolveVisualizationConfig => { return async ({ identifier }) => resultsByIdentifier[identifier] ?? - createResolvedVisualization({ type: 'lens', config: { type: 'metric' } }); + createResolvedVisualization({ type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric' } }); }; it('executes operations in order', async () => { @@ -277,11 +278,11 @@ describe('executeDashboardOperations', () => { resolvePanelsFromAttachments: () => ({ panels: [], failures: [] }), resolveVisualizationConfig: createResolveVisualizationConfig({ 'show total requests': createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric' }, }), 'show error rate': createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'bar' }, }), }), @@ -299,12 +300,12 @@ describe('executeDashboardOperations', () => { grid: { y: 12 }, panels: [ expect.objectContaining({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { type: 'metric' } }, grid: { x: 0, y: 0, w: 24, h: 9 }, }), expect.objectContaining({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { type: 'bar' } }, grid: { x: 24, y: 0, w: 24, h: 9 }, }), @@ -340,7 +341,7 @@ describe('executeDashboardOperations', () => { resolvePanelsFromAttachments: () => ({ panels: [], failures: [] }), resolveVisualizationConfig: createResolveVisualizationConfig({ 'show total requests': createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric' }, }), 'show p95 latency': { @@ -359,7 +360,7 @@ describe('executeDashboardOperations', () => { expect(sections).toHaveLength(1); expect(sections[0].panels).toEqual([ expect.objectContaining({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { type: 'metric' } }, grid: { x: 0, y: 0, w: 24, h: 9 }, }), @@ -442,13 +443,13 @@ describe('executeDashboardOperations', () => { secondSectionPanel.resolve( createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'bar' }, }) ); firstSectionPanel.resolve( createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric' }, }) ); @@ -534,13 +535,13 @@ describe('executeDashboardOperations', () => { topLevelPanel.resolve( createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'bar' }, }) ); sectionPanel.resolve( createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric' }, }) ); @@ -911,11 +912,11 @@ describe('executeDashboardOperations', () => { resolvePanelsFromAttachments: () => ({ panels: [], failures: [] }), resolveVisualizationConfig: createResolveVisualizationConfig({ 'show total requests': createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric' }, }), 'show error rate': createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'bar' }, }), }), @@ -926,14 +927,14 @@ describe('executeDashboardOperations', () => { expect(topLevelPanels).toEqual([ expect.objectContaining({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { type: 'metric' } }, grid: { x: 0, y: 0, w: 24, h: 9 }, }), ]); expect(sections[0].panels).toEqual([ expect.objectContaining({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { type: 'bar' } }, grid: { x: 24, y: 0, w: 24, h: 9 }, }), @@ -962,9 +963,12 @@ describe('executeDashboardOperations', () => { logger, resolvePanelsFromAttachments: () => ({ panels: [], failures: [] }), resolveVisualizationConfig: createResolveVisualizationConfig({ - 'panel-1': createResolvedVisualization({ type: 'lens', config: { type: 'bar' } }), + 'panel-1': createResolvedVisualization({ + type: LENS_EMBEDDABLE_TYPE, + config: { type: 'bar' }, + }), 'section-panel-1': createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'line' }, }), }), @@ -1020,13 +1024,13 @@ describe('executeDashboardOperations', () => { if (nlQuery === 'make this a bar chart') { return createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric', testStep: 'after-first-edit' }, }); } return createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric', testStep: configStep === 'after-first-edit' ? 'after-second-edit' : 'stale-edit', @@ -1049,7 +1053,9 @@ describe('executeDashboardOperations', () => { const resolveVisualizationConfig = jest.fn< ReturnType, Parameters - >(async () => createResolvedVisualization({ type: 'lens', config: { type: 'bar' } })); + >(async () => + createResolvedVisualization({ type: LENS_EMBEDDABLE_TYPE, config: { type: 'bar' } }) + ); const result = await executeDashboardOperations({ dashboardData: { @@ -1106,7 +1112,7 @@ describe('executeDashboardOperations', () => { resolvePanelsFromAttachments: () => ({ panels: [], failures: [] }), resolveVisualizationConfig: createResolveVisualizationConfig({ 'show total requests': createResolvedVisualization({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { type: 'metric' }, }), 'show p95 latency': { diff --git a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/utils.ts b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/utils.ts index 2a165024f6f15..22150894c26f3 100644 --- a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/utils.ts +++ b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/manage_dashboard/utils.ts @@ -14,6 +14,7 @@ import { type AttachmentVersion, getLatestVersion } from '@kbn/agent-builder-com import type { LensApiSchemaType } from '@kbn/lens-embeddable-utils'; import { z } from '@kbn/zod/v4'; import { toEmbeddablePanel, type VisualizationContent } from '@kbn/dashboard-agent-common'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; /** * Failure record for tracking visualization errors. @@ -44,7 +45,7 @@ const resolvePanelsFromVisualizationAttachment = (data: unknown): VisualizationC return [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: visualization as LensApiSchemaType, }, ]; diff --git a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/utils.test.ts b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/utils.test.ts index e8aef607736a1..e2f5f087913cc 100644 --- a/x-pack/platform/plugins/shared/dashboard_agent/server/tools/utils.test.ts +++ b/x-pack/platform/plugins/shared/dashboard_agent/server/tools/utils.test.ts @@ -9,6 +9,7 @@ import type { AttachmentStateManager } from '@kbn/agent-builder-server/attachmen import type { VersionedAttachment } from '@kbn/agent-builder-common/attachments'; import type { Logger } from '@kbn/core/server'; import { resolvePanelsFromAttachments } from './manage_dashboard/utils'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; const createMockLogger = (): Logger => ({ @@ -72,7 +73,7 @@ describe('resolvePanelsFromAttachments', () => { expect(result.failures).toEqual([]); expect(result.panels).toHaveLength(1); expect(result.panels[0]).toMatchObject({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { title: 'Request count', attributes: expect.objectContaining({ diff --git a/x-pack/platform/plugins/shared/dashboard_agent/tsconfig.json b/x-pack/platform/plugins/shared/dashboard_agent/tsconfig.json index 5d3824da11832..2b0d4e5078c1c 100644 --- a/x-pack/platform/plugins/shared/dashboard_agent/tsconfig.json +++ b/x-pack/platform/plugins/shared/dashboard_agent/tsconfig.json @@ -23,6 +23,7 @@ "@kbn/css-utils", "@kbn/logging", "@kbn/core-elasticsearch-server", + "@kbn/lens-common", "@kbn/presentation-publishing", "@kbn/core-saved-objects-api-server" ], diff --git a/x-pack/platform/plugins/shared/lens/common/constants.ts b/x-pack/platform/plugins/shared/lens/common/constants.ts index f3b65098355cc..df36b0c5151cb 100644 --- a/x-pack/platform/plugins/shared/lens/common/constants.ts +++ b/x-pack/platform/plugins/shared/lens/common/constants.ts @@ -17,7 +17,6 @@ export const PLUGIN_ID = 'lens'; export const APP_ID = PLUGIN_ID; export const DOC_TYPE = 'lens'; export const LENS_APP_NAME = APP_ID; -export const LENS_EMBEDDABLE_TYPE = DOC_TYPE; export const LENS_DASHBOARD_APP_TYPE = 'lens-dashboard-app'; export const NOT_INTERNATIONALIZED_PRODUCT_NAME = 'Lens Visualizations'; export const LENS_EDIT_BY_VALUE = 'edit_by_value'; diff --git a/x-pack/platform/plugins/shared/lens/public/app_plugin/mounter.tsx b/x-pack/platform/plugins/shared/lens/public/app_plugin/mounter.tsx index 3987ae077efdc..51b8ecabd0156 100644 --- a/x-pack/platform/plugins/shared/lens/public/app_plugin/mounter.tsx +++ b/x-pack/platform/plugins/shared/lens/public/app_plugin/mounter.tsx @@ -38,13 +38,13 @@ import type { LensTopNavMenuEntryGenerator, LensAttributesService, } from '@kbn/lens-common'; -import { LENS_SHARE_STATE_ACTION } from '@kbn/lens-common'; +import { LENS_EMBEDDABLE_TYPE, LENS_SHARE_STATE_ACTION } from '@kbn/lens-common'; import type { LensSerializedAPIConfig } from '@kbn/lens-common-2'; import { ProjectRoutingAccess } from '@kbn/cps-utils'; import { App } from './app'; import { addHelpMenuToAppChrome } from '../help_menu_util'; import type { LensPluginStartDependencies } from '../plugin'; -import { LENS_EMBEDDABLE_TYPE, LENS_EDIT_BY_VALUE, APP_ID } from '../../common/constants'; +import { LENS_EDIT_BY_VALUE, APP_ID } from '../../common/constants'; import type { RedirectToOriginProps, HistoryLocationState } from './types'; import type { LensRootStore } from '../state_management'; import { makeConfigureStore, navigateAway, loadInitial, setState } from '../state_management'; diff --git a/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container.test.tsx b/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container.test.tsx index fc01982cdc564..963d6087cb431 100644 --- a/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container.test.tsx +++ b/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container.test.tsx @@ -10,6 +10,7 @@ import { type SaveVisualizationProps, runSaveLensVisualization } from './save_mo import { defaultDoc, makeDefaultServices } from '../mocks'; import { faker } from '@faker-js/faker'; import { makeAttributeService } from '../mocks/services_mock'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; describe('runSaveLensVisualization', () => { // Need to call reset here as makeDefaultServices() reuses some mocks from core @@ -259,7 +260,7 @@ describe('runSaveLensVisualization', () => { expect.objectContaining({ state: expect.arrayContaining([ expect.objectContaining({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, serializedState: expect.objectContaining({ ref_id: undefined }), }), ]), @@ -289,7 +290,7 @@ describe('runSaveLensVisualization', () => { expect.objectContaining({ state: expect.arrayContaining([ expect.objectContaining({ - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, serializedState: expect.objectContaining({ ref_id: '1234' }), }), ]), diff --git a/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container_helpers.test.ts b/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container_helpers.test.ts index ccb2a5fa89a16..74f34e02b44c4 100644 --- a/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container_helpers.test.ts +++ b/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container_helpers.test.ts @@ -7,7 +7,7 @@ import { makeDefaultServices } from '../mocks'; import { redirectToDashboard } from './save_modal_container_helpers'; import type { LensSerializedState } from '..'; -import type { LensAppServices } from '@kbn/lens-common'; +import { LENS_EMBEDDABLE_TYPE, type LensAppServices } from '@kbn/lens-common'; describe('redirectToDashboard', () => { const embeddableInput = { @@ -30,7 +30,7 @@ describe('redirectToDashboard', () => { }); expect(navigateToWithEmbeddablePackagesSpy).toHaveBeenCalledWith('security', { path: '#/view/id', - state: [{ serializedState: { test: 'test' }, type: 'lens' }], + state: [{ serializedState: { test: 'test' }, type: LENS_EMBEDDABLE_TYPE }], }); }); @@ -49,7 +49,7 @@ describe('redirectToDashboard', () => { }); expect(navigateToWithEmbeddablePackagesSpy).toHaveBeenCalledWith('dashboards', { path: '#/view/id', - state: [{ serializedState: { test: 'test' }, type: 'lens' }], + state: [{ serializedState: { test: 'test' }, type: LENS_EMBEDDABLE_TYPE }], }); }); }); diff --git a/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container_helpers.ts b/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container_helpers.ts index 953f21e231b57..f6d2ea7c0b682 100644 --- a/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container_helpers.ts +++ b/x-pack/platform/plugins/shared/lens/public/app_plugin/save_modal_container_helpers.ts @@ -9,8 +9,11 @@ import { omit } from 'lodash'; import type { ControlPanelsState } from '@kbn/control-group-renderer'; import type { EmbeddablePackageState } from '@kbn/embeddable-plugin/public'; -import type { LensAppServices, LensSerializedState } from '@kbn/lens-common'; -import { LENS_EMBEDDABLE_TYPE } from '../../common/constants'; +import { + LENS_EMBEDDABLE_TYPE, + type LensAppServices, + type LensSerializedState, +} from '@kbn/lens-common'; export const redirectToDashboard = ({ embeddableInput, diff --git a/x-pack/platform/plugins/shared/lens/public/drilldowns/get_discover_drilldown.ts b/x-pack/platform/plugins/shared/lens/public/drilldowns/get_discover_drilldown.ts index bbf4bfbaa37e6..cf132f9f83c55 100644 --- a/x-pack/platform/plugins/shared/lens/public/drilldowns/get_discover_drilldown.ts +++ b/x-pack/platform/plugins/shared/lens/public/drilldowns/get_discover_drilldown.ts @@ -12,7 +12,8 @@ import type { DataViewsService } from '@kbn/data-views-plugin/public'; import type { LensApi } from '@kbn/lens-common-2'; import type { DrilldownDefinition } from '@kbn/embeddable-plugin/public'; import { apiIsOfType, type EmbeddableApiContext } from '@kbn/presentation-publishing'; -import { DISCOVER_DRILLDOWN_SUPPORTED_TRIGGERS, DOC_TYPE } from '../../common/constants'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; +import { DISCOVER_DRILLDOWN_SUPPORTED_TRIGGERS } from '../../common/constants'; import { DiscoverDrilldownEditor } from './editor'; import type { DiscoverDrilldownState } from '../../server'; import type { DiscoverAppLocator } from '../trigger_actions/open_in_discover_helpers'; @@ -87,7 +88,7 @@ export function getDiscoverDrilldown(deps: { }), isCompatible: (context: SetupContext) => deps.hasDiscoverAccess() && - apiIsOfType(context.embeddable, DOC_TYPE) && + apiIsOfType(context.embeddable, LENS_EMBEDDABLE_TYPE) && (context.embeddable as LensApi).isTextBasedLanguage() !== true, isStateValid: () => true, order: 8, diff --git a/x-pack/platform/plugins/shared/lens/public/index.ts b/x-pack/platform/plugins/shared/lens/public/index.ts index bb26636ef3a08..e7e07464ed9ff 100644 --- a/x-pack/platform/plugins/shared/lens/public/index.ts +++ b/x-pack/platform/plugins/shared/lens/public/index.ts @@ -122,7 +122,6 @@ export type { InlineEditLensEmbeddableContext } from './trigger_actions/open_len export type { ChartInfo } from './chart_info_api'; export { LENS_LAYER_TYPES as layerTypes } from '@kbn/lens-common'; -export { LENS_EMBEDDABLE_TYPE } from '../common/constants'; export { EditorFrameServiceProvider, diff --git a/x-pack/platform/plugins/shared/lens/public/plugin.ts b/x-pack/platform/plugins/shared/lens/public/plugin.ts index 6723de3d8fe96..2631098b39bef 100644 --- a/x-pack/platform/plugins/shared/lens/public/plugin.ts +++ b/x-pack/platform/plugins/shared/lens/public/plugin.ts @@ -41,16 +41,17 @@ import type { import { i18n } from '@kbn/i18n'; import type { ChartType } from '@kbn/visualization-utils'; import { DEFAULT_APP_CATEGORIES } from '@kbn/core/public'; -import type { - VisualizationType, - LensAppLocator, - DatasourceMap, - VisualizationMap, - LensTopNavMenuEntryGenerator, - VisualizeEditorContext, - EditorFrameSetup, - LensDocument, - LensByRefSerializedState, +import { + type VisualizationType, + type LensAppLocator, + type DatasourceMap, + type VisualizationMap, + type LensTopNavMenuEntryGenerator, + type VisualizeEditorContext, + type EditorFrameSetup, + type LensDocument, + type LensByRefSerializedState, + LENS_EMBEDDABLE_TYPE, } from '@kbn/lens-common'; import type { Start as InspectorStartContract } from '@kbn/inspector-plugin/public'; import type { DataViewEditorStart } from '@kbn/data-view-editor-plugin/public'; @@ -114,7 +115,6 @@ import { APP_ID, DISCOVER_DRILLDOWN_TYPE, getEditPath, - LENS_EMBEDDABLE_TYPE, LENS_ICON, NOT_INTERNATIONALIZED_PRODUCT_NAME, } from '../common/constants'; diff --git a/x-pack/platform/plugins/shared/lens/public/react_embeddable/lens_embeddable.tsx b/x-pack/platform/plugins/shared/lens/public/react_embeddable/lens_embeddable.tsx index 3d9642ae1564a..2a1797818ff81 100644 --- a/x-pack/platform/plugins/shared/lens/public/react_embeddable/lens_embeddable.tsx +++ b/x-pack/platform/plugins/shared/lens/public/react_embeddable/lens_embeddable.tsx @@ -10,9 +10,8 @@ import type { EmbeddableFactory } from '@kbn/embeddable-plugin/public'; import { initializeTitleManager } from '@kbn/presentation-publishing'; import { initializeUnsavedChanges } from '@kbn/presentation-publishing'; import { merge } from 'rxjs'; -import type { LensRuntimeState } from '@kbn/lens-common'; +import { LENS_EMBEDDABLE_TYPE, type LensRuntimeState } from '@kbn/lens-common'; import type { LensApi, LensSerializedAPIConfig } from '@kbn/lens-common-2'; -import { DOC_TYPE } from '../../common/constants'; import { loadEmbeddableData } from './data_loader'; import { isTextBasedLanguage, deserializeState } from './helper'; @@ -38,7 +37,7 @@ export const createLensEmbeddableFactory = ( services: LensEmbeddableStartServices ): EmbeddableFactory => { return { - type: DOC_TYPE, + type: LENS_EMBEDDABLE_TYPE, /** * This is called after the deserialize, so some assumptions can be made about its arguments: * @param uuid a unique identifier for the embeddable panel diff --git a/x-pack/platform/plugins/shared/lens/public/react_embeddable/mocks/index.tsx b/x-pack/platform/plugins/shared/lens/public/react_embeddable/mocks/index.tsx index 92164fba64194..cc6f884fbff54 100644 --- a/x-pack/platform/plugins/shared/lens/public/react_embeddable/mocks/index.tsx +++ b/x-pack/platform/plugins/shared/lens/public/react_embeddable/mocks/index.tsx @@ -22,19 +22,19 @@ import { chartPluginMock } from '@kbn/charts-plugin/public/mocks'; import type { ReactExpressionRendererProps } from '@kbn/expressions-plugin/public'; import { fieldsMetadataPluginPublicMock } from '@kbn/fields-metadata-plugin/public/mocks'; import type { ESQLControlVariable } from '@kbn/esql-types'; -import type { - Datasource, - DatasourceMap, - Visualization, - VisualizationMap, - ExpressionWrapperProps, - LensInternalApi, - LensRendererProps, - LensRuntimeState, - LensSerializedState, +import { + type Datasource, + type DatasourceMap, + type Visualization, + type VisualizationMap, + type ExpressionWrapperProps, + type LensInternalApi, + type LensRendererProps, + type LensRuntimeState, + type LensSerializedState, + LENS_EMBEDDABLE_TYPE, } from '@kbn/lens-common'; import type { LensApi } from '@kbn/lens-common-2'; -import { DOC_TYPE } from '../../../common/constants'; import { createEmptyLensState } from '../helper'; import { createMockDatasource, createMockVisualization, makeDefaultServices } from '../../mocks'; import { initializeInternalApi } from '../initializers/initialize_internal_api'; @@ -43,7 +43,7 @@ import type { LensEmbeddableStartServices } from '../types'; function getDefaultLensApiMock() { const LensApiMock: LensApi = { // Static props - type: DOC_TYPE, + type: LENS_EMBEDDABLE_TYPE, uuid: faker.string.uuid(), // Shared Embeddable Observables title$: new BehaviorSubject(faker.lorem.words()), diff --git a/x-pack/platform/plugins/shared/lens/public/react_embeddable/renderer/lens_custom_renderer_component.tsx b/x-pack/platform/plugins/shared/lens/public/react_embeddable/renderer/lens_custom_renderer_component.tsx index 8c6dadde4a38e..8c2c06075e743 100644 --- a/x-pack/platform/plugins/shared/lens/public/react_embeddable/renderer/lens_custom_renderer_component.tsx +++ b/x-pack/platform/plugins/shared/lens/public/react_embeddable/renderer/lens_custom_renderer_component.tsx @@ -11,10 +11,13 @@ import { BehaviorSubject } from 'rxjs'; import { EmbeddableRenderer } from '@kbn/embeddable-plugin/public'; import { useSearchApi } from '@kbn/presentation-publishing'; import type { PresentationPanelProps } from '@kbn/presentation-panel-plugin/public'; -import type { LensRendererProps, LensSerializedState } from '@kbn/lens-common'; +import { + LENS_EMBEDDABLE_TYPE, + type LensRendererProps, + type LensSerializedState, +} from '@kbn/lens-common'; import type { LensApi, LensSerializedAPIConfig } from '@kbn/lens-common-2'; -import { LENS_EMBEDDABLE_TYPE } from '../../../common/constants'; import { createEmptyLensState, transformToApiConfig } from '../helper'; import type { LensParentApi } from './types'; @@ -87,12 +90,15 @@ export function LensRenderer({ // Lens API will be set once, but when set trigger a reflow to adopt the latest attributes const [lensApi, setLensApi] = useState(undefined); - // TODO find where people are setting type on attributes to lens - const { - type: _type, - id: _id, - ...cleanedAttributes - } = props.attributes as LensRendererProps['attributes'] & { type: string; id: string }; + const cleanedAttributes = useMemo(() => { + // TODO find where people are setting type on attributes to lens + const { + type: _type, + id: _id, + ...rest + } = props.attributes as LensRendererProps['attributes'] & { type: string; id: string }; + return rest; + }, [props.attributes]); const initialStateRef = useRef( props.attributes ? { attributes: cleanedAttributes } : createEmptyLensState(null, title) ); diff --git a/x-pack/platform/plugins/shared/lens/public/react_embeddable/type_guards.ts b/x-pack/platform/plugins/shared/lens/public/react_embeddable/type_guards.ts index 1251d9a6ec399..6cea6fb706805 100644 --- a/x-pack/platform/plugins/shared/lens/public/react_embeddable/type_guards.ts +++ b/x-pack/platform/plugins/shared/lens/public/react_embeddable/type_guards.ts @@ -11,11 +11,12 @@ import { apiPublishesUnifiedSearch, } from '@kbn/presentation-publishing'; import { isObject } from 'lodash'; -import type { - LensApiCallbacks, - LensPublicCallbacks, - LensComponentForwardedProps, - UserMessage, +import { + type LensApiCallbacks, + type LensPublicCallbacks, + type LensComponentForwardedProps, + type UserMessage, + LENS_EMBEDDABLE_TYPE, } from '@kbn/lens-common'; import type { LensApi } from '@kbn/lens-common-2'; @@ -32,7 +33,7 @@ function apiHasLensCallbacks(api: unknown): api is LensApiCallbacks { export const isLensApi = (api: unknown): api is LensApi => { return Boolean( api && - apiIsOfType(api, 'lens') && + apiIsOfType(api, LENS_EMBEDDABLE_TYPE) && 'canViewUnderlyingData$' in api && apiHasLensCallbacks(api) && apiPublishesTitle(api) && diff --git a/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.ts b/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.ts index 1c12e7f2b1369..0e0c16b044a6e 100644 --- a/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.ts +++ b/x-pack/platform/plugins/shared/lens/public/state_management/shared_logic.ts @@ -11,14 +11,14 @@ import { DataViewPersistableStateService } from '@kbn/data-views-plugin/common'; import type { AggregateQuery, Query, Filter } from '@kbn/es-query'; import type { FilterManager } from '@kbn/data-plugin/public'; import type { Datatable } from '@kbn/expressions-plugin/common'; -import type { - VisualizationState, - DatasourceStates, - DatasourceMap, - VisualizationMap, - Datasource, - LensDocument, - Visualization, +import { + type VisualizationState, + type DatasourceStates, + type DatasourceMap, + type VisualizationMap, + type Datasource, + type LensDocument, + type Visualization, } from '@kbn/lens-common'; import { LENS_ITEM_LATEST_VERSION } from '@kbn/lens-common/content_management/constants'; import { INDEX_PATTERN_TYPE } from '../../common/constants'; diff --git a/x-pack/platform/plugins/shared/lens/public/trigger_actions/open_lens_config/add_esql_panel_action.tsx b/x-pack/platform/plugins/shared/lens/public/trigger_actions/open_lens_config/add_esql_panel_action.tsx index 1750e02d5707a..77a99a361b47e 100644 --- a/x-pack/platform/plugins/shared/lens/public/trigger_actions/open_lens_config/add_esql_panel_action.tsx +++ b/x-pack/platform/plugins/shared/lens/public/trigger_actions/open_lens_config/add_esql_panel_action.tsx @@ -14,6 +14,7 @@ import { apiIsPresentationContainer } from '@kbn/presentation-publishing'; import { ADD_PANEL_VISUALIZATION_GROUP } from '@kbn/embeddable-plugin/public'; import { ENABLE_ESQL } from '@kbn/esql-utils'; import type { LensApi } from '@kbn/lens-common-2'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import { ACTION_CREATE_ESQL_CHART } from './constants'; import { generateId } from '../../id_generator'; import { mountInlinePanel } from '../../react_embeddable/mount'; @@ -55,7 +56,7 @@ export class AddESQLPanelAction implements Action { loadContent: async ({ closeFlyout } = { closeFlyout: () => {} }) => { const embeddable = await api.addNewPanel({ maybePanelId: uuid, - panelType: 'lens', + panelType: LENS_EMBEDDABLE_TYPE, serializedState: { id: uuid, isNewPanel: true, diff --git a/x-pack/platform/plugins/shared/lens/public/vis_type_alias.ts b/x-pack/platform/plugins/shared/lens/public/vis_type_alias.ts index 8f986c3770118..0dd54b2592571 100644 --- a/x-pack/platform/plugins/shared/lens/public/vis_type_alias.ts +++ b/x-pack/platform/plugins/shared/lens/public/vis_type_alias.ts @@ -9,9 +9,9 @@ import { i18n } from '@kbn/i18n'; import type { VisTypeAlias } from '@kbn/visualizations-plugin/public'; import { APP_ID, + DOC_TYPE, getBasePath, getEditPath, - LENS_EMBEDDABLE_TYPE, LENS_ICON, STAGE_ID, } from '../common/constants'; @@ -36,7 +36,7 @@ export const lensVisTypeAlias: VisTypeAlias = { stage: STAGE_ID, appExtensions: { visualizations: { - docTypes: [LENS_EMBEDDABLE_TYPE], + docTypes: [DOC_TYPE], searchFields: ['title^3'], clientOptions: { update: { overwrite: true } }, client: getLensBasicClient, @@ -53,7 +53,7 @@ export const lensVisTypeAlias: VisTypeAlias = { icon: LENS_ICON, stage: STAGE_ID, savedObjectType: type, - type: LENS_EMBEDDABLE_TYPE, + type: DOC_TYPE, typeTitle: i18n.translate('xpack.lens.visTypeAlias.type', { defaultMessage: 'Lens' }), }; }, diff --git a/x-pack/platform/plugins/shared/lens/server/embeddable/make_lens_embeddable_factory.ts b/x-pack/platform/plugins/shared/lens/server/embeddable/make_lens_embeddable_factory.ts index 3a82689d2abfd..7dad63c4a7493 100644 --- a/x-pack/platform/plugins/shared/lens/server/embeddable/make_lens_embeddable_factory.ts +++ b/x-pack/platform/plugins/shared/lens/server/embeddable/make_lens_embeddable_factory.ts @@ -60,6 +60,9 @@ export const makeLensEmbeddableFactory = ) => (): LensEmbeddableRegistryDefinition => { return { + // In 9.4, lens embeddable type changed from 'lens' to 'vis' as part of "as code" project. + // Migrations should be registered with legacy value, 'lens', because + // embeddable migrations are BWC that work on legacy embeddable state id: DOC_TYPE, migrations: () => mergeMigrationFunctionMaps( diff --git a/x-pack/platform/plugins/shared/lens/server/embeddable/types.ts b/x-pack/platform/plugins/shared/lens/server/embeddable/types.ts index a63f4ad0aa580..9943e8adc138b 100644 --- a/x-pack/platform/plugins/shared/lens/server/embeddable/types.ts +++ b/x-pack/platform/plugins/shared/lens/server/embeddable/types.ts @@ -10,12 +10,12 @@ import type { EmbeddableStateWithType, } from '@kbn/embeddable-plugin/server'; +import type { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import type { LensRuntimeState } from '../../public'; -import type { DOC_TYPE } from '../../common/constants'; export type LensEmbeddableStateWithType = EmbeddableStateWithType & LensRuntimeState & { - type: typeof DOC_TYPE; + type: typeof LENS_EMBEDDABLE_TYPE; }; export type LensEmbeddableRegistryDefinition = diff --git a/x-pack/platform/plugins/shared/lens/server/transforms.ts b/x-pack/platform/plugins/shared/lens/server/transforms.ts index 55e30620f6085..73b86e2446202 100644 --- a/x-pack/platform/plugins/shared/lens/server/transforms.ts +++ b/x-pack/platform/plugins/shared/lens/server/transforms.ts @@ -23,8 +23,8 @@ import { ON_OPEN_PANEL_MENU, } from '@kbn/ui-actions-plugin/common/trigger_ids'; import { BY_REF_SCHEMA_META, BY_VALUE_SCHEMA_META } from '@kbn/presentation-publishing-schemas'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import { isByRefLensConfig } from '../common/transforms/utils'; -import { LENS_EMBEDDABLE_TYPE } from '../common/constants'; import { getTransformIn } from '../common/transforms/transform_in'; import { getTransformOut } from '../common/transforms/transform_out'; import type { LensTransforms } from '../common/transforms/types'; diff --git a/x-pack/platform/plugins/shared/ml/moon.yml b/x-pack/platform/plugins/shared/ml/moon.yml index 92c9f72719f93..5db1ed275ead2 100644 --- a/x-pack/platform/plugins/shared/ml/moon.yml +++ b/x-pack/platform/plugins/shared/ml/moon.yml @@ -147,6 +147,7 @@ dependsOn: - '@kbn/as-code-filters-transforms' - '@kbn/cps' - '@kbn/cps-utils' + - '@kbn/lens-common' tags: - plugin - prod diff --git a/x-pack/platform/plugins/shared/ml/public/application/explorer/alerts/chart.tsx b/x-pack/platform/plugins/shared/ml/public/application/explorer/alerts/chart.tsx index ff4bff88432b1..26a9a37a47f71 100644 --- a/x-pack/platform/plugins/shared/ml/public/application/explorer/alerts/chart.tsx +++ b/x-pack/platform/plugins/shared/ml/public/application/explorer/alerts/chart.tsx @@ -11,6 +11,7 @@ import type { TypedLensByValueInput } from '@kbn/lens-plugin/public'; import useObservable from 'react-use/lib/useObservable'; import { css } from '@emotion/react'; import { i18n } from '@kbn/i18n'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import { useAnomalyExplorerContext } from '../anomaly_explorer_context'; import { useMlKibana } from '../../contexts/kibana'; import { Y_AXIS_LABEL_WIDTH } from '../constants'; @@ -42,7 +43,7 @@ export const AnomalyDetectionAlertsOverviewChart: FC { public async isCompatible({ embeddable }: Context) { const { apiIsOfType, hasBlockingError } = await import('@kbn/presentation-publishing'); - const isLensApi = apiIsOfType(embeddable, 'lens'); + const isLensApi = apiIsOfType(embeddable, LENS_EMBEDDABLE_TYPE); if (!isLensApi || hasBlockingError(embeddable)) return false; const query = embeddable.query$.getValue(); return Boolean(query && 'esql' in query); diff --git a/x-pack/platform/plugins/shared/triggers_actions_ui/tsconfig.json b/x-pack/platform/plugins/shared/triggers_actions_ui/tsconfig.json index 9a3862ab29b54..1fd41cc4e1eba 100644 --- a/x-pack/platform/plugins/shared/triggers_actions_ui/tsconfig.json +++ b/x-pack/platform/plugins/shared/triggers_actions_ui/tsconfig.json @@ -97,7 +97,8 @@ "@kbn/cps-utils", "@kbn/cps", "@kbn/security-plugin", - "@kbn/std" + "@kbn/std", + "@kbn/lens-common" ], "exclude": ["target/**/*"] } diff --git a/x-pack/solutions/observability/plugins/observability/server/services/helpers.ts b/x-pack/solutions/observability/plugins/observability/server/services/helpers.ts index 5c20194fa8e23..6089a49a779af 100644 --- a/x-pack/solutions/observability/plugins/observability/server/services/helpers.ts +++ b/x-pack/solutions/observability/plugins/observability/server/services/helpers.ts @@ -8,7 +8,7 @@ import type { SavedObjectReference } from '@kbn/core/server'; import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import type { LensSavedObjectAttributes } from '@kbn/lens-plugin/public'; -import { LENS_CONTENT_TYPE } from '@kbn/lens-common/content_management/constants'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; const SUGGESTED_DASHBOARDS_VALID_RULE_TYPE_IDS = [OBSERVABILITY_THRESHOLD_RULE_TYPE_ID] as const; @@ -25,7 +25,7 @@ export const isSuggestedDashboardsValidRuleTypeId = ( }; // When adding a new panel type TS will make sure we update ReferencedPanelAttributes, getPanelIndicesMap and getPanelFieldsMap -const SUGGESTED_DASHBOARDS_VALID_PANEL_TYPES = [LENS_CONTENT_TYPE] as const; +const SUGGESTED_DASHBOARDS_VALID_PANEL_TYPES = [LENS_EMBEDDABLE_TYPE] as const; export type SuggestedDashboardsValidPanelType = (typeof SUGGESTED_DASHBOARDS_VALID_PANEL_TYPES)[number]; @@ -37,7 +37,7 @@ export const isSuggestedDashboardsValidPanelType = ( }; const PANEL_TYPE_TO_ATTR = { - lens: {} as LensSavedObjectAttributes, + [LENS_EMBEDDABLE_TYPE]: {} as LensSavedObjectAttributes, } satisfies Record; export type ReferencedPanelAttributes = diff --git a/x-pack/solutions/observability/plugins/observability/server/services/related_dashboards_client.test.ts b/x-pack/solutions/observability/plugins/observability/server/services/related_dashboards_client.test.ts index e03cb6b15d754..e12bbc460b42a 100644 --- a/x-pack/solutions/observability/plugins/observability/server/services/related_dashboards_client.test.ts +++ b/x-pack/solutions/observability/plugins/observability/server/services/related_dashboards_client.test.ts @@ -12,6 +12,7 @@ import type { AlertData } from './alert_data'; import { OBSERVABILITY_THRESHOLD_RULE_TYPE_ID } from '@kbn/rule-data-utils'; import { savedObjectsClientMock } from '@kbn/core/server/mocks'; import { ReferencedPanelManager } from './referenced_panel_manager'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; describe('RelatedDashboardsClient', () => { const mockGetDashboard = jest.fn(); @@ -117,7 +118,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard 1', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { references: [ @@ -131,7 +132,7 @@ describe('RelatedDashboardsClient', () => { }, }, }, - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, }, }, }, @@ -142,7 +143,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard 2', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { references: [ @@ -156,7 +157,7 @@ describe('RelatedDashboardsClient', () => { }, }, }, - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, }, }, }, @@ -199,7 +200,7 @@ describe('RelatedDashboardsClient', () => { title: `Dashboard ${i + 1}`, panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { references: [ @@ -211,7 +212,7 @@ describe('RelatedDashboardsClient', () => { formBased: { layers: [{ columns: [{ sourceField: 'field1' }] }] }, }, }, - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, }, }, }, @@ -244,7 +245,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard 1', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, uid: '123', config: { attributes: { @@ -254,7 +255,7 @@ describe('RelatedDashboardsClient', () => { formBased: { layers: [{ columns: [{ sourceField: 'field1' }] }] }, // matches by field which is handled by getDashboardsByField }, }, - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, }, }, }, @@ -313,7 +314,7 @@ describe('RelatedDashboardsClient', () => { it('should fetch referenced panels when fetching dashboards', async () => { const PANEL_SO_ID = 'panelSOId'; - const PANEL_TYPE = 'lens'; + const PANEL_TYPE = LENS_EMBEDDABLE_TYPE; const PANEL_UID = 'panelUid'; const PANEL_SO_ATTRIBUTES = { title: 'Panel 1' }; mockScanDashboards.mockResolvedValue({ @@ -346,7 +347,7 @@ describe('RelatedDashboardsClient', () => { it('should not refetch a referenced panel if it was fetched before', async () => { const PANEL_SO_ID = 'panelSOId'; - const PANEL_TYPE = 'lens'; + const PANEL_TYPE = LENS_EMBEDDABLE_TYPE; const PANEL_UID = 'panelUid'; const OTHER_PANEL_UID = 'otherPanelUid'; const PANEL_SO_ATTRIBUTES = { title: 'Panel 1' }; @@ -392,10 +393,10 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard 1', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, references: [ { name: 'indexpattern', id: 'index2' }, { name: 'irrelevant', id: 'index1' }, @@ -426,7 +427,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard 1', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: null, // Lens attributes are not available }, @@ -450,7 +451,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard missing attributes', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, id: PANEL_UID, config: {}, }, @@ -481,7 +482,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard 1', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, config: { attributes: null, // Lens attributes are not available }, @@ -503,7 +504,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard missing state', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, id: PANEL_UID, config: {}, }, @@ -762,7 +763,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard 1', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, uid: '123', config: { attributes: { @@ -772,7 +773,7 @@ describe('RelatedDashboardsClient', () => { formBased: { layers: [{ columns: [{ sourceField: 'field1' }] }] }, // matches by field which is handled by getDashboardsByField }, }, - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, }, }, }, @@ -783,7 +784,7 @@ describe('RelatedDashboardsClient', () => { title: 'Dashboard 2', panels: [ { - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, uid: '123', config: { attributes: { @@ -793,7 +794,7 @@ describe('RelatedDashboardsClient', () => { formBased: { layers: [{ columns: [{ sourceField: 'field2' }] }] }, }, }, - type: 'lens', + type: LENS_EMBEDDABLE_TYPE, }, }, }, diff --git a/x-pack/solutions/observability/plugins/observability/server/services/related_dashboards_client.ts b/x-pack/solutions/observability/plugins/observability/server/services/related_dashboards_client.ts index 345af5cdf9306..b28f773b7ed85 100644 --- a/x-pack/solutions/observability/plugins/observability/server/services/related_dashboards_client.ts +++ b/x-pack/solutions/observability/plugins/observability/server/services/related_dashboards_client.ts @@ -13,7 +13,7 @@ import type { ScanDashboardsResult, DashboardReadResponseBody, } from '@kbn/dashboard-plugin/server'; -import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-plugin/common/constants'; +import { LENS_EMBEDDABLE_TYPE } from '@kbn/lens-common'; import type { FieldBasedIndexPatternColumn, GenericIndexPatternColumn, @@ -75,7 +75,7 @@ export class RelatedDashboardsClient { SuggestedDashboardsValidPanelType, (panel: DashboardPanel) => Set | undefined > = { - lens: (panel: DashboardPanel) => { + [LENS_EMBEDDABLE_TYPE]: (panel: DashboardPanel) => { let references = this.isLensVizAttributes(panel.type, panel.config) ? panel.config.attributes.references : undefined; @@ -94,7 +94,7 @@ export class RelatedDashboardsClient { SuggestedDashboardsValidPanelType, (panel: DashboardPanel) => Set | undefined > = { - lens: (panel: DashboardPanel) => { + [LENS_EMBEDDABLE_TYPE]: (panel: DashboardPanel) => { let state: unknown = this.isLensVizAttributes(panel.type, panel.config) ? panel.config.attributes.state : undefined;