Skip to content

Commit ee4fd66

Browse files
committed
Dashboard add or update panel (#71130)
Added a standard method for adding or replacing a panel on a dashboard.
1 parent 370cb47 commit ee4fd66

File tree

2 files changed

+50
-23
lines changed

2 files changed

+50
-23
lines changed

src/plugins/dashboard/public/application/dashboard_app_controller.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ import {
6060
ViewMode,
6161
ContainerOutput,
6262
EmbeddableInput,
63+
SavedObjectEmbeddableInput,
6364
} from '../../../embeddable/public';
6465
import { NavAction, SavedDashboardPanel } from '../types';
6566

@@ -431,7 +432,7 @@ export class DashboardAppController {
431432
.getIncomingEmbeddablePackage();
432433
if (incomingState) {
433434
if ('id' in incomingState) {
434-
container.addNewEmbeddable<EmbeddableInput>(incomingState.type, {
435+
container.addOrUpdateEmbeddable<SavedObjectEmbeddableInput>(incomingState.type, {
435436
savedObjectId: incomingState.id,
436437
});
437438
} else if ('input' in incomingState) {
@@ -440,7 +441,7 @@ export class DashboardAppController {
440441
const explicitInput = {
441442
savedVis: input,
442443
};
443-
container.addNewEmbeddable<EmbeddableInput>(incomingState.type, explicitInput);
444+
container.addOrUpdateEmbeddable<EmbeddableInput>(incomingState.type, explicitInput);
444445
}
445446
}
446447
}

src/plugins/dashboard/public/application/embeddable/dashboard_container.tsx

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import {
4646
} from '../../../../kibana_react/public';
4747
import { PLACEHOLDER_EMBEDDABLE } from './placeholder';
4848
import { PanelPlacementMethod, IPanelPlacementArgs } from './panel/dashboard_panel_placement';
49-
import { EmbeddableStateTransfer } from '../../../../embeddable/public';
49+
import { EmbeddableStateTransfer, EmbeddableOutput } from '../../../../embeddable/public';
5050

5151
export interface DashboardContainerInput extends ContainerInput {
5252
viewMode: ViewMode;
@@ -159,29 +159,55 @@ export class DashboardContainer extends Container<InheritedChildInput, Dashboard
159159
[placeholderPanelState.explicitInput.id]: placeholderPanelState,
160160
},
161161
});
162-
newStateComplete.then((newPanelState: Partial<PanelState>) => {
163-
const finalPanels = { ...this.input.panels };
164-
delete finalPanels[placeholderPanelState.explicitInput.id];
165-
const newPanelId = newPanelState.explicitInput?.id
166-
? newPanelState.explicitInput.id
167-
: uuid.v4();
168-
finalPanels[newPanelId] = {
169-
...placeholderPanelState,
170-
...newPanelState,
171-
gridData: {
172-
...placeholderPanelState.gridData,
173-
i: newPanelId,
174-
},
162+
newStateComplete.then((newPanelState: Partial<PanelState>) =>
163+
this.replacePanel(placeholderPanelState, newPanelState)
164+
);
165+
}
166+
167+
public replacePanel(
168+
previousPanelState: DashboardPanelState<EmbeddableInput>,
169+
newPanelState: Partial<PanelState>
170+
) {
171+
// TODO: In the current infrastructure, embeddables in a container do not react properly to
172+
// changes. Removing the existing embeddable, and adding a new one is a temporary workaround
173+
// until the container logic is fixed.
174+
const finalPanels = { ...this.input.panels };
175+
delete finalPanels[previousPanelState.explicitInput.id];
176+
const newPanelId = newPanelState.explicitInput?.id ? newPanelState.explicitInput.id : uuid.v4();
177+
finalPanels[newPanelId] = {
178+
...previousPanelState,
179+
...newPanelState,
180+
gridData: {
181+
...previousPanelState.gridData,
182+
i: newPanelId,
183+
},
184+
explicitInput: {
185+
...newPanelState.explicitInput,
186+
id: newPanelId,
187+
},
188+
};
189+
this.updateInput({
190+
panels: finalPanels,
191+
lastReloadRequestTime: new Date().getTime(),
192+
});
193+
}
194+
195+
public async addOrUpdateEmbeddable<
196+
EEI extends EmbeddableInput = EmbeddableInput,
197+
EEO extends EmbeddableOutput = EmbeddableOutput,
198+
E extends IEmbeddable<EEI, EEO> = IEmbeddable<EEI, EEO>
199+
>(type: string, explicitInput: Partial<EEI>) {
200+
if (explicitInput.id && this.input.panels[explicitInput.id]) {
201+
this.replacePanel(this.input.panels[explicitInput.id], {
202+
type,
175203
explicitInput: {
176-
...newPanelState.explicitInput,
177-
id: newPanelId,
204+
...explicitInput,
205+
id: uuid.v4(),
178206
},
179-
};
180-
this.updateInput({
181-
panels: finalPanels,
182-
lastReloadRequestTime: new Date().getTime(),
183207
});
184-
});
208+
} else {
209+
this.addNewEmbeddable<EEI, EEO, E>(type, explicitInput);
210+
}
185211
}
186212

187213
public render(dom: HTMLElement) {

0 commit comments

Comments
 (0)