diff --git a/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_edit.tsx b/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_edit.tsx index c9641deb4f2fc..8091e64e715cf 100644 --- a/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_edit.tsx +++ b/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_edit.tsx @@ -37,6 +37,7 @@ import { setupPanelManagement } from '../inline_editing/panel_management'; import { mountInlineEditPanel } from '../inline_editing/mount'; import { StateManagementConfig } from './initialize_state_management'; import { apiPublishesInlineEditingCapabilities } from '../type_guards'; +import { SearchContextConfig } from './initialize_search_context'; function getSupportedTriggers( getState: GetStateType, @@ -61,6 +62,7 @@ export function initializeEditApi( internalApi: LensInternalApi, stateApi: StateManagementConfig['api'], inspectorApi: LensInspectorAdapters, + searchContextApi: SearchContextConfig['api'], isTextBasedLanguage: (currentState: LensRuntimeState) => boolean, startDependencies: LensEmbeddableStartServices, parentApi?: unknown @@ -126,9 +128,34 @@ export function initializeEditApi( stateApi.updateSavedObjectId(newState.savedObjectId); }; + // Wrap the getState() when inline editing and make sure that the filters in the attributes + // are properly injected with the correct references to avoid issues when saving/navigating to the full editor + const getStateWithInjectedFilters = () => { + const currentState = getState(); + // use the search context api here for filters for 2 reasons: + // * the filters here have the correct references already injected + // * the edit filters flow may change in the future and this is the right place to get the filters + const currentFilters = searchContextApi.filters$.getValue() ?? []; + // if there are no filters, avoid to copy the attributes + if (!currentFilters.length) { + return currentState; + } + // otherwise make sure to inject the references into filters + return { + ...currentState, + attributes: { + ...currentState.attributes, + state: { + ...currentState.attributes.state, + filters: currentFilters, + }, + }, + }; + }; + const openInlineEditor = prepareInlineEditPanel( initialState, - getState, + getStateWithInjectedFilters, updateState, internalApi, panelManagementApi, @@ -206,6 +233,9 @@ export function initializeEditApi( const rootEmbeddable = parentApi; const overlayTracker = tracksOverlays(rootEmbeddable) ? rootEmbeddable : undefined; const ConfigPanel = await openInlineEditor({ + // the getState() here contains the wrong filters references + // but the input attributes are correct as openInlineEditor() handler is using + // the getStateWithInjectedFilters() function onApply: (attributes: LensRuntimeState['attributes']) => updateState({ ...getState(), attributes }), // restore the first state found when the panel opened diff --git a/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_search_context.ts b/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_search_context.ts index 1a608de11e230..1d95fd49b3f55 100644 --- a/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_search_context.ts +++ b/x-pack/plugins/lens/public/react_embeddable/initializers/initialize_search_context.ts @@ -18,18 +18,26 @@ import { apiPublishesSearchSession, } from '@kbn/presentation-publishing/interfaces/fetch/publishes_search_session'; import { buildObservableVariable } from '../helper'; -import { LensInternalApi, LensRuntimeState, LensUnifiedSearchContext } from '../types'; +import { + LensEmbeddableStartServices, + LensInternalApi, + LensRuntimeState, + LensUnifiedSearchContext, +} from '../types'; -export function initializeSearchContext( - initialState: LensRuntimeState, - internalApi: LensInternalApi, - parentApi: unknown -): { +export interface SearchContextConfig { api: PublishesUnifiedSearch & PublishesSearchSession; comparators: StateComparators; serialize: () => LensUnifiedSearchContext; cleanup: () => void; -} { +} + +export function initializeSearchContext( + initialState: LensRuntimeState, + internalApi: LensInternalApi, + parentApi: unknown, + { injectFilterReferences }: LensEmbeddableStartServices +): SearchContextConfig { const [searchSessionId$] = buildObservableVariable( apiPublishesSearchSession(parentApi) ? parentApi.searchSessionId$ : undefined ); @@ -38,7 +46,10 @@ export function initializeSearchContext( const [lastReloadRequestTime] = buildObservableVariable(undefined); - const [filters$] = buildObservableVariable(attributes.state.filters); + // Make sure the panel access the filters with the correct references + const [filters$] = buildObservableVariable( + injectFilterReferences(attributes.state.filters, attributes.references) + ); const [query$] = buildObservableVariable( attributes.state.query diff --git a/x-pack/plugins/lens/public/react_embeddable/lens_embeddable.tsx b/x-pack/plugins/lens/public/react_embeddable/lens_embeddable.tsx index 2fc1928dc40c8..c193e02c06f0e 100644 --- a/x-pack/plugins/lens/public/react_embeddable/lens_embeddable.tsx +++ b/x-pack/plugins/lens/public/react_embeddable/lens_embeddable.tsx @@ -84,6 +84,13 @@ export const createLensEmbeddableFactory = ( const inspectorConfig = initializeInspector(services); + const searchContextConfig = initializeSearchContext( + initialState, + internalApi, + parentApi, + services + ); + const editConfig = initializeEditApi( uuid, initialState, @@ -91,12 +98,12 @@ export const createLensEmbeddableFactory = ( internalApi, stateConfig.api, inspectorConfig.api, + searchContextConfig.api, isTextBasedLanguage, services, parentApi ); - const searchContextConfig = initializeSearchContext(initialState, internalApi, parentApi); const integrationsConfig = initializeIntegrations(getState, services); const actionsConfig = initializeActionApi( uuid,