[embeddable] update DefaultPresentationPanelApi to define parentApi as unknown (#218668)

DefaultPresentationPanelApi should define parentApi as unknown.

`ReactEmbeddableRenderer` renders panels with `PresentationPanel`.
`PresentationPanel` takes `api: DefaultPresentationPanelApi` as a prop
and `DefaultPresentationPanelApi` should not define ParentApi type more
precisely then its defined in `ReactEmbeddableRenderer`.
`ReactEmbeddableRenderer` defines parent as `ParentApi extends
HasSerializedChildState<SerializedState> =
HasSerializedChildState<SerializedState>`.

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2025-04-22 08:54:50 -06:00 committed by GitHub
parent 60af3ff3d5
commit 678b53a1a7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 16 additions and 24 deletions

View file

@ -29,7 +29,7 @@ import {
useBatchedPublishingSubjects, useBatchedPublishingSubjects,
} from '@kbn/presentation-publishing'; } from '@kbn/presentation-publishing';
import React from 'react'; import React from 'react';
import { PresentationContainer } from '@kbn/presentation-containers'; import { PresentationContainer, apiIsPresentationContainer } from '@kbn/presentation-containers';
import { serializeBookAttributes, stateManagerFromAttributes } from './book_state'; import { serializeBookAttributes, stateManagerFromAttributes } from './book_state';
import { SAVED_BOOK_ID } from './constants'; import { SAVED_BOOK_ID } from './constants';
import { openSavedBookEditor } from './saved_book_editor'; import { openSavedBookEditor } from './saved_book_editor';
@ -116,8 +116,11 @@ export const getSavedBookEmbeddableFactory = (core: CoreStart) => {
const nextIsByReference = Boolean(result.savedBookId); const nextIsByReference = Boolean(result.savedBookId);
// if the by reference state has changed during this edit, reinitialize the panel. // if the by reference state has changed during this edit, reinitialize the panel.
if (nextIsByReference !== isByReference) { if (
api.parentApi?.replacePanel<BookSerializedState>(api.uuid, { nextIsByReference !== isByReference &&
apiIsPresentationContainer(api.parentApi)
) {
api.parentApi.replacePanel<BookSerializedState>(api.uuid, {
serializedState: serializeBook(nextIsByReference, result.savedBookId), serializedState: serializeBook(nextIsByReference, result.savedBookId),
panelType: api.type, panelType: api.type,
}); });

View file

@ -28,14 +28,14 @@ export const apiCanAccessViewMode = (api: unknown): api is CanAccessViewMode =>
* A function which will get the view mode from the API or the parent API. if this api has a view mode AND its * A function which will get the view mode from the API or the parent API. if this api has a view mode AND its
* parent has a view mode, we consider the APIs version the source of truth. * parent has a view mode, we consider the APIs version the source of truth.
*/ */
export const getInheritedViewMode = (api?: CanAccessViewMode) => { export const getInheritedViewMode = (api?: unknown) => {
if (apiPublishesViewMode(api)) return api.viewMode$.getValue(); if (apiPublishesViewMode(api)) return api.viewMode$.getValue();
if (apiHasParentApi(api) && apiPublishesViewMode(api.parentApi)) { if (apiHasParentApi(api) && apiPublishesViewMode(api.parentApi)) {
return api.parentApi.viewMode$.getValue(); return api.parentApi.viewMode$.getValue();
} }
}; };
export const getViewModeSubject = (api?: CanAccessViewMode) => { export const getViewModeSubject = (api?: unknown) => {
if (apiPublishesViewMode(api)) return api.viewMode$; if (apiPublishesViewMode(api)) return api.viewMode$;
if (apiHasParentApi(api) && apiPublishesViewMode(api.parentApi)) { if (apiHasParentApi(api) && apiPublishesViewMode(api.parentApi)) {
return api.parentApi.viewMode$; return api.parentApi.viewMode$;

View file

@ -21,6 +21,7 @@ import {
} from '@kbn/presentation-publishing'; } from '@kbn/presentation-publishing';
import { css } from '@emotion/react'; import { css } from '@emotion/react';
import { apiIsPresentationContainer } from '@kbn/presentation-containers';
import { import {
CONTENT_ID, CONTENT_ID,
DASHBOARD_LINK_TYPE, DASHBOARD_LINK_TYPE,
@ -181,14 +182,14 @@ export const getLinksEmbeddableFactory = () => {
// if the by reference state has changed during this edit, reinitialize the panel. // if the by reference state has changed during this edit, reinitialize the panel.
const nextIsByReference = Boolean(newState?.savedObjectId); const nextIsByReference = Boolean(newState?.savedObjectId);
if (nextIsByReference !== isByReference) { if (nextIsByReference !== isByReference && apiIsPresentationContainer(api.parentApi)) {
const serializedState = serializeLinksState( const serializedState = serializeLinksState(
nextIsByReference, nextIsByReference,
newState?.savedObjectId newState?.savedObjectId
); );
(serializedState.rawState as SerializedTitles).title = newState.title; (serializedState.rawState as SerializedTitles).title = newState.title;
api.parentApi?.replacePanel<LinksSerializedState>(api.uuid, { api.parentApi.replacePanel<LinksSerializedState>(api.uuid, {
serializedState, serializedState,
panelType: api.type, panelType: api.type,
}); });

View file

@ -37,6 +37,7 @@ import { css } from '@emotion/react';
import { import {
apiCanLockHoverActions, apiCanLockHoverActions,
EmbeddableApiContext, EmbeddableApiContext,
PublishesTitle,
useBatchedOptionalPublishingSubjects, useBatchedOptionalPublishingSubjects,
ViewMode, ViewMode,
} from '@kbn/presentation-publishing'; } from '@kbn/presentation-publishing';
@ -147,7 +148,7 @@ export const PresentationPanelHoverActions = ({
api?.description$, api?.description$,
api?.hideTitle$, api?.hideTitle$,
api?.hasLockedHoverActions$, api?.hasLockedHoverActions$,
api?.parentApi?.hideTitle$ (api?.parentApi as Partial<PublishesTitle>)?.hideTitle$
); );
const hideTitle = hidePanelTitle || parentHideTitle; const hideTitle = hidePanelTitle || parentHideTitle;

View file

@ -11,6 +11,7 @@ import { EuiErrorBoundary, EuiFlexGroup, EuiPanel, htmlIdGenerator } from '@elas
import { css } from '@emotion/react'; import { css } from '@emotion/react';
import { PanelLoader } from '@kbn/panel-loader'; import { PanelLoader } from '@kbn/panel-loader';
import { import {
PublishesTitle,
apiHasParentApi, apiHasParentApi,
apiPublishesViewMode, apiPublishesViewMode,
useBatchedOptionalPublishingSubjects, useBatchedOptionalPublishingSubjects,
@ -72,7 +73,7 @@ export const PresentationPanelInternal = <
api?.defaultTitle$, api?.defaultTitle$,
api?.defaultDescription$, api?.defaultDescription$,
viewModeSubject, viewModeSubject,
api?.parentApi?.hideTitle$ (api?.parentApi as Partial<PublishesTitle>)?.hideTitle$
); );
const viewMode = rawViewMode ?? 'view'; const viewMode = rawViewMode ?? 'view';

View file

@ -7,7 +7,6 @@
* License v3.0 only", or the "Server Side Public License, v 1". * License v3.0 only", or the "Server Side Public License, v 1".
*/ */
import { PresentationContainer } from '@kbn/presentation-containers';
import { import {
CanLockHoverActions, CanLockHoverActions,
HasParentApi, HasParentApi,
@ -17,7 +16,6 @@ import {
PublishesDisabledActionIds, PublishesDisabledActionIds,
PublishesDescription, PublishesDescription,
PublishesTitle, PublishesTitle,
PublishesViewMode,
} from '@kbn/presentation-publishing'; } from '@kbn/presentation-publishing';
import { UiActionsService } from '@kbn/ui-actions-plugin/public'; import { UiActionsService } from '@kbn/ui-actions-plugin/public';
import { MaybePromise } from '@kbn/utility-types'; import { MaybePromise } from '@kbn/utility-types';
@ -79,9 +77,7 @@ export interface DefaultPresentationPanelApi
PublishesBlockingError & PublishesBlockingError &
PublishesDescription & PublishesDescription &
PublishesDisabledActionIds & PublishesDisabledActionIds &
HasParentApi< HasParentApi &
PresentationContainer & Partial<Pick<PublishesTitle, 'hideTitle$'> & PublishesViewMode>
> &
CanLockHoverActions CanLockHoverActions
> {} > {}

View file

@ -117,12 +117,6 @@ async function expectRerenderOnDataLoader(
onBrushEnd: jest.fn(), onBrushEnd: jest.fn(),
onFilter: jest.fn(), onFilter: jest.fn(),
onTableRowClick: jest.fn(), onTableRowClick: jest.fn(),
// Make TS happy
removePanel: jest.fn(),
replacePanel: jest.fn(),
getPanelCount: jest.fn(),
children$: new BehaviorSubject({}),
addNewPanel: jest.fn(),
...parentApiOverrides, ...parentApiOverrides,
}; };
const api: LensApi = { const api: LensApi = {

View file

@ -17,7 +17,6 @@ import type { ESQLControlVariable } from '@kbn/esql-types';
import type { import type {
HasEditCapabilities, HasEditCapabilities,
HasLibraryTransforms, HasLibraryTransforms,
HasParentApi,
HasSupportedTriggers, HasSupportedTriggers,
PublishesBlockingError, PublishesBlockingError,
PublishesDataLoading, PublishesDataLoading,
@ -64,7 +63,6 @@ import type { AllowedGaugeOverrides } from '@kbn/expression-gauge-plugin/common'
import type { AllowedPartitionOverrides } from '@kbn/expression-partition-vis-plugin/common'; import type { AllowedPartitionOverrides } from '@kbn/expression-partition-vis-plugin/common';
import type { AllowedXYOverrides } from '@kbn/expression-xy-plugin/common'; import type { AllowedXYOverrides } from '@kbn/expression-xy-plugin/common';
import type { Action } from '@kbn/ui-actions-plugin/public'; import type { Action } from '@kbn/ui-actions-plugin/public';
import { PresentationContainer } from '@kbn/presentation-containers';
import { PublishesSearchSession } from '@kbn/presentation-publishing/interfaces/fetch/publishes_search_session'; import { PublishesSearchSession } from '@kbn/presentation-publishing/interfaces/fetch/publishes_search_session';
import type { LegacyMetricState } from '../../common'; import type { LegacyMetricState } from '../../common';
import type { LensDocument } from '../persistence'; import type { LensDocument } from '../persistence';
@ -401,8 +399,6 @@ export type LensApi = Simplify<
HasLibraryTransforms<LensSerializedState, LensSerializedState> & HasLibraryTransforms<LensSerializedState, LensSerializedState> &
// Let the container know the view mode // Let the container know the view mode
PublishesViewMode & PublishesViewMode &
// forward the parentApi, note that will be exposed only if it satisfy the PresentationContainer interface
Partial<HasParentApi<PresentationContainer>> &
// Let the container know the saved object id // Let the container know the saved object id
PublishesSavedObjectId & PublishesSavedObjectId &
// Lens specific API methods: // Lens specific API methods: