Dashboards: Add undo/redo support for adding/removing template variables (#106643)

* Dashboards: Add undo/redo support for adding/removing template variables

* Remove unnecessary ObjectRemovedFromCanvasEvent
This commit is contained in:
kay delaney
2025-06-17 14:50:11 +01:00
committed by GitHub
parent 8b6329a224
commit f71c9c6ebf
4 changed files with 60 additions and 8 deletions
@@ -255,6 +255,6 @@ export class DashboardEditPane extends SceneObjectBase<DashboardEditPaneState> {
private newObjectAddedToCanvas(obj: SceneObject) {
this.selectObject(obj, obj.state.key!);
this.state.selection!.markAsNewElement();
this.state.selection?.markAsNewElement();
}
}
@@ -2,7 +2,14 @@ import { useSessionStorage } from 'react-use';
import { BusEventWithPayload } from '@grafana/data';
import { t } from '@grafana/i18n';
import { LocalValueVariable, SceneGridRow, SceneObject, SceneVariableSet, VizPanel } from '@grafana/scenes';
import {
LocalValueVariable,
SceneGridRow,
SceneObject,
SceneVariable,
SceneVariableSet,
VizPanel,
} from '@grafana/scenes';
import { DashboardScene } from '../scene/DashboardScene';
import { SceneGridRowEditableElement } from '../scene/layout-default/SceneGridRowEditableElement';
@@ -99,6 +106,16 @@ export interface RemoveElementActionHelperProps {
undo: () => void;
}
export interface AddVariableActionHelperProps {
addedObject: SceneVariable;
source: SceneVariableSet;
}
export interface RemoveVariableActionHelperProps {
removedObject: SceneVariable;
source: SceneVariableSet;
}
export interface ChangeTitleActionHelperProps {
oldTitle: string;
newTitle: string;
@@ -159,6 +176,35 @@ export const dashboardEditActions = {
});
},
addVariable({ source, addedObject }: AddVariableActionHelperProps) {
const varsBeforeAddition = [...source.state.variables];
dashboardEditActions.addElement({
source,
addedObject,
perform() {
source.setState({ variables: [...varsBeforeAddition, addedObject] });
},
undo() {
source.setState({ variables: [...varsBeforeAddition] });
},
});
},
removeVariable({ source, removedObject }: RemoveVariableActionHelperProps) {
const varsBeforeRemoval = [...source.state.variables];
dashboardEditActions.removeElement({
source,
removedObject,
perform() {
source.setState({ variables: varsBeforeRemoval.filter((v) => v !== removedObject) });
},
undo() {
source.setState({ variables: varsBeforeRemoval });
},
});
},
changeTitle({ source, oldTitle, newTitle }: ChangeTitleActionHelperProps) {
dashboardEditActions.edit({
description: t('dashboard.title.action', 'Change dashboard title'),
@@ -9,7 +9,7 @@ import { Input, TextArea, Button, Field, Box, Stack } from '@grafana/ui';
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
import { ObjectRemovedFromCanvasEvent } from '../../edit-pane/shared';
import { dashboardEditActions } from '../../edit-pane/shared';
import { useEditPaneInputAutoFocus } from '../../scene/layouts-shared/utils';
import { BulkActionElement } from '../../scene/types/BulkActionElement';
import { EditableDashboardElement, EditableDashboardElementInfo } from '../../scene/types/EditableDashboardElement';
@@ -96,8 +96,10 @@ export class VariableEditableElement implements EditableDashboardElement, BulkAc
public onDelete() {
const set = this.variable.parent!;
if (set instanceof SceneVariableSet) {
this.variable.publishEvent(new ObjectRemovedFromCanvasEvent(this.variable), true);
set.setState({ variables: set.state.variables.filter((v) => v !== this.variable) });
dashboardEditActions.removeVariable({
source: set,
removedObject: this.variable,
});
}
}
@@ -10,7 +10,7 @@ import { Stack, Button, useStyles2, Text, Box, Card } from '@grafana/ui';
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared';
import { dashboardEditActions } from '../../edit-pane/shared';
import { DashboardScene } from '../../scene/DashboardScene';
import { EditableDashboardElement, EditableDashboardElementInfo } from '../../scene/types/EditableDashboardElement';
import { getDashboardSceneFor } from '../../utils/utils';
@@ -64,8 +64,12 @@ function VariableList({ set }: { set: SceneVariableSet }) {
const { variables } = set.state;
const nextName = getNextAvailableId(type, variables);
const newVar = getVariableScene(type, { name: nextName });
set.setState({ variables: [...variables, newVar] });
set.publishEvent(new NewObjectAddedToCanvasEvent(newVar), true);
dashboardEditActions.addVariable({
source: set,
addedObject: newVar,
});
setIsAdding(false);
};