diff --git a/packages/grafana-e2e-selectors/src/selectors/components.ts b/packages/grafana-e2e-selectors/src/selectors/components.ts
index ecf551d4395..05b0f553578 100644
--- a/packages/grafana-e2e-selectors/src/selectors/components.ts
+++ b/packages/grafana-e2e-selectors/src/selectors/components.ts
@@ -45,6 +45,9 @@ export const versionedComponents = {
pasteTab: {
'12.1.0': 'data-testid CanvasGridAddActions paste-tab',
},
+ pastePanel: {
+ '12.1.0': 'data-testid CanvasGridAddActions paste-panel',
+ },
},
DashboardEditPaneSplitter: {
primaryBody: {
diff --git a/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.test.tsx b/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.test.tsx
new file mode 100644
index 00000000000..627ceb96d3b
--- /dev/null
+++ b/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.test.tsx
@@ -0,0 +1,93 @@
+import { render, screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+
+import { selectors } from '@grafana/e2e-selectors';
+import { SceneTimeRange } from '@grafana/scenes';
+
+import { DashboardScene } from '../scene/DashboardScene';
+import { RowItem } from '../scene/layout-rows/RowItem';
+import { RowsLayoutManager } from '../scene/layout-rows/RowsLayoutManager';
+import { TabItem } from '../scene/layout-tabs/TabItem';
+import { TabsLayoutManager } from '../scene/layout-tabs/TabsLayoutManager';
+import { DashboardInteractions } from '../utils/interactions';
+import { activateFullSceneTree } from '../utils/test-utils';
+
+import { DashboardEditPane } from './DashboardEditPane';
+import { EditPaneHeader } from './EditPaneHeader';
+import { ElementSelection } from './ElementSelection';
+
+// Mock DashboardInteractions
+jest.mock('../utils/interactions', () => ({
+ DashboardInteractions: {
+ trackRemoveRowClick: jest.fn(),
+ trackRemoveTabClick: jest.fn(),
+ },
+}));
+
+const sceneWithTab = new DashboardScene({
+ $timeRange: new SceneTimeRange({ from: 'now-6h', to: 'now' }),
+ isEditing: true,
+ body: new TabsLayoutManager({
+ tabs: [
+ new TabItem({
+ title: 'test tab',
+ }),
+ ],
+ }),
+});
+
+const sceneWithRow = new DashboardScene({
+ $timeRange: new SceneTimeRange({ from: 'now-6h', to: 'now' }),
+ isEditing: true,
+ body: new RowsLayoutManager({
+ rows: [
+ new RowItem({
+ title: 'test row',
+ }),
+ ],
+ }),
+});
+
+const buildTestScene = (scene: DashboardScene) => {
+ activateFullSceneTree(scene);
+ return scene;
+};
+
+describe('EditPaneHeader', () => {
+ const mockEditPane = {
+ state: { selection: null },
+ clearSelection: jest.fn(),
+ } as unknown as DashboardEditPane;
+
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ describe('tracking item deletion', () => {
+ it('should call DashboardActions.trackDeleteRow when deleting a row', async () => {
+ const user = userEvent.setup();
+ const scene = buildTestScene(sceneWithRow);
+ const row = (scene.state.body as RowsLayoutManager).state.rows[0];
+ const elementSelection = new ElementSelection([['row-test', row.getRef()]]);
+ const editableElement = elementSelection.createSelectionElement()!;
+
+ render();
+
+ await user.click(screen.getByTestId(selectors.components.EditPaneHeader.deleteButton));
+ expect(DashboardInteractions.trackRemoveRowClick).toHaveBeenCalled();
+ });
+
+ it('should call DashboardActions.trackDeleteTab when deleting a tab', async () => {
+ const user = userEvent.setup();
+ const scene = buildTestScene(sceneWithTab);
+ const tab = (scene.state.body as TabsLayoutManager).state.tabs[0];
+ const elementSelection = new ElementSelection([['tab-test', tab.getRef()]]);
+ const editableElement = elementSelection.createSelectionElement()!;
+
+ render();
+
+ await user.click(screen.getByTestId(selectors.components.EditPaneHeader.deleteButton));
+ expect(DashboardInteractions.trackRemoveTabClick).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx b/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx
index a98674d84d0..e0e5a74a10a 100644
--- a/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx
+++ b/public/app/features/dashboard-scene/edit-pane/EditPaneHeader.tsx
@@ -4,6 +4,7 @@ import { GrafanaTheme2 } from '@grafana/data';
import { selectors } from '@grafana/e2e-selectors';
import { t } from '@grafana/i18n';
import { Button, Menu, Stack, Text, useStyles2, Dropdown, Icon, IconButton } from '@grafana/ui';
+import { trackDeleteDashboardElement } from 'app/features/dashboard/utils/tracking';
import { EditableDashboardElement } from '../scene/types/EditableDashboardElement';
@@ -26,6 +27,15 @@ export function EditPaneHeader({ element, editPane }: EditPaneHeaderProps) {
const onGoBack = () => editPane.clearSelection();
const canGoBack = editPane.state.selection;
+ const onDeleteElement = () => {
+ if (onConfirmDelete) {
+ onConfirmDelete();
+ } else if (onDelete) {
+ onDelete();
+ }
+ trackDeleteDashboardElement(elementInfo);
+ };
+
return (
@@ -75,7 +85,7 @@ export function EditPaneHeader({ element, editPane }: EditPaneHeaderProps) {
{(onDelete || onConfirmDelete) && (
@@ -41,15 +45,19 @@ export function CanvasGridAddActions({ layoutManager }: Props) {
{
addNewRowTo(layoutManager);
+ DashboardInteractions.trackGroupRowClick();
}}
>
{
addNewTabTo(layoutManager);
+ DashboardInteractions.trackGroupTabClick();
}}
>
@@ -67,11 +75,13 @@ export function CanvasGridAddActions({ layoutManager }: Props) {
{renderUngroupAction(layoutManager)}
{hasCopiedPanel && layoutManager.pastePanel && (