fix to update panel component when data view changes

This commit is contained in:
Walter Rafelsberger 2024-10-10 14:37:30 +02:00
parent 75ca4cac37
commit 2b58567771
3 changed files with 61 additions and 33 deletions

View file

@ -28,7 +28,7 @@ import { cloneDeep } from 'lodash';
import React, { useMemo } from 'react';
import useObservable from 'react-use/lib/useObservable';
import { BehaviorSubject, distinctUntilChanged, map, skipWhile } from 'rxjs';
import { getLogRateAnalysisComponent } from '../../shared_components';
import { getLogRateAnalysisEmbeddableWrapperComponent } from '../../shared_components';
import type { AiopsPluginStart, AiopsPluginStartDeps } from '../../types';
import { initializeLogRateAnalysisControls } from './initialize_log_rate_analysis_analysis_controls';
import type {
@ -162,7 +162,10 @@ export const getLogRateAnalysisEmbeddableFactory = (
}
);
const LogRateAnalysisComponent = getLogRateAnalysisComponent(coreStart, pluginStart);
const LogRateAnalysisEmbeddableWrapper = getLogRateAnalysisEmbeddableWrapperComponent(
coreStart,
pluginStart
);
const onLoading = (v: boolean) => dataLoading.next(v);
const onRenderComplete = () => dataLoading.next(false);
@ -203,7 +206,7 @@ export const getLogRateAnalysisEmbeddableFactory = (
: undefined;
return (
<LogRateAnalysisComponent
<LogRateAnalysisEmbeddableWrapper
dataViewId={dataViewId}
timeRange={timeRange}
onLoading={onLoading}

View file

@ -11,7 +11,7 @@ import type { CoreStart } from '@kbn/core-lifecycle-browser';
import type { AiopsPluginStartDeps } from '../types';
import type { ChangePointDetectionSharedComponent } from './change_point_detection';
import type { PatternAnalysisSharedComponent } from './pattern_analysis';
import type { LogRateAnalysisSharedComponent } from './log_rate_analysis';
import type { LogRateAnalysisEmbeddableWrapper } from './log_rate_analysis_embeddable_wrapper';
const ChangePointDetectionLazy = dynamic(async () => import('./change_point_detection'));
@ -39,15 +39,23 @@ export const getPatternAnalysisComponent = (
export type { PatternAnalysisSharedComponent } from './pattern_analysis';
const LogRateAnalysisLazy = dynamic(async () => import('./log_rate_analysis'));
const LogRateAnalysisEmbeddableWrapperLazy = dynamic(
async () => import('./log_rate_analysis_embeddable_wrapper')
);
export const getLogRateAnalysisComponent = (
export const getLogRateAnalysisEmbeddableWrapperComponent = (
coreStart: CoreStart,
pluginStart: AiopsPluginStartDeps
): LogRateAnalysisSharedComponent => {
): LogRateAnalysisEmbeddableWrapper => {
return React.memo((props) => {
return <LogRateAnalysisLazy coreStart={coreStart} pluginStart={pluginStart} {...props} />;
return (
<LogRateAnalysisEmbeddableWrapperLazy
coreStart={coreStart}
pluginStart={pluginStart}
{...props}
/>
);
});
};
export type { LogRateAnalysisSharedComponent } from './log_rate_analysis';
export type { LogRateAnalysisEmbeddableWrapper } from './log_rate_analysis_embeddable_wrapper';

View file

@ -7,6 +7,7 @@
import { pick } from 'lodash';
import React, { useEffect, useMemo, useState, type FC } from 'react';
import usePrevious from 'react-use/lib/usePrevious';
import type { Observable } from 'rxjs';
import { BehaviorSubject, combineLatest, distinctUntilChanged, map } from 'rxjs';
import { createBrowserHistory } from 'history';
@ -34,14 +35,14 @@ import { LogRateAnalysisContent } from '../components/log_rate_analysis/log_rate
/**
* Only used to initialize internally
*/
export type LogRateAnalysisPropsWithDeps = LogRateAnalysisProps & {
export type LogRateAnalysisPropsWithDeps = LogRateAnalysisEmbeddableWrapperProps & {
coreStart: CoreStart;
pluginStart: AiopsPluginStartDeps;
};
export type LogRateAnalysisSharedComponent = FC<LogRateAnalysisProps>;
export type LogRateAnalysisEmbeddableWrapper = FC<LogRateAnalysisEmbeddableWrapperProps>;
export interface LogRateAnalysisProps {
export interface LogRateAnalysisEmbeddableWrapperProps {
dataViewId: string;
timeRange: TimeRange;
/**
@ -63,7 +64,7 @@ export interface LogRateAnalysisProps {
onError: (error: Error) => void;
}
const LogRateAnalysisWrapper: FC<LogRateAnalysisPropsWithDeps> = ({
const LogRateAnalysisEmbeddableWrapperWithDeps: FC<LogRateAnalysisPropsWithDeps> = ({
// Component dependencies
coreStart,
pluginStart,
@ -132,6 +133,20 @@ const LogRateAnalysisWrapper: FC<LogRateAnalysisPropsWithDeps> = ({
}
}, [timeRange]);
// We use the following pattern to track changes of dataViewId, and if there's
// a change, we unmount and remount the complete inner component. This makes
// sure the component is reinitialized correctly when the options of the
// dashboard panel are used to change the data view. This is a bit of a
// workaround since originally log rate analysis was developed as a standalone
// page with the expectation that the data view is set once and never changes.
const prevDataViewId = usePrevious(dataViewId);
const [_, setRerenderFlag] = useState(false);
useEffect(() => {
if (prevDataViewId && prevDataViewId !== dataViewId) {
setRerenderFlag((prev) => !prev);
}
}, [dataViewId, prevDataViewId]);
// TODO: Remove data-shared-item as part of https://github.com/elastic/kibana/issues/179376>
return (
<div
@ -144,28 +159,30 @@ const LogRateAnalysisWrapper: FC<LogRateAnalysisPropsWithDeps> = ({
padding: '10px',
}}
>
<Router history={history}>
<ReloadContextProvider reload$={resultObservable$}>
<AiopsAppContext.Provider value={aiopsAppContextValue}>
<UrlStateProvider>
<DataSourceContextProvider
dataViews={pluginStart.data.dataViews}
dataViewId={dataViewId}
>
<LogRateAnalysisReduxProvider>
<DatePickerContextProvider {...datePickerDeps}>
<LogRateAnalysisDocumentCountChartData timeRange={timeRangeParsed} />
<LogRateAnalysisContent />
</DatePickerContextProvider>
</LogRateAnalysisReduxProvider>
</DataSourceContextProvider>
</UrlStateProvider>
</AiopsAppContext.Provider>
</ReloadContextProvider>
</Router>
{prevDataViewId === dataViewId && (
<Router history={history}>
<ReloadContextProvider reload$={resultObservable$}>
<AiopsAppContext.Provider value={aiopsAppContextValue}>
<UrlStateProvider>
<DataSourceContextProvider
dataViews={pluginStart.data.dataViews}
dataViewId={dataViewId}
>
<LogRateAnalysisReduxProvider>
<DatePickerContextProvider {...datePickerDeps}>
<LogRateAnalysisDocumentCountChartData timeRange={timeRangeParsed} />
<LogRateAnalysisContent />
</DatePickerContextProvider>
</LogRateAnalysisReduxProvider>
</DataSourceContextProvider>
</UrlStateProvider>
</AiopsAppContext.Provider>
</ReloadContextProvider>
</Router>
)}
</div>
);
};
// eslint-disable-next-line import/no-default-export
export default LogRateAnalysisWrapper;
export default LogRateAnalysisEmbeddableWrapperWithDeps;