[Embeddables Rebuild] Fix runtime state types. (#186194)

Fixes runtime state types, requiring them to be specified twice.
This commit is contained in:
Devon Thomson 2024-06-19 10:05:27 -04:00 committed by GitHub
parent 05723d4775
commit 6d39b8a432
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
36 changed files with 293 additions and 205 deletions

View file

@ -52,8 +52,8 @@ export const getControlGroupEmbeddableFactory = (services: {
}) => {
const controlGroupEmbeddableFactory: ReactEmbeddableFactory<
ControlGroupSerializedState,
ControlGroupApi,
ControlGroupRuntimeState
ControlGroupRuntimeState,
ControlGroupApi
> = {
type: CONTROL_GROUP_TYPE,
deserializeState: (state) => deserializeControlGroup(state),
@ -117,7 +117,7 @@ export const getControlGroupEmbeddableFactory = (services: {
},
snapshotRuntimeState: () => {
// TODO: Remove this if it ends up being unnecessary
return {} as unknown as ControlGroupSerializedState;
return {} as unknown as ControlGroupRuntimeState;
},
dataLoading: dataLoading$,
children$: children$ as PublishingSubject<{

View file

@ -42,7 +42,7 @@ export type ControlGroupUnsavedChanges = Omit<
export type ControlPanelState = DefaultControlState & { type: string; order: number };
export type ControlGroupApi = PresentationContainer &
DefaultEmbeddableApi<ControlGroupSerializedState> &
DefaultEmbeddableApi<ControlGroupSerializedState, ControlGroupRuntimeState> &
PublishesFilters &
PublishesDataViews &
HasSerializedChildState<ControlPanelState> &

View file

@ -98,7 +98,7 @@ export const RenderExamples = () => {
<EuiSpacer size="s" />
<ReactEmbeddableRenderer<SearchSerializedState, SearchApi>
<ReactEmbeddableRenderer<SearchSerializedState, SearchSerializedState, SearchApi>
key={hidePanelChrome ? 'hideChrome' : 'showChrome'}
type={SEARCH_EMBEDDABLE_ID}
getParentApi={() => parentApi}

View file

@ -26,12 +26,12 @@ import { BehaviorSubject } from 'rxjs';
import { StartDeps } from '../../plugin';
import { DATA_TABLE_ID } from './constants';
import { initializeDataTableQueries } from './data_table_queries';
import { DataTableApi, DataTableSerializedState } from './types';
import { DataTableApi, DataTableRuntimeState, DataTableSerializedState } from './types';
export const getDataTableFactory = (
core: CoreStart,
services: StartDeps
): ReactEmbeddableFactory<DataTableSerializedState, DataTableApi> => ({
): ReactEmbeddableFactory<DataTableSerializedState, DataTableRuntimeState, DataTableApi> => ({
type: DATA_TABLE_ID,
deserializeState: (state) => {
return state.rawState as DataTableSerializedState;

View file

@ -15,4 +15,6 @@ import {
export type DataTableSerializedState = SerializedTitles & SerializedTimeRange;
export type DataTableRuntimeState = DataTableSerializedState;
export type DataTableApi = DefaultEmbeddableApi<DataTableSerializedState> & PublishesDataLoading;

View file

@ -19,10 +19,15 @@ import { euiThemeVars } from '@kbn/ui-theme';
import React from 'react';
import { BehaviorSubject } from 'rxjs';
import { EUI_MARKDOWN_ID } from './constants';
import { MarkdownEditorSerializedState, MarkdownEditorApi } from './types';
import {
MarkdownEditorApi,
MarkdownEditorRuntimeState,
MarkdownEditorSerializedState,
} from './types';
export const markdownEmbeddableFactory: ReactEmbeddableFactory<
MarkdownEditorSerializedState,
MarkdownEditorRuntimeState,
MarkdownEditorApi
> = {
type: EUI_MARKDOWN_ID,

View file

@ -13,4 +13,6 @@ export type MarkdownEditorSerializedState = SerializedTitles & {
content: string;
};
export type MarkdownEditorRuntimeState = MarkdownEditorSerializedState;
export type MarkdownEditorApi = DefaultEmbeddableApi<MarkdownEditorSerializedState>;

View file

@ -25,7 +25,12 @@ import { cloneDeep } from 'lodash';
import React, { useEffect } from 'react';
import { BehaviorSubject, skip, Subscription, switchMap } from 'rxjs';
import { FIELD_LIST_DATA_VIEW_REF_NAME, FIELD_LIST_ID } from './constants';
import { FieldListApi, Services, FieldListSerializedStateState } from './types';
import {
FieldListApi,
Services,
FieldListSerializedStateState,
FieldListRuntimeState,
} from './types';
const DataViewPicker = withSuspense(LazyDataViewPicker, null);
@ -46,6 +51,7 @@ export const getFieldListFactory = (
) => {
const fieldListEmbeddableFactory: ReactEmbeddableFactory<
FieldListSerializedStateState,
FieldListRuntimeState,
FieldListApi
> = {
type: FIELD_LIST_ID,

View file

@ -19,7 +19,14 @@ export type FieldListSerializedStateState = SerializedTitles & {
selectedFieldNames?: string[];
};
export type FieldListApi = DefaultEmbeddableApi & PublishesSelectedFields & PublishesDataViews;
export type FieldListRuntimeState = FieldListSerializedStateState;
export type FieldListApi = DefaultEmbeddableApi<
FieldListSerializedStateState,
FieldListSerializedStateState
> &
PublishesSelectedFields &
PublishesDataViews;
export interface Services {
dataViews: DataViewsPublicPluginStart;

View file

@ -41,8 +41,8 @@ const bookSerializedStateIsByReference = (
export const getSavedBookEmbeddableFactory = (core: CoreStart) => {
const savedBookEmbeddableFactory: ReactEmbeddableFactory<
BookSerializedState,
BookApi,
BookRuntimeState
BookRuntimeState,
BookApi
> = {
type: SAVED_BOOK_ID,
deserializeState: async (serializedState) => {

View file

@ -45,6 +45,6 @@ export interface BookRuntimeState
Partial<BookByReferenceSerializedState>,
SerializedTitles {}
export type BookApi = DefaultEmbeddableApi<BookSerializedState> &
export type BookApi = DefaultEmbeddableApi<BookSerializedState, BookRuntimeState> &
HasEditCapabilities &
HasInPlaceLibraryTransforms;

View file

@ -21,10 +21,10 @@ import React, { useEffect } from 'react';
import { BehaviorSubject, switchMap, tap } from 'rxjs';
import { SEARCH_EMBEDDABLE_ID } from './constants';
import { getCount } from './get_count';
import { SearchApi, Services, SearchSerializedState } from './types';
import { SearchApi, Services, SearchSerializedState, SearchRuntimeState } from './types';
export const getSearchEmbeddableFactory = (services: Services) => {
const factory: ReactEmbeddableFactory<SearchSerializedState, SearchApi> = {
const factory: ReactEmbeddableFactory<SearchSerializedState, SearchRuntimeState, SearchApi> = {
type: SEARCH_EMBEDDABLE_ID,
deserializeState: (state) => state.rawState,
buildEmbeddable: async (state, buildApi, uuid, parentApi) => {

View file

@ -20,6 +20,8 @@ import {
export type SearchSerializedState = SerializedTimeRange;
export type SearchRuntimeState = SearchSerializedState;
export type SearchApi = DefaultEmbeddableApi<SearchSerializedState> &
PublishesDataViews &
PublishesDataLoading &

View file

@ -18,7 +18,7 @@ import { FILTER_DEBUGGER_EMBEDDABLE_ID } from './constants';
export type Api = DefaultEmbeddableApi<{}>;
export const factory: ReactEmbeddableFactory<{}, Api> = {
export const factory: ReactEmbeddableFactory<{}, {}, Api> = {
type: FILTER_DEBUGGER_EMBEDDABLE_ID,
deserializeState: () => {
return {};

View file

@ -9,7 +9,7 @@
import { i18n } from '@kbn/i18n';
import { DefaultEmbeddableApi, ReactEmbeddableFactory } from './types';
const registry: { [key: string]: () => Promise<ReactEmbeddableFactory<any, any>> } = {};
const registry: { [key: string]: () => Promise<ReactEmbeddableFactory<any, any, any>> } = {};
/**
* Registers a new React embeddable factory. This should be called at plugin start time.
@ -20,11 +20,14 @@ const registry: { [key: string]: () => Promise<ReactEmbeddableFactory<any, any>>
*/
export const registerReactEmbeddableFactory = <
SerializedState extends object = object,
Api extends DefaultEmbeddableApi<SerializedState> = DefaultEmbeddableApi<SerializedState>,
RuntimeState extends object = SerializedState
RuntimeState extends object = SerializedState,
Api extends DefaultEmbeddableApi<SerializedState, RuntimeState> = DefaultEmbeddableApi<
SerializedState,
RuntimeState
>
>(
type: string,
getFactory: () => Promise<ReactEmbeddableFactory<SerializedState, Api, RuntimeState>>
getFactory: () => Promise<ReactEmbeddableFactory<SerializedState, RuntimeState, Api>>
) => {
if (registry[type] !== undefined)
throw new Error(
@ -40,11 +43,14 @@ export const reactEmbeddableRegistryHasKey = (key: string) => registry[key] !==
export const getReactEmbeddableFactory = async <
SerializedState extends object = object,
Api extends DefaultEmbeddableApi<SerializedState> = DefaultEmbeddableApi<SerializedState>,
RuntimeState extends object = SerializedState
RuntimeState extends object = SerializedState,
Api extends DefaultEmbeddableApi<SerializedState, RuntimeState> = DefaultEmbeddableApi<
SerializedState,
RuntimeState
>
>(
key: string
): Promise<ReactEmbeddableFactory<SerializedState, Api, RuntimeState>> => {
): Promise<ReactEmbeddableFactory<SerializedState, RuntimeState, Api>> => {
if (registry[key] === undefined)
throw new Error(
i18n.translate('embeddableApi.reactEmbeddable.factoryNotFoundError', {

View file

@ -38,8 +38,11 @@ const ON_STATE_CHANGE_DEBOUNCE = 100;
*/
export const ReactEmbeddableRenderer = <
SerializedState extends object = object,
Api extends DefaultEmbeddableApi<SerializedState> = DefaultEmbeddableApi<SerializedState>,
RuntimeState extends object = SerializedState,
Api extends DefaultEmbeddableApi<SerializedState, RuntimeState> = DefaultEmbeddableApi<
SerializedState,
RuntimeState
>,
ParentApi extends HasSerializedChildState<SerializedState> = HasSerializedChildState<SerializedState>
>({
type,
@ -95,11 +98,11 @@ export const ReactEmbeddableRenderer = <
*/
return (async () => {
const parentApi = getParentApi();
const factory = await getReactEmbeddableFactory<SerializedState, Api, RuntimeState>(type);
const factory = await getReactEmbeddableFactory<SerializedState, RuntimeState, Api>(type);
const subscriptions = new Subscription();
const setApi = (
apiRegistration: SetReactEmbeddableApiRegistration<SerializedState, Api>
apiRegistration: SetReactEmbeddableApiRegistration<SerializedState, RuntimeState, Api>
) => {
const fullApi = {
...apiRegistration,
@ -115,12 +118,16 @@ export const ReactEmbeddableRenderer = <
const buildEmbeddable = async () => {
const { initialState, startStateDiffing } = await initializeReactEmbeddableState<
SerializedState,
Api,
RuntimeState
RuntimeState,
Api
>(uuid, factory, parentApi);
const buildApi = (
apiRegistration: BuildReactEmbeddableApiRegistration<SerializedState, Api>,
apiRegistration: BuildReactEmbeddableApiRegistration<
SerializedState,
RuntimeState,
Api
>,
comparators: StateComparators<RuntimeState>
) => {
if (onAnyStateChange) {
@ -160,7 +167,7 @@ export const ReactEmbeddableRenderer = <
unsavedChanges,
resetUnsavedChanges,
snapshotRuntimeState,
} as unknown as SetReactEmbeddableApiRegistration<SerializedState, Api>);
} as unknown as SetReactEmbeddableApiRegistration<SerializedState, RuntimeState, Api>);
cleanupFunction.current = () => cleanup();
return fullApi;

View file

@ -29,11 +29,14 @@ import { DefaultEmbeddableApi, ReactEmbeddableFactory } from './types';
export const initializeReactEmbeddableState = async <
SerializedState extends object = object,
Api extends DefaultEmbeddableApi<SerializedState> = DefaultEmbeddableApi<SerializedState>,
RuntimeState extends object = SerializedState
RuntimeState extends object = SerializedState,
Api extends DefaultEmbeddableApi<SerializedState, RuntimeState> = DefaultEmbeddableApi<
SerializedState,
RuntimeState
>
>(
uuid: string,
factory: ReactEmbeddableFactory<SerializedState, Api, RuntimeState>,
factory: ReactEmbeddableFactory<SerializedState, RuntimeState, Api>,
parentApi: HasSerializedChildState<SerializedState>
) => {
const lastSavedRuntimeState = await factory.deserializeState(

View file

@ -41,7 +41,11 @@ export interface DefaultEmbeddableApi<
*/
export type SetReactEmbeddableApiRegistration<
SerializedState extends object = object,
Api extends DefaultEmbeddableApi<SerializedState> = DefaultEmbeddableApi<SerializedState>
RuntimeState extends object = SerializedState,
Api extends DefaultEmbeddableApi<SerializedState, RuntimeState> = DefaultEmbeddableApi<
SerializedState,
RuntimeState
>
> = Omit<Api, 'uuid' | 'parent' | 'type' | 'phase$'>;
/**
@ -50,9 +54,13 @@ export type SetReactEmbeddableApiRegistration<
*/
export type BuildReactEmbeddableApiRegistration<
SerializedState extends object = object,
Api extends DefaultEmbeddableApi<SerializedState> = DefaultEmbeddableApi<SerializedState>
RuntimeState extends object = SerializedState,
Api extends DefaultEmbeddableApi<SerializedState, RuntimeState> = DefaultEmbeddableApi<
SerializedState,
RuntimeState
>
> = Omit<
SetReactEmbeddableApiRegistration<SerializedState, Api>,
SetReactEmbeddableApiRegistration<SerializedState, RuntimeState, Api>,
'unsavedChanges' | 'resetUnsavedChanges' | 'snapshotRuntimeState'
>;
@ -65,8 +73,11 @@ export type BuildReactEmbeddableApiRegistration<
**/
export interface ReactEmbeddableFactory<
SerializedState extends object = object,
Api extends DefaultEmbeddableApi<SerializedState> = DefaultEmbeddableApi<SerializedState>,
RuntimeState extends object = SerializedState
RuntimeState extends object = SerializedState,
Api extends DefaultEmbeddableApi<SerializedState, RuntimeState> = DefaultEmbeddableApi<
SerializedState,
RuntimeState
>
> {
/**
* A unique key for the type of this embeddable. The React Embeddable Renderer will use this type
@ -101,12 +112,12 @@ export interface ReactEmbeddableFactory<
* changes logic that the dashboard expects using the provided comparators
*/
buildApi: (
apiRegistration: BuildReactEmbeddableApiRegistration<SerializedState, Api>,
apiRegistration: BuildReactEmbeddableApiRegistration<SerializedState, RuntimeState, Api>,
comparators: StateComparators<RuntimeState>
) => Api,
uuid: string,
parentApi: unknown | undefined,
/** `setApi` should be used when the unsaved changes logic in `buildApi` is unnecessary */
setApi: (api: SetReactEmbeddableApiRegistration<SerializedState, Api>) => Api
setApi: (api: SetReactEmbeddableApiRegistration<SerializedState, RuntimeState, Api>) => Api
) => Promise<{ Component: React.FC<{}>; api: Api }>;
}

View file

@ -30,6 +30,7 @@ export const getImageEmbeddableFactory = ({
embeddableEnhanced?: EmbeddableEnhancedPluginStart;
}) => {
const imageEmbeddableFactory: ReactEmbeddableFactory<
ImageEmbeddableSerializedState,
ImageEmbeddableSerializedState,
ImageEmbeddableApi
> = {

View file

@ -68,8 +68,8 @@ export const getChangePointChartEmbeddableFactory = (
) => {
const factory: ReactEmbeddableFactory<
ChangePointEmbeddableState,
ChangePointEmbeddableApi,
ChangePointEmbeddableRuntimeState
ChangePointEmbeddableRuntimeState,
ChangePointEmbeddableApi
> = {
type: EMBEDDABLE_CHANGE_POINT_CHART_TYPE,
deserializeState: (state) => {

View file

@ -12,7 +12,7 @@ import { ReactEmbeddableRenderer, ViewMode } from '@kbn/embeddable-plugin/public
import type { LayerDescriptor } from '../../common/descriptor_types';
import { INITIAL_LOCATION, MAP_SAVED_OBJECT_TYPE } from '../../common';
import { createBasemapLayerDescriptor } from '../classes/layers/create_basemap_layer_descriptor';
import { MapApi, MapSerializedState } from '../react_embeddable/types';
import { MapApi, MapRuntimeState, MapSerializedState } from '../react_embeddable/types';
export interface Props {
passiveLayer: LayerDescriptor;
@ -50,7 +50,7 @@ export function PassiveMap(props: Props) {
return (
<div className="mapEmbeddableContainer">
<ReactEmbeddableRenderer<MapSerializedState, MapApi>
<ReactEmbeddableRenderer<MapSerializedState, MapRuntimeState, MapApi>
type={MAP_SAVED_OBJECT_TYPE}
getParentApi={() => ({
getSerializedStateForChild: () => {

View file

@ -22,7 +22,7 @@ import { BehaviorSubject } from 'rxjs';
import { apiPublishesSettings } from '@kbn/presentation-containers/interfaces/publishes_settings';
import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants';
import { inject } from '../../common/embeddable';
import type { MapApi, MapSerializedState } from './types';
import type { MapApi, MapRuntimeState, MapSerializedState } from './types';
import { SavedMap } from '../routes/map_page';
import { initializeReduxSync } from './initialize_redux_sync';
import {
@ -44,7 +44,11 @@ export function getControlledBy(id: string) {
return `mapEmbeddablePanel${id}`;
}
export const mapEmbeddableFactory: ReactEmbeddableFactory<MapSerializedState, MapApi> = {
export const mapEmbeddableFactory: ReactEmbeddableFactory<
MapSerializedState,
MapRuntimeState,
MapApi
> = {
type: MAP_SAVED_OBJECT_TYPE,
deserializeState: (state) => {
return state.rawState

View file

@ -11,7 +11,7 @@ import { ReactEmbeddableRenderer } from '@kbn/embeddable-plugin/public';
import { useSearchApi } from '@kbn/presentation-publishing';
import type { LayerDescriptor, MapCenterAndZoom, MapSettings } from '../../common/descriptor_types';
import { createBasemapLayerDescriptor } from '../classes/layers/create_basemap_layer_descriptor';
import { MapApi, MapSerializedState } from './types';
import { MapApi, MapRuntimeState, MapSerializedState } from './types';
import { MAP_SAVED_OBJECT_TYPE } from '../../common/constants';
import { RenderToolTipContent } from '../classes/tooltips/tooltip_property';
@ -58,7 +58,7 @@ export function MapRenderer(props: Props) {
return (
<div className="mapEmbeddableContainer">
<ReactEmbeddableRenderer<MapSerializedState, MapApi>
<ReactEmbeddableRenderer<MapSerializedState, MapRuntimeState, MapApi>
type={MAP_SAVED_OBJECT_TYPE}
getParentApi={() => ({
...searchApi,

View file

@ -58,6 +58,8 @@ export type MapSerializedState = SerializedTitles &
tooltipRenderer?: RenderToolTipContent;
};
export type MapRuntimeState = MapSerializedState;
export type MapApi = DefaultEmbeddableApi<MapSerializedState> &
HasDynamicActions &
Partial<HasEditCapabilities> &

View file

@ -37,161 +37,164 @@ import { buildDataViewPublishingApi } from '../common/anomaly_detection_embeddab
export const getAnomalyChartsReactEmbeddableFactory = (
getStartServices: StartServicesAccessor<MlStartDependencies, MlPluginStart>
) => {
const factory: ReactEmbeddableFactory<AnomalyChartsEmbeddableState, AnomalyChartsEmbeddableApi> =
{
type: ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE,
deserializeState: (state) => state.rawState,
buildEmbeddable: async (state, buildApi, uuid, parentApi) => {
if (!apiHasExecutionContext(parentApi)) {
throw new Error('Parent API does not have execution context');
}
const [coreStartServices, pluginsStartServices] = await getStartServices();
const anomalyChartsDependencies = await getAnomalyChartsServiceDependencies(
coreStartServices,
pluginsStartServices
);
const factory: ReactEmbeddableFactory<
AnomalyChartsEmbeddableState,
AnomalyChartsEmbeddableState,
AnomalyChartsEmbeddableApi
> = {
type: ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE,
deserializeState: (state) => state.rawState,
buildEmbeddable: async (state, buildApi, uuid, parentApi) => {
if (!apiHasExecutionContext(parentApi)) {
throw new Error('Parent API does not have execution context');
}
const [coreStartServices, pluginsStartServices] = await getStartServices();
const anomalyChartsDependencies = await getAnomalyChartsServiceDependencies(
coreStartServices,
pluginsStartServices
);
const [, , mlServices] = anomalyChartsDependencies;
const [, , mlServices] = anomalyChartsDependencies;
const subscriptions = new Subscription();
const subscriptions = new Subscription();
const { titlesApi, titleComparators, serializeTitles } = initializeTitles(state);
const {
api: timeRangeApi,
comparators: timeRangeComparators,
serialize: serializeTimeRange,
} = initializeTimeRange(state);
const { titlesApi, titleComparators, serializeTitles } = initializeTitles(state);
const {
api: timeRangeApi,
comparators: timeRangeComparators,
serialize: serializeTimeRange,
} = initializeTimeRange(state);
const {
anomalyChartsControlsApi,
dataLoadingApi,
serializeAnomalyChartsState,
anomalyChartsComparators,
onAnomalyChartsDestroy,
} = initializeAnomalyChartsControls(state, titlesApi, parentApi);
const {
anomalyChartsControlsApi,
dataLoadingApi,
serializeAnomalyChartsState,
anomalyChartsComparators,
onAnomalyChartsDestroy,
} = initializeAnomalyChartsControls(state, titlesApi, parentApi);
const api = buildApi(
{
isEditingEnabled: () => true,
getTypeDisplayName: () =>
i18n.translate('xpack.ml.components.mlAnomalyExplorerEmbeddable.typeDisplayName', {
defaultMessage: 'anomaly charts',
}),
onEdit: async () => {
try {
const { resolveEmbeddableAnomalyChartsUserInput } = await import(
'./anomaly_charts_setup_flyout'
);
const result = await resolveEmbeddableAnomalyChartsUserInput(
coreStartServices,
pluginsStartServices,
parentApi,
uuid,
{
...serializeTitles(),
...serializeAnomalyChartsState(),
}
);
anomalyChartsControlsApi.updateUserInput(result);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
return Promise.reject();
}
},
...titlesApi,
...timeRangeApi,
...anomalyChartsControlsApi,
...dataLoadingApi,
dataViews: buildDataViewPublishingApi(
{
anomalyDetectorService: mlServices.anomalyDetectorService,
dataViewsService: pluginsStartServices.data.dataViews,
},
{ jobIds: anomalyChartsControlsApi.jobIds$ },
subscriptions
),
serializeState: () => {
return {
rawState: {
timeRange: undefined,
const api = buildApi(
{
isEditingEnabled: () => true,
getTypeDisplayName: () =>
i18n.translate('xpack.ml.components.mlAnomalyExplorerEmbeddable.typeDisplayName', {
defaultMessage: 'anomaly charts',
}),
onEdit: async () => {
try {
const { resolveEmbeddableAnomalyChartsUserInput } = await import(
'./anomaly_charts_setup_flyout'
);
const result = await resolveEmbeddableAnomalyChartsUserInput(
coreStartServices,
pluginsStartServices,
parentApi,
uuid,
{
...serializeTitles(),
...serializeTimeRange(),
...serializeAnomalyChartsState(),
},
references: [],
};
},
},
{
...timeRangeComparators,
...titleComparators,
...anomalyChartsComparators,
}
);
const appliedTimeRange$: Observable<TimeRange | undefined> = fetch$(api).pipe(
map((fetchContext) => fetchContext.timeRange),
distinctUntilChanged(fastIsEqual)
);
const { onRenderComplete, onLoading, onError } = dataLoadingApi;
const contextServices = {
mlServices: {
...mlServices,
},
...coreStartServices,
...pluginsStartServices,
};
return {
api,
Component: () => {
if (!apiHasExecutionContext(parentApi)) {
throw new Error('Parent API does not have execution context');
}
);
anomalyChartsControlsApi.updateUserInput(result);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
return Promise.reject();
}
useReactEmbeddableExecutionContext(
coreStartServices.executionContext,
parentApi.executionContext,
ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE,
uuid
);
useUnmount(() => {
onAnomalyChartsDestroy();
subscriptions.unsubscribe();
});
const { euiTheme } = useEuiTheme();
return (
<KibanaRenderContextProvider {...coreStartServices}>
<KibanaContextProvider services={contextServices}>
<div
css={css`
width: 100%;
padding: ${euiTheme.size.xs};
overflow-y: auto;
`}
data-test-subj="mlAnomalySwimlaneEmbeddableWrapper"
>
<LazyAnomalyChartsContainer
id={uuid}
severityThreshold={state.severityThreshold}
api={api}
services={anomalyChartsDependencies}
onLoading={onLoading}
onRenderComplete={onRenderComplete}
onError={onError}
timeRange$={appliedTimeRange$}
/>
</div>
</KibanaContextProvider>
</KibanaRenderContextProvider>
);
},
};
},
};
...titlesApi,
...timeRangeApi,
...anomalyChartsControlsApi,
...dataLoadingApi,
dataViews: buildDataViewPublishingApi(
{
anomalyDetectorService: mlServices.anomalyDetectorService,
dataViewsService: pluginsStartServices.data.dataViews,
},
{ jobIds: anomalyChartsControlsApi.jobIds$ },
subscriptions
),
serializeState: () => {
return {
rawState: {
timeRange: undefined,
...serializeTitles(),
...serializeTimeRange(),
...serializeAnomalyChartsState(),
},
references: [],
};
},
},
{
...timeRangeComparators,
...titleComparators,
...anomalyChartsComparators,
}
);
const appliedTimeRange$: Observable<TimeRange | undefined> = fetch$(api).pipe(
map((fetchContext) => fetchContext.timeRange),
distinctUntilChanged(fastIsEqual)
);
const { onRenderComplete, onLoading, onError } = dataLoadingApi;
const contextServices = {
mlServices: {
...mlServices,
},
...coreStartServices,
...pluginsStartServices,
};
return {
api,
Component: () => {
if (!apiHasExecutionContext(parentApi)) {
throw new Error('Parent API does not have execution context');
}
useReactEmbeddableExecutionContext(
coreStartServices.executionContext,
parentApi.executionContext,
ANOMALY_EXPLORER_CHARTS_EMBEDDABLE_TYPE,
uuid
);
useUnmount(() => {
onAnomalyChartsDestroy();
subscriptions.unsubscribe();
});
const { euiTheme } = useEuiTheme();
return (
<KibanaRenderContextProvider {...coreStartServices}>
<KibanaContextProvider services={contextServices}>
<div
css={css`
width: 100%;
padding: ${euiTheme.size.xs};
overflow-y: auto;
`}
data-test-subj="mlAnomalySwimlaneEmbeddableWrapper"
>
<LazyAnomalyChartsContainer
id={uuid}
severityThreshold={state.severityThreshold}
api={api}
services={anomalyChartsDependencies}
onLoading={onLoading}
onRenderComplete={onRenderComplete}
onError={onError}
timeRange$={appliedTimeRange$}
/>
</div>
</KibanaContextProvider>
</KibanaRenderContextProvider>
);
},
};
},
};
return factory;
};

View file

@ -97,7 +97,11 @@ describe('getAnomalySwimLaneEmbeddableFactory', () => {
>;
render(
<ReactEmbeddableRenderer<AnomalySwimLaneEmbeddableState, AnomalySwimLaneEmbeddableApi>
<ReactEmbeddableRenderer<
AnomalySwimLaneEmbeddableState,
AnomalySwimLaneEmbeddableState,
AnomalySwimLaneEmbeddableApi
>
maybeId={'maybe_id'}
type={ANOMALY_SWIMLANE_EMBEDDABLE_TYPE}
onApiAvailable={onApiAvailable}

View file

@ -89,8 +89,8 @@ export const getAnomalySwimLaneEmbeddableFactory = (
) => {
const factory: ReactEmbeddableFactory<
AnomalySwimLaneEmbeddableState,
AnomalySwimLaneEmbeddableApi,
AnomalySwimlaneRuntimeState
AnomalySwimlaneRuntimeState,
AnomalySwimLaneEmbeddableApi
> = {
type: ANOMALY_SWIMLANE_EMBEDDABLE_TYPE,
deserializeState: (state) => state.rawState,

View file

@ -36,8 +36,8 @@ export const getSingleMetricViewerEmbeddableFactory = (
) => {
const factory: ReactEmbeddableFactory<
SingleMetricViewerEmbeddableState,
SingleMetricViewerEmbeddableApi,
SingleMetricViewerRuntimeState
SingleMetricViewerRuntimeState,
SingleMetricViewerEmbeddableApi
> = {
type: ANOMALY_SINGLE_METRIC_VIEWER_EMBEDDABLE_TYPE,
deserializeState: (state) => state.rawState,

View file

@ -116,7 +116,11 @@ export const AnomalySwimLane: FC<AnomalySwimLaneProps> = ({
);
return (
<ReactEmbeddableRenderer<AnomalySwimLaneEmbeddableState, AnomalySwimLaneEmbeddableApi>
<ReactEmbeddableRenderer<
AnomalySwimLaneEmbeddableState,
AnomalySwimLaneEmbeddableState,
AnomalySwimLaneEmbeddableApi
>
maybeId={id}
type={ANOMALY_SWIMLANE_EMBEDDABLE_TYPE}
getParentApi={() => parentApi}

View file

@ -19,6 +19,7 @@ export const APM_ALERTING_FAILED_TRANSACTIONS_CHART_EMBEDDABLE =
export const getApmAlertingFailedTransactionsChartEmbeddableFactory = (deps: EmbeddableDeps) => {
const factory: ReactEmbeddableFactory<
EmbeddableApmAlertingVizProps,
EmbeddableApmAlertingVizProps,
DefaultEmbeddableApi<EmbeddableApmAlertingVizProps>
> = {

View file

@ -18,6 +18,7 @@ export const APM_ALERTING_LATENCY_CHART_EMBEDDABLE = 'APM_ALERTING_LATENCY_CHART
export const getApmAlertingLatencyChartEmbeddableFactory = (deps: EmbeddableDeps) => {
const factory: ReactEmbeddableFactory<
EmbeddableApmAlertingLatencyVizProps,
EmbeddableApmAlertingLatencyVizProps,
DefaultEmbeddableApi<EmbeddableApmAlertingLatencyVizProps>
> = {

View file

@ -18,6 +18,7 @@ export const APM_ALERTING_THROUGHPUT_CHART_EMBEDDABLE = 'APM_ALERTING_THROUGHPUT
export const getApmAlertingThroughputChartEmbeddableFactory = (deps: EmbeddableDeps) => {
const factory: ReactEmbeddableFactory<
EmbeddableApmAlertingVizProps,
EmbeddableApmAlertingVizProps,
DefaultEmbeddableApi<EmbeddableApmAlertingVizProps>
> = {

View file

@ -24,7 +24,11 @@ import { useKibanaContextForPluginProvider } from '../../hooks/use_kibana';
import { InfraClientStartDeps, InfraClientStartExports } from '../../types';
export function getLogStreamEmbeddableFactory(services: Services) {
const factory: ReactEmbeddableFactory<LogStreamSerializedState, LogStreamApi> = {
const factory: ReactEmbeddableFactory<
LogStreamSerializedState,
LogStreamSerializedState,
LogStreamApi
> = {
type: LOG_STREAM_EMBEDDABLE,
deserializeState: (state) => state.rawState,
buildEmbeddable: async (state, buildApi) => {

View file

@ -33,7 +33,11 @@ export const getAlertsPanelTitle = () =>
});
export function getAlertsEmbeddableFactory(deps: SloEmbeddableDeps, kibanaVersion: string) {
const factory: ReactEmbeddableFactory<SloAlertsEmbeddableState, SloAlertsApi> = {
const factory: ReactEmbeddableFactory<
SloAlertsEmbeddableState,
SloAlertsEmbeddableState,
SloAlertsApi
> = {
type: SLO_ALERTS_EMBEDDABLE_ID,
deserializeState: (state) => {
return state.rawState as SloAlertsEmbeddableState;

View file

@ -28,7 +28,11 @@ export const getErrorBudgetPanelTitle = () =>
const queryClient = new QueryClient();
export const getErrorBudgetEmbeddableFactory = (deps: SloEmbeddableDeps) => {
const factory: ReactEmbeddableFactory<SloErrorBudgetEmbeddableState, ErrorBudgetApi> = {
const factory: ReactEmbeddableFactory<
SloErrorBudgetEmbeddableState,
SloErrorBudgetEmbeddableState,
ErrorBudgetApi
> = {
type: SLO_ERROR_BUDGET_ID,
deserializeState: (state) => {
return state.rawState as SloErrorBudgetEmbeddableState;

View file

@ -36,7 +36,11 @@ export const getOverviewPanelTitle = () =>
defaultMessage: 'SLO Overview',
});
export const getOverviewEmbeddableFactory = (deps: SloEmbeddableDeps) => {
const factory: ReactEmbeddableFactory<SloOverviewEmbeddableState, SloOverviewApi> = {
const factory: ReactEmbeddableFactory<
SloOverviewEmbeddableState,
SloOverviewEmbeddableState,
SloOverviewApi
> = {
type: SLO_OVERVIEW_EMBEDDABLE_ID,
deserializeState: (state) => {
return state.rawState as SloOverviewEmbeddableState;