Skip to content

Commit

Permalink
[Embeddables Rebuild] Clone panels with runtime state (#186052)
Browse files Browse the repository at this point in the history
Makes the clone operation use runtime state rather than serialized state.
  • Loading branch information
ThomThomson authored Jun 20, 2024
1 parent 0468b8f commit 7e19cc5
Show file tree
Hide file tree
Showing 20 changed files with 441 additions and 214 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ export const ControlRenderer = <
return fullApi;
};

const { rawState: initialState } = parentApi.getSerializedStateForChild(uuid);
const { rawState: initialState } = parentApi.getSerializedStateForChild(uuid) ?? {};

const { api, Component } = factory.buildControl(
initialState as unknown as StateType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
const bookSerializedStateIsByReference = (
state?: BookSerializedState
): state is BookByReferenceSerializedState => {
return Boolean(state && (state as BookByReferenceSerializedState).savedBookId !== undefined);
return Boolean(state && (state as BookByReferenceSerializedState).savedBookId);
};

export const getSavedBookEmbeddableFactory = (core: CoreStart) => {
Expand Down Expand Up @@ -86,7 +86,7 @@ export const getSavedBookEmbeddableFactory = (core: CoreStart) => {
defaultMessage: 'book',
}),
serializeState: async () => {
if (savedBookId$.value === undefined) {
if (!Boolean(savedBookId$.value)) {
// if this book is currently by value, we serialize the entire state.
const bookByValueState: BookByValueSerializedState = {
attributes: serializeBookAttributes(bookAttributesManager),
Expand All @@ -97,7 +97,7 @@ export const getSavedBookEmbeddableFactory = (core: CoreStart) => {

// if this book is currently by reference, we serialize the reference and write to the external store.
const bookByReferenceState: BookByReferenceSerializedState = {
savedBookId: savedBookId$.value,
savedBookId: savedBookId$.value!,
...serializeTitles(),
};

Expand All @@ -123,6 +123,11 @@ export const getSavedBookEmbeddableFactory = (core: CoreStart) => {
unlinkFromLibrary: () => {
savedBookId$.next(undefined);
},
getByValueRuntimeSnapshot: () => {
const snapshot = api.snapshotRuntimeState();
delete snapshot.savedBookId;
return snapshot;
},
},
{
savedBookId: [savedBookId$, (val) => savedBookId$.next(val)],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,4 @@ export interface BookRuntimeState

export type BookApi = DefaultEmbeddableApi<BookSerializedState, BookRuntimeState> &
HasEditCapabilities &
HasInPlaceLibraryTransforms;
HasInPlaceLibraryTransforms<BookRuntimeState>;
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
import { SerializedPanelState } from './serialized_state';

export interface HasSerializedChildState<SerializedState extends object = object> {
getSerializedStateForChild: (childId: string) => SerializedPanelState<SerializedState>;
getSerializedStateForChild: (
childId: string
) => SerializedPanelState<SerializedState> | undefined;
}

export interface HasRuntimeChildState<RuntimeState extends object = object> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ export const apiHasSerializableState = (api: unknown | null): api is HasSerializ

export interface HasSnapshottableState<RuntimeState extends object = object> {
/**
* Serializes all runtime state exactly as it appears. This could be used
* to rehydrate a component's state without needing to deserialize it.
* Serializes all runtime state exactly as it appears. This can be used
* to rehydrate a component's state without needing to serialize then deserialize it.
*/
snapshotRuntimeState: () => RuntimeState;
}
Expand Down
18 changes: 11 additions & 7 deletions packages/presentation/presentation_publishing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ export interface EmbeddableApiContext {

export {
getInitialValuesFromComparators,
runComparators,
getUnchangingComparator,
runComparators,
type ComparatorDefinition,
type ComparatorFunction,
type StateComparators,
Expand All @@ -35,22 +35,22 @@ export {
type SerializedTimeRange,
} from './interfaces/fetch/initialize_time_range';
export {
apiPublishesPartialUnifiedSearch,
apiPublishesFilters,
apiPublishesPartialUnifiedSearch,
apiPublishesTimeRange,
apiPublishesUnifiedSearch,
apiPublishesWritableUnifiedSearch,
useSearchApi,
type PublishesTimeRange,
type PublishesFilters,
type PublishesTimeRange,
type PublishesTimeslice,
type PublishesUnifiedSearch,
type PublishesWritableUnifiedSearch,
type PublishesTimeslice,
} from './interfaces/fetch/publishes_unified_search';
export {
apiHasAppContext,
type HasAppContext,
type EmbeddableAppContext,
type HasAppContext,
} from './interfaces/has_app_context';
export {
apiHasDisableTriggers,
Expand All @@ -63,9 +63,9 @@ export {
type HasExecutionContext,
} from './interfaces/has_execution_context';
export {
apiHasInPlaceLibraryTransforms,
apiHasLegacyLibraryTransforms,
apiHasLibraryTransforms,
apiHasInPlaceLibraryTransforms,
type HasInPlaceLibraryTransforms,
type HasLegacyLibraryTransforms,
type HasLibraryTransforms,
Expand Down Expand Up @@ -130,7 +130,11 @@ export {
type PublishesPanelTitle,
type PublishesWritablePanelTitle,
} from './interfaces/titles/publishes_panel_title';
export { initializeTitles, type SerializedTitles } from './interfaces/titles/titles_api';
export {
initializeTitles,
stateHasTitles,
type SerializedTitles,
} from './interfaces/titles/titles_api';
export {
useBatchedOptionalPublishingSubjects,
useBatchedPublishingSubjects,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interface LibraryTransformGuards {
* APIs that inherit this interface can be linked to and unlinked from the library in place without
* re-initialization.
*/
export interface HasInPlaceLibraryTransforms
export interface HasInPlaceLibraryTransforms<RuntimeState extends object = object>
extends Partial<LibraryTransformGuards>,
DuplicateTitleCheck {
/**
Expand All @@ -49,6 +49,11 @@ export interface HasInPlaceLibraryTransforms
*/
saveToLibrary: (title: string) => Promise<string>;

/**
* gets a snapshot of this embeddable's runtime state without any state that links it to a library item.
*/
getByValueRuntimeSnapshot: () => RuntimeState;

/**
* Un-links this embeddable from the library. This method is optional, and only needed if the Embeddable
* is not meant to be re-initialized as part of the unlink operation. If the embeddable needs to be re-initialized
Expand All @@ -69,6 +74,7 @@ export const apiHasInPlaceLibraryTransforms = (
};

/**
* @deprecated use HasInPlaceLibraryTransforms instead
* APIs that inherit this interface can be linked to and unlinked from the library. After the save or unlink
* operation, the embeddable will be reinitialized.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ export interface SerializedTitles {
hidePanelTitles?: boolean;
}

export const stateHasTitles = (state: unknown): state is SerializedTitles => {
return (
(state as SerializedTitles)?.title !== undefined ||
(state as SerializedTitles)?.description !== undefined ||
(state as SerializedTitles)?.hidePanelTitles !== undefined
);
};

export interface TitlesApi extends PublishesWritablePanelTitle, PublishesWritablePanelDescription {}

export const initializeTitles = (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class UnlinkFromLibraryAction implements Action<EmbeddableApiContext> {
return api.canUnlinkFromLibrary();
} else if (apiHasInPlaceLibraryTransforms(api)) {
const canUnLink = api.canUnlinkFromLibrary ? await api.canUnlinkFromLibrary() : true;
return canUnLink && api.libraryId$.value !== undefined;
return canUnLink && Boolean(api.libraryId$.value);
}
throw new IncompatibleActionError();
}
Expand Down

This file was deleted.

Loading

0 comments on commit 7e19cc5

Please sign in to comment.