Dashboard add or update panel (#71130)

Added a standard method for adding or replacing a panel on a dashboard.
This commit is contained in:
Devon Thomson 2020-07-09 14:32:39 -04:00 committed by GitHub
parent 0d3f7a18ae
commit e54729caf2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 25 deletions

View file

@ -60,6 +60,7 @@ import {
ViewMode,
ContainerOutput,
EmbeddableInput,
SavedObjectEmbeddableInput,
} from '../../../embeddable/public';
import { NavAction, SavedDashboardPanel } from '../types';
@ -431,7 +432,7 @@ export class DashboardAppController {
.getIncomingEmbeddablePackage();
if (incomingState) {
if ('id' in incomingState) {
container.addNewEmbeddable<EmbeddableInput>(incomingState.type, {
container.addOrUpdateEmbeddable<SavedObjectEmbeddableInput>(incomingState.type, {
savedObjectId: incomingState.id,
});
} else if ('input' in incomingState) {
@ -440,7 +441,7 @@ export class DashboardAppController {
const explicitInput = {
savedVis: input,
};
container.addNewEmbeddable<EmbeddableInput>(incomingState.type, explicitInput);
container.addOrUpdateEmbeddable<EmbeddableInput>(incomingState.type, explicitInput);
}
}
}

View file

@ -46,7 +46,7 @@ import {
} from '../../../../kibana_react/public';
import { PLACEHOLDER_EMBEDDABLE } from './placeholder';
import { PanelPlacementMethod, IPanelPlacementArgs } from './panel/dashboard_panel_placement';
import { EmbeddableStateTransfer } from '../../../../embeddable/public';
import { EmbeddableStateTransfer, EmbeddableOutput } from '../../../../embeddable/public';
export interface DashboardContainerInput extends ContainerInput {
viewMode: ViewMode;
@ -159,31 +159,57 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
[placeholderPanelState.explicitInput.id]: placeholderPanelState,
},
});
newStateComplete.then((newPanelState: Partial<PanelState>) => {
const finalPanels = { ...this.input.panels };
delete finalPanels[placeholderPanelState.explicitInput.id];
const newPanelId = newPanelState.explicitInput?.id
? newPanelState.explicitInput.id
: uuid.v4();
finalPanels[newPanelId] = {
...placeholderPanelState,
...newPanelState,
gridData: {
...placeholderPanelState.gridData,
i: newPanelId,
},
explicitInput: {
...newPanelState.explicitInput,
id: newPanelId,
},
};
this.updateInput({
panels: finalPanels,
lastReloadRequestTime: new Date().getTime(),
});
newStateComplete.then((newPanelState: Partial<PanelState>) =>
this.replacePanel(placeholderPanelState, newPanelState)
);
}
public replacePanel(
previousPanelState: DashboardPanelState<EmbeddableInput>,
newPanelState: Partial<PanelState>
) {
// TODO: In the current infrastructure, embeddables in a container do not react properly to
// changes. Removing the existing embeddable, and adding a new one is a temporary workaround
// until the container logic is fixed.
const finalPanels = { ...this.input.panels };
delete finalPanels[previousPanelState.explicitInput.id];
const newPanelId = newPanelState.explicitInput?.id ? newPanelState.explicitInput.id : uuid.v4();
finalPanels[newPanelId] = {
...previousPanelState,
...newPanelState,
gridData: {
...previousPanelState.gridData,
i: newPanelId,
},
explicitInput: {
...newPanelState.explicitInput,
id: newPanelId,
},
};
this.updateInput({
panels: finalPanels,
lastReloadRequestTime: new Date().getTime(),
});
}
public async addOrUpdateEmbeddable<
EEI extends EmbeddableInput = EmbeddableInput,
EEO extends EmbeddableOutput = EmbeddableOutput,
E extends IEmbeddable<EEI, EEO> = IEmbeddable<EEI, EEO>
>(type: string, explicitInput: Partial<EEI>) {
if (explicitInput.id && this.input.panels[explicitInput.id]) {
this.replacePanel(this.input.panels[explicitInput.id], {
type,
explicitInput: {
...explicitInput,
id: uuid.v4(),
},
});
} else {
this.addNewEmbeddable<EEI, EEO, E>(type, explicitInput);
}
}
public render(dom: HTMLElement) {
ReactDOM.render(
<I18nProvider>