mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
* Fix Initialization Race Condition
(cherry picked from commit 702827b42f
)
# Conflicts:
# src/plugins/dashboard/public/application/embeddable/dashboard_container_factory.tsx
# x-pack/test/functional/apps/dashboard/group3/drilldowns/dashboard_to_dashboard_drilldown.ts
This commit is contained in:
parent
bb518ae62a
commit
f70e86982a
5 changed files with 54 additions and 32 deletions
|
@ -10,7 +10,7 @@ import { skip, debounceTime, distinctUntilChanged } from 'rxjs/operators';
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Filter, uniqFilters } from '@kbn/es-query';
|
||||
import { merge, Subject, Subscription } from 'rxjs';
|
||||
import { BehaviorSubject, merge, Subject, Subscription } from 'rxjs';
|
||||
import { EuiContextMenuPanel } from '@elastic/eui';
|
||||
|
||||
import {
|
||||
|
@ -57,6 +57,8 @@ export class ControlGroupContainer extends Container<
|
|||
public readonly type = CONTROL_GROUP_TYPE;
|
||||
public readonly anyControlOutputConsumerLoading$: Subject<boolean> = new Subject();
|
||||
|
||||
private initialized$ = new BehaviorSubject(false);
|
||||
|
||||
private subscriptions: Subscription = new Subscription();
|
||||
private domNode?: HTMLElement;
|
||||
private recalculateFilters$: Subject<null>;
|
||||
|
@ -194,10 +196,11 @@ export class ControlGroupContainer extends Container<
|
|||
});
|
||||
|
||||
// when all children are ready setup subscriptions
|
||||
this.untilReady().then(() => {
|
||||
this.untilAllChildrenReady().then(() => {
|
||||
this.recalculateDataViews();
|
||||
this.recalculateFilters();
|
||||
this.setupSubscriptions();
|
||||
this.initialized$.next(true);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -327,7 +330,7 @@ export class ControlGroupContainer extends Container<
|
|||
};
|
||||
}
|
||||
|
||||
public untilReady = () => {
|
||||
public untilAllChildrenReady = () => {
|
||||
const panelsLoading = () =>
|
||||
Object.keys(this.getInput().panels).some(
|
||||
(panelId) => !this.getOutput().embeddableLoaded[panelId]
|
||||
|
@ -349,6 +352,24 @@ export class ControlGroupContainer extends Container<
|
|||
return Promise.resolve();
|
||||
};
|
||||
|
||||
public untilInitialized = () => {
|
||||
if (this.initialized$.value === false) {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
const subscription = this.initialized$.subscribe((isInitialized) => {
|
||||
if (this.destroyed) {
|
||||
subscription.unsubscribe();
|
||||
reject();
|
||||
}
|
||||
if (isInitialized) {
|
||||
subscription.unsubscribe();
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
public render(dom: HTMLElement) {
|
||||
if (this.domNode) {
|
||||
ReactDOM.unmountComponentAtNode(this.domNode);
|
||||
|
|
|
@ -153,16 +153,13 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
|
|||
isProjectEnabledInLabs('labs:dashboard:dashboardControls')
|
||||
) {
|
||||
this.controlGroup = controlGroup;
|
||||
this.controlGroup.untilReady().then(() => {
|
||||
if (!this.controlGroup || isErrorEmbeddable(this.controlGroup)) return;
|
||||
syncDashboardControlGroup({
|
||||
dashboardContainer: this,
|
||||
controlGroup: this.controlGroup,
|
||||
}).then((result) => {
|
||||
if (!result) return;
|
||||
const { onDestroyControlGroup } = result;
|
||||
this.onDestroyControlGroup = onDestroyControlGroup;
|
||||
});
|
||||
syncDashboardControlGroup({
|
||||
dashboardContainer: this,
|
||||
controlGroup: this.controlGroup,
|
||||
}).then((result) => {
|
||||
if (!result) return;
|
||||
const { onDestroyControlGroup } = result;
|
||||
this.onDestroyControlGroup = onDestroyControlGroup;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import {
|
|||
ContainerOutput,
|
||||
EmbeddableFactory,
|
||||
EmbeddableFactoryDefinition,
|
||||
isErrorEmbeddable,
|
||||
} from '@kbn/embeddable-plugin/public';
|
||||
|
||||
import { DashboardContainerInput } from '../..';
|
||||
|
@ -32,7 +33,6 @@ import {
|
|||
createExtract,
|
||||
createInject,
|
||||
} from '../../../common/embeddable/dashboard_container_persistable_state';
|
||||
import { pluginServices } from '../../services/plugin_services';
|
||||
|
||||
export type DashboardContainerFactory = EmbeddableFactory<
|
||||
DashboardContainerInput,
|
||||
|
@ -76,14 +76,13 @@ export class DashboardContainerFactoryDefinition
|
|||
};
|
||||
}
|
||||
|
||||
public create = async (
|
||||
initialInput: DashboardContainerInput,
|
||||
parent?: Container
|
||||
): Promise<DashboardContainer | ErrorEmbeddable> => {
|
||||
private buildControlGroup = async (
|
||||
initialInput: DashboardContainerInput
|
||||
): Promise<ControlGroupContainer | ErrorEmbeddable | undefined> => {
|
||||
const { pluginServices } = await import('../../services/plugin_services');
|
||||
const {
|
||||
embeddable: { getEmbeddableFactory },
|
||||
} = pluginServices.getServices();
|
||||
|
||||
const controlsGroupFactory = getEmbeddableFactory<
|
||||
ControlGroupInput,
|
||||
ControlGroupOutput,
|
||||
|
@ -99,10 +98,23 @@ export class DashboardContainerFactoryDefinition
|
|||
filters,
|
||||
query,
|
||||
});
|
||||
if (controlGroup && !isErrorEmbeddable(controlGroup)) {
|
||||
await controlGroup.untilInitialized();
|
||||
}
|
||||
return controlGroup;
|
||||
};
|
||||
|
||||
const { DashboardContainer: DashboardContainerEmbeddable } = await import(
|
||||
'./dashboard_container'
|
||||
);
|
||||
public create = async (
|
||||
initialInput: DashboardContainerInput,
|
||||
parent?: Container
|
||||
): Promise<DashboardContainer | ErrorEmbeddable> => {
|
||||
const controlGroupPromise = this.buildControlGroup(initialInput);
|
||||
const dashboardContainerPromise = import('./dashboard_container');
|
||||
|
||||
const [controlGroup, { DashboardContainer: DashboardContainerEmbeddable }] = await Promise.all([
|
||||
controlGroupPromise,
|
||||
dashboardContainerPromise,
|
||||
]);
|
||||
|
||||
return Promise.resolve(new DashboardContainerEmbeddable(initialInput, parent, controlGroup));
|
||||
};
|
||||
|
|
|
@ -33,7 +33,6 @@ export interface DashboardViewportProps {
|
|||
|
||||
interface State {
|
||||
isFullScreenMode: boolean;
|
||||
controlGroupReady: boolean;
|
||||
useMargins: boolean;
|
||||
title: string;
|
||||
description?: string;
|
||||
|
@ -57,7 +56,6 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
|
|||
this.controlsRoot = React.createRef();
|
||||
|
||||
this.state = {
|
||||
controlGroupReady: !this.props.controlGroup,
|
||||
isFullScreenMode,
|
||||
panelCount: Object.values(panels).length,
|
||||
useMargins,
|
||||
|
@ -85,9 +83,6 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
|
|||
if (this.props.controlGroup && this.controlsRoot.current) {
|
||||
this.props.controlGroup.render(this.controlsRoot.current);
|
||||
}
|
||||
if (this.props.controlGroup) {
|
||||
this.props.controlGroup?.untilReady().then(() => this.setState({ controlGroupReady: true }));
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount() {
|
||||
|
@ -164,9 +159,7 @@ export class DashboardViewport extends React.Component<DashboardViewportProps, S
|
|||
<DashboardEmptyScreen isEditMode={isEditMode} />
|
||||
</div>
|
||||
)}
|
||||
{this.state.controlGroupReady && (
|
||||
<DashboardGrid container={container} onDataLoaded={this.props.onDataLoaded} />
|
||||
)}
|
||||
<DashboardGrid container={container} onDataLoaded={this.props.onDataLoaded} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -37,8 +37,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) {
|
|||
const spaces = getService('spaces');
|
||||
const elasticChart = getService('elasticChart');
|
||||
|
||||
// Skipping in 8.5 until https://github.com/elastic/kibana/pull/143220 is merged and backported...
|
||||
describe.skip('Dashboard to dashboard drilldown', function () {
|
||||
describe('Dashboard to dashboard drilldown', function () {
|
||||
describe('Create & use drilldowns', () => {
|
||||
before(async () => {
|
||||
log.debug('Dashboard Drilldowns:initTests');
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue