Dashboard: Auto focus title fields in edit pane (#101668)
* Dashboard: Auto focus title fields in edit pane * Fix scroll issue * Update * No auto focus in panel edit * Update to implementation * alt skip fix * fixed playwright test * Update * Fix
This commit is contained in:
@@ -15,11 +15,13 @@ import {
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { isInCloneChain } from '../utils/clone';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { DashboardAddPane } from './DashboardAddPane';
|
||||
import { DashboardOutline } from './DashboardOutline';
|
||||
import { ElementEditPane } from './ElementEditPane';
|
||||
import { ElementSelection } from './ElementSelection';
|
||||
import { NewObjectAddedToCanvasEvent } from './shared';
|
||||
import { useEditableElement } from './useEditableElement';
|
||||
|
||||
export interface DashboardEditPaneState extends SceneObjectState {
|
||||
@@ -39,6 +41,18 @@ export class DashboardEditPane extends SceneObjectBase<DashboardEditPaneState> {
|
||||
onSelect: (item, multi) => this.selectElement(item, multi),
|
||||
},
|
||||
});
|
||||
|
||||
this.addActivationHandler(this.onActivate.bind(this));
|
||||
}
|
||||
|
||||
private onActivate() {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
|
||||
this._subs.add(
|
||||
dashboard.subscribeToEvent(NewObjectAddedToCanvasEvent, ({ payload }) => {
|
||||
this.newObjectAddedToCanvas(payload);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
public enableSelection() {
|
||||
@@ -134,7 +148,7 @@ export class DashboardEditPane extends SceneObjectBase<DashboardEditPaneState> {
|
||||
this.setState({ tab });
|
||||
};
|
||||
|
||||
public newObjectAddedToCanvas(obj: SceneObject) {
|
||||
private newObjectAddedToCanvas(obj: SceneObject) {
|
||||
this.selectObject(obj, obj.state.key!, false);
|
||||
|
||||
if (this.state.tab !== 'configure') {
|
||||
@@ -173,13 +187,12 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
const styles = useStyles2(getStyles);
|
||||
const paneRef = useRef<HTMLDivElement>(null);
|
||||
const editableElement = useEditableElement(selection, editPane);
|
||||
const selectedObject = selection?.getFirstObject();
|
||||
|
||||
if (!editableElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { typeId } = editableElement.getEditableElementInfo();
|
||||
|
||||
if (isCollapsed) {
|
||||
return (
|
||||
<>
|
||||
@@ -196,7 +209,7 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
|
||||
{openOverlay && (
|
||||
<Resizable className={cx(styles.fixed, styles.container)} defaultSize={{ height: '100%', width: '20vw' }}>
|
||||
<ElementEditPane element={editableElement} key={typeId} />
|
||||
<ElementEditPane element={editableElement} key={selectedObject?.state.key} />
|
||||
</Resizable>
|
||||
)}
|
||||
</>
|
||||
@@ -224,7 +237,7 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
</TabsBar>
|
||||
<div className={styles.tabContent}>
|
||||
{tab === 'add' && <DashboardAddPane editPane={editPane} />}
|
||||
{tab === 'configure' && <ElementEditPane element={editableElement} key={typeId} />}
|
||||
{tab === 'configure' && <ElementEditPane element={editableElement} key={selectedObject?.state.key} />}
|
||||
{tab === 'outline' && <DashboardOutline editPane={editPane} />}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useSessionStorage } from 'react-use';
|
||||
|
||||
import { BusEventWithPayload } from '@grafana/data';
|
||||
import { SceneGridRow, SceneObject, VizPanel } from '@grafana/scenes';
|
||||
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
@@ -53,3 +54,7 @@ export function hasEditableElement(sceneObj: SceneObject | undefined): boolean {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export class NewObjectAddedToCanvasEvent extends BusEventWithPayload<SceneObject> {
|
||||
static type = 'new-object-added-to-canvas';
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CoreApp } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { config } from '@grafana/runtime';
|
||||
import { SceneTimeRangeLike, VizPanel } from '@grafana/scenes';
|
||||
@@ -10,6 +11,7 @@ import { getPanelLinksVariableSuggestions } from 'app/features/panel/panellinks/
|
||||
|
||||
import { VizPanelLinks } from '../scene/PanelLinks';
|
||||
import { PanelTimeRange } from '../scene/PanelTimeRange';
|
||||
import { useEditPaneInputAutoFocus } from '../scene/layouts-shared/utils';
|
||||
import { isDashboardLayoutItem } from '../scene/types/DashboardLayoutItem';
|
||||
import { vizPanelToPanel, transformSceneToSaveModel } from '../serialization/transformSceneToSaveModel';
|
||||
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
|
||||
@@ -108,9 +110,11 @@ function ScenePanelLinksEditor({ panelLinks }: ScenePanelLinksEditorProps) {
|
||||
|
||||
export function PanelFrameTitleInput({ panel }: { panel: VizPanel }) {
|
||||
const { title } = panel.useState();
|
||||
let ref = useEditPaneInputAutoFocus({ noAutoFocus: panel.getPanelContext().app === CoreApp.PanelEditor });
|
||||
|
||||
return (
|
||||
<Input
|
||||
ref={ref}
|
||||
data-testid={selectors.components.PanelEditor.OptionsPane.fieldInput('Title')}
|
||||
value={title}
|
||||
onChange={(e) => setPanelTitle(panel, e.currentTarget.value)}
|
||||
|
||||
@@ -453,16 +453,22 @@ describe('DashboardScene', () => {
|
||||
});
|
||||
|
||||
it('Should select new panel', () => {
|
||||
scene.state.editPane.activate();
|
||||
|
||||
const panel = scene.onCreateNewPanel();
|
||||
expect(scene.state.editPane.state.selection?.getFirstObject()).toBe(panel);
|
||||
});
|
||||
|
||||
it('Should select new row', () => {
|
||||
scene.state.editPane.activate();
|
||||
|
||||
const row = scene.onCreateNewRow();
|
||||
expect(scene.state.editPane.state.selection?.getFirstObject()).toBe(row);
|
||||
});
|
||||
|
||||
it('Should select new tab', () => {
|
||||
scene.state.editPane.activate();
|
||||
|
||||
const tab = scene.onCreateNewTab();
|
||||
expect(scene.state.editPane.state.selection?.getFirstObject()).toBe(tab);
|
||||
});
|
||||
|
||||
@@ -490,8 +490,6 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> impleme
|
||||
|
||||
// Add panel to layout
|
||||
this.state.body.addPanel(vizPanel);
|
||||
// Select panel
|
||||
this.state.editPane.newObjectAddedToCanvas(vizPanel);
|
||||
}
|
||||
|
||||
public createLibraryPanel(panelToReplace: VizPanel, libPanel: LibraryPanel) {
|
||||
@@ -599,15 +597,11 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> impleme
|
||||
}
|
||||
|
||||
public onCreateNewRow() {
|
||||
const newRow = addNewRowTo(this.state.body);
|
||||
this.state.editPane.newObjectAddedToCanvas(newRow);
|
||||
return newRow;
|
||||
return addNewRowTo(this.state.body);
|
||||
}
|
||||
|
||||
public onCreateNewTab() {
|
||||
const tab = addNewTabTo(this.state.body);
|
||||
this.state.editPane.newObjectAddedToCanvas(tab);
|
||||
return tab;
|
||||
return addNewTabTo(this.state.body);
|
||||
}
|
||||
|
||||
public onCreateNewPanel(): VizPanel {
|
||||
|
||||
+8
-2
@@ -15,6 +15,7 @@ import { GRID_COLUMN_COUNT } from 'app/core/constants';
|
||||
import { t } from 'app/core/internationalization';
|
||||
import DashboardEmpty from 'app/features/dashboard/dashgrid/DashboardEmpty';
|
||||
|
||||
import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared';
|
||||
import { isClonedKey, joinCloneKeys } from '../../utils/clone';
|
||||
import { dashboardSceneGraph } from '../../utils/dashboardSceneGraph';
|
||||
import {
|
||||
@@ -77,6 +78,8 @@ export class DefaultGridLayoutManager
|
||||
this.state.grid.setState({
|
||||
children: [newGridItem, ...this.state.grid.state.children],
|
||||
});
|
||||
|
||||
this.publishEvent(new NewObjectAddedToCanvasEvent(vizPanel), true);
|
||||
}
|
||||
|
||||
public removePanel(panel: VizPanel) {
|
||||
@@ -132,6 +135,8 @@ export class DefaultGridLayoutManager
|
||||
// when we duplicate a panel we don't want to clone the alert state
|
||||
delete panelData.state.data?.alertState;
|
||||
|
||||
const newPanel = new VizPanel({ ...panelState, $data: panelData, key: getVizPanelKeyForPanelId(newPanelId) });
|
||||
|
||||
newGridItem = new DashboardGridItem({
|
||||
x: gridItem.state.x,
|
||||
y: gridItem.state.y,
|
||||
@@ -142,19 +147,20 @@ export class DefaultGridLayoutManager
|
||||
repeatDirection: gridItem.state.repeatDirection,
|
||||
maxPerRow: gridItem.state.maxPerRow,
|
||||
key: getGridItemKeyForPanelId(newPanelId),
|
||||
body: new VizPanel({ ...panelState, $data: panelData, key: getVizPanelKeyForPanelId(newPanelId) }),
|
||||
body: newPanel,
|
||||
});
|
||||
|
||||
if (gridItem.parent instanceof SceneGridRow) {
|
||||
const row = gridItem.parent;
|
||||
|
||||
row.setState({ children: [...row.state.children, newGridItem] });
|
||||
|
||||
grid.forceRender();
|
||||
return;
|
||||
}
|
||||
|
||||
grid.setState({ children: [...grid.state.children, newGridItem] });
|
||||
|
||||
this.publishEvent(new NewObjectAddedToCanvasEvent(newPanel), true);
|
||||
}
|
||||
|
||||
public getVizPanels(): VizPanel[] {
|
||||
|
||||
+10
-3
@@ -2,6 +2,7 @@ import { SceneComponentProps, SceneCSSGridLayout, SceneObjectBase, SceneObjectSt
|
||||
import { t } from 'app/core/internationalization';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
|
||||
import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared';
|
||||
import { joinCloneKeys } from '../../utils/clone';
|
||||
import { dashboardSceneGraph } from '../../utils/dashboardSceneGraph';
|
||||
import { getGridItemKeyForPanelId, getPanelIdForVizPanel, getVizPanelKeyForPanelId } from '../../utils/utils';
|
||||
@@ -60,6 +61,8 @@ export class ResponsiveGridLayoutManager
|
||||
this.state.layout.setState({
|
||||
children: [new ResponsiveGridItem({ body: vizPanel }), ...this.state.layout.state.children],
|
||||
});
|
||||
|
||||
this.publishEvent(new NewObjectAddedToCanvasEvent(vizPanel), true);
|
||||
}
|
||||
|
||||
public removePanel(panel: VizPanel) {
|
||||
@@ -77,11 +80,13 @@ export class ResponsiveGridLayoutManager
|
||||
const newPanelId = dashboardSceneGraph.getNextPanelId(this);
|
||||
const grid = this.state.layout;
|
||||
|
||||
const newPanel = panel.clone({
|
||||
key: getVizPanelKeyForPanelId(newPanelId),
|
||||
});
|
||||
|
||||
const newGridItem = gridItem.clone({
|
||||
key: getGridItemKeyForPanelId(newPanelId),
|
||||
body: panel.clone({
|
||||
key: getVizPanelKeyForPanelId(newPanelId),
|
||||
}),
|
||||
body: newPanel,
|
||||
});
|
||||
|
||||
const sourceIndex = grid.state.children.indexOf(gridItem);
|
||||
@@ -91,6 +96,8 @@ export class ResponsiveGridLayoutManager
|
||||
newChildren.splice(sourceIndex + 1, 0, newGridItem);
|
||||
|
||||
grid.setState({ children: newChildren });
|
||||
|
||||
this.publishEvent(new NewObjectAddedToCanvasEvent(newPanel), true);
|
||||
}
|
||||
|
||||
public getVizPanels(): VizPanel[] {
|
||||
|
||||
@@ -14,6 +14,7 @@ import { EditPaneHeader } from '../../edit-pane/EditPaneHeader';
|
||||
import { getDashboardSceneFor, getQueryRunnerFor } from '../../utils/utils';
|
||||
import { DashboardScene } from '../DashboardScene';
|
||||
import { DashboardLayoutSelector } from '../layouts-shared/DashboardLayoutSelector';
|
||||
import { useEditPaneInputAutoFocus } from '../layouts-shared/utils';
|
||||
|
||||
import { RowItem } from './RowItem';
|
||||
|
||||
@@ -77,9 +78,11 @@ export function getEditOptions(model: RowItem): OptionsPaneCategoryDescriptor[]
|
||||
|
||||
function RowTitleInput({ row }: { row: RowItem }) {
|
||||
const { title } = row.useState();
|
||||
const ref = useEditPaneInputAutoFocus();
|
||||
|
||||
return (
|
||||
<Input
|
||||
ref={ref}
|
||||
title={t('dashboard.rows-layout.row-options.title-option', 'Title')}
|
||||
value={title}
|
||||
onChange={(e) => row.onChangeTitle(e.currentTarget.value)}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { SceneGridItemLike, SceneGridRow, SceneObjectBase, SceneObjectState, VizPanel } from '@grafana/scenes';
|
||||
import { t } from 'app/core/internationalization';
|
||||
|
||||
import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared';
|
||||
import { isClonedKey } from '../../utils/clone';
|
||||
import { dashboardSceneGraph } from '../../utils/dashboardSceneGraph';
|
||||
import { DashboardGridItem } from '../layout-default/DashboardGridItem';
|
||||
@@ -96,10 +97,14 @@ export class RowsLayoutManager extends SceneObjectBase<RowsLayoutManagerState> i
|
||||
}
|
||||
|
||||
public addRowAbove(row: RowItem) {
|
||||
const rows = this.state.rows;
|
||||
const index = rows.indexOf(row);
|
||||
rows.splice(index, 0, new RowItem());
|
||||
this.setState({ rows });
|
||||
const index = this.state.rows.indexOf(row);
|
||||
const newRow = new RowItem();
|
||||
const newRows = [...this.state.rows];
|
||||
|
||||
newRows.splice(index, 0, newRow);
|
||||
|
||||
this.setState({ rows: newRows });
|
||||
this.publishEvent(new NewObjectAddedToCanvasEvent(newRow), true);
|
||||
}
|
||||
|
||||
public addRowBelow(row: RowItem) {
|
||||
@@ -111,8 +116,13 @@ export class RowsLayoutManager extends SceneObjectBase<RowsLayoutManagerState> i
|
||||
index = index + 1;
|
||||
}
|
||||
|
||||
rows.splice(index + 1, 0, new RowItem());
|
||||
this.setState({ rows });
|
||||
const newRow = new RowItem();
|
||||
const newRows = [...this.state.rows];
|
||||
|
||||
newRows.splice(index + 1, 0, newRow);
|
||||
|
||||
this.setState({ rows: newRows });
|
||||
this.publishEvent(new NewObjectAddedToCanvasEvent(newRow), true);
|
||||
}
|
||||
|
||||
public removeRow(row: RowItem) {
|
||||
|
||||
@@ -7,6 +7,7 @@ import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/Pan
|
||||
|
||||
import { EditPaneHeader } from '../../edit-pane/EditPaneHeader';
|
||||
import { useLayoutCategory } from '../layouts-shared/DashboardLayoutSelector';
|
||||
import { useEditPaneInputAutoFocus } from '../layouts-shared/utils';
|
||||
|
||||
import { TabItem } from './TabItem';
|
||||
|
||||
@@ -35,6 +36,7 @@ export function getEditOptions(model: TabItem): OptionsPaneCategoryDescriptor[]
|
||||
|
||||
function TabTitleInput({ tab }: { tab: TabItem }) {
|
||||
const { title } = tab.useState();
|
||||
const ref = useEditPaneInputAutoFocus();
|
||||
|
||||
return <Input value={title} onChange={(e) => tab.onChangeTitle(e.currentTarget.value)} />;
|
||||
return <Input ref={ref} value={title} onChange={(e) => tab.onChangeTitle(e.currentTarget.value)} />;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import { SceneGridRow, SceneObject } from '@grafana/scenes';
|
||||
import { SceneGridRow } from '@grafana/scenes';
|
||||
|
||||
import { NewObjectAddedToCanvasEvent } from '../../edit-pane/shared';
|
||||
import { DefaultGridLayoutManager } from '../layout-default/DefaultGridLayoutManager';
|
||||
import { RowItem } from '../layout-rows/RowItem';
|
||||
import { RowsLayoutManager } from '../layout-rows/RowsLayoutManager';
|
||||
import { TabItem } from '../layout-tabs/TabItem';
|
||||
import { TabsLayoutManager } from '../layout-tabs/TabsLayoutManager';
|
||||
import { DashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
import { isLayoutParent } from '../types/LayoutParent';
|
||||
|
||||
export function addNewTabTo(sceneObject: SceneObject): TabItem {
|
||||
if (sceneObject instanceof TabsLayoutManager) {
|
||||
return sceneObject.addNewTab();
|
||||
export function addNewTabTo(layout: DashboardLayoutManager): TabItem {
|
||||
if (layout instanceof TabsLayoutManager) {
|
||||
const tab = layout.addNewTab();
|
||||
layout.publishEvent(new NewObjectAddedToCanvasEvent(tab), true);
|
||||
return tab;
|
||||
}
|
||||
|
||||
const layoutParent = sceneObject.parent!;
|
||||
const layoutParent = layout.parent!;
|
||||
if (!isLayoutParent(layoutParent)) {
|
||||
throw new Error('Parent layout is not a LayoutParent');
|
||||
}
|
||||
@@ -20,24 +24,31 @@ export function addNewTabTo(sceneObject: SceneObject): TabItem {
|
||||
const tabsLayout = TabsLayoutManager.createFromLayout(layoutParent.getLayout());
|
||||
layoutParent.switchLayout(tabsLayout);
|
||||
|
||||
return tabsLayout.state.tabs[0];
|
||||
const tab = tabsLayout.state.tabs[0];
|
||||
layout.publishEvent(new NewObjectAddedToCanvasEvent(tab), true);
|
||||
|
||||
return tab;
|
||||
}
|
||||
|
||||
export function addNewRowTo(sceneObject: SceneObject): RowItem | SceneGridRow {
|
||||
if (sceneObject instanceof RowsLayoutManager) {
|
||||
return sceneObject.addNewRow();
|
||||
export function addNewRowTo(layout: DashboardLayoutManager): RowItem | SceneGridRow {
|
||||
if (layout instanceof RowsLayoutManager) {
|
||||
const row = layout.addNewRow();
|
||||
layout.publishEvent(new NewObjectAddedToCanvasEvent(row), true);
|
||||
return row;
|
||||
}
|
||||
|
||||
if (sceneObject instanceof DefaultGridLayoutManager) {
|
||||
return sceneObject.addNewRow();
|
||||
if (layout instanceof DefaultGridLayoutManager) {
|
||||
const row = layout.addNewRow();
|
||||
layout.publishEvent(new NewObjectAddedToCanvasEvent(row), true);
|
||||
return row;
|
||||
}
|
||||
|
||||
if (sceneObject instanceof TabsLayoutManager) {
|
||||
const currentTab = sceneObject.getCurrentTab();
|
||||
if (layout instanceof TabsLayoutManager) {
|
||||
const currentTab = layout.getCurrentTab();
|
||||
return addNewRowTo(currentTab.state.layout);
|
||||
}
|
||||
|
||||
const layoutParent = sceneObject.parent!;
|
||||
const layoutParent = layout.parent!;
|
||||
if (!isLayoutParent(layoutParent)) {
|
||||
throw new Error('Parent layout is not a LayoutParent');
|
||||
}
|
||||
@@ -45,5 +56,8 @@ export function addNewRowTo(sceneObject: SceneObject): RowItem | SceneGridRow {
|
||||
const rowsLayout = RowsLayoutManager.createFromLayout(layoutParent.getLayout());
|
||||
layoutParent.switchLayout(rowsLayout);
|
||||
|
||||
return rowsLayout.state.rows[0];
|
||||
const row = rowsLayout.state.rows[0];
|
||||
layout.publishEvent(new NewObjectAddedToCanvasEvent(row), true);
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
import { SceneObject } from '@grafana/scenes';
|
||||
|
||||
import { DashboardLayoutManager, isDashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
@@ -15,3 +17,20 @@ export function findParentLayout(sceneObject: SceneObject): DashboardLayoutManag
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export interface EditPaneInputAutoFocusProps {
|
||||
noAutoFocus?: boolean;
|
||||
}
|
||||
|
||||
export function useEditPaneInputAutoFocus({ noAutoFocus }: EditPaneInputAutoFocusProps = {}) {
|
||||
const ref = useRef<HTMLInputElement>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current && !noAutoFocus) {
|
||||
// Need the setTimeout here for some reason
|
||||
setTimeout(() => ref.current?.focus(), 200);
|
||||
}
|
||||
}, [noAutoFocus]);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ import { DashboardScene } from './DashboardScene';
|
||||
|
||||
export function setDashboardPanelContext(vizPanel: VizPanel, context: PanelContext) {
|
||||
const dashboard = getDashboardSceneFor(vizPanel);
|
||||
context.app = dashboard.state.isEditing ? CoreApp.PanelEditor : CoreApp.Dashboard;
|
||||
context.app = dashboard.state.editPanel ? CoreApp.PanelEditor : CoreApp.Dashboard;
|
||||
|
||||
dashboard.subscribeToState((state) => {
|
||||
if (state.isEditing) {
|
||||
if (state.editPanel) {
|
||||
context.app = CoreApp.PanelEditor;
|
||||
} else {
|
||||
context.app = CoreApp.Dashboard;
|
||||
|
||||
@@ -19,6 +19,7 @@ import { LibraryPanelBehavior } from '../scene/LibraryPanelBehavior';
|
||||
import { VizPanelLinks, VizPanelLinksMenu } from '../scene/PanelLinks';
|
||||
import { panelMenuBehavior } from '../scene/PanelMenuBehavior';
|
||||
import { DashboardGridItem } from '../scene/layout-default/DashboardGridItem';
|
||||
import { setDashboardPanelContext } from '../scene/setDashboardPanelContext';
|
||||
import { DashboardLayoutManager, isDashboardLayoutManager } from '../scene/types/DashboardLayoutManager';
|
||||
|
||||
import { containsCloneKey, getLastKeyFromClone, getOriginalKey, isInCloneChain } from './clone';
|
||||
@@ -323,6 +324,7 @@ export function getDefaultVizPanel(): VizPanel {
|
||||
titleItems: [new VizPanelLinks({ menu: new VizPanelLinksMenu({}) })],
|
||||
hoverHeaderOffset: 0,
|
||||
$behaviors: [],
|
||||
extendPanelContext: setDashboardPanelContext,
|
||||
menu: new VizPanelMenu({
|
||||
$behaviors: [panelMenuBehavior],
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user