mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboard: Edit mode element selection (#97718)
* Dashboard: Edit mode elemenmt selection * Add new panel to rows layout (#97729) * Add new panel to rows layout * Use `DashboardEditPane` to obtain selected object * Fixed rows bottom padding issue * Update * Minor fix * Update * Update * Update --------- Co-authored-by: Bogdan Matei <bogdan.matei@grafana.com>
This commit is contained in:
parent
0f9b107201
commit
e0cfd12fb3
@ -328,4 +328,5 @@ export {
|
||||
ElementSelectionContext,
|
||||
useElementSelection,
|
||||
type ElementSelectionContextState,
|
||||
type ElementSelectionContextItem,
|
||||
} from './ElementSelectionContext/ElementSelectionContext';
|
||||
|
@ -2,27 +2,78 @@ import { css } from '@emotion/css';
|
||||
import { useEffect, useRef } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { SceneObjectState, SceneObjectBase, SceneObject, SceneObjectRef } from '@grafana/scenes';
|
||||
import { ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
import {
|
||||
SceneObjectState,
|
||||
SceneObjectBase,
|
||||
SceneObject,
|
||||
SceneObjectRef,
|
||||
sceneGraph,
|
||||
useSceneObjectState,
|
||||
} from '@grafana/scenes';
|
||||
import { ElementSelectionContextItem, ElementSelectionContextState, ToolbarButton, useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { EditableDashboardElement, isEditableDashboardElement } from '../scene/types';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
import { ElementEditPane } from './ElementEditPane';
|
||||
import { useEditableElement } from './useEditableElement';
|
||||
|
||||
export interface DashboardEditPaneState extends SceneObjectState {
|
||||
selectedObject?: SceneObjectRef<SceneObject>;
|
||||
selectionContext: ElementSelectionContextState;
|
||||
}
|
||||
|
||||
export class DashboardEditPane extends SceneObjectBase<DashboardEditPaneState> {
|
||||
public selectObject(obj: SceneObject) {
|
||||
public constructor() {
|
||||
super({
|
||||
selectionContext: {
|
||||
enabled: false,
|
||||
selected: [],
|
||||
onSelect: (item, multi) => this.selectElement(item, multi),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public enableSelection() {
|
||||
// Enable element selection
|
||||
this.setState({ selectionContext: { ...this.state.selectionContext, enabled: true } });
|
||||
}
|
||||
|
||||
public disableSelection() {
|
||||
this.setState({ selectionContext: { ...this.state.selectionContext, enabled: false } });
|
||||
}
|
||||
|
||||
private selectElement(element: ElementSelectionContextItem, multi?: boolean) {
|
||||
const obj = sceneGraph.findByKey(this, element.id);
|
||||
if (obj) {
|
||||
this.selectObject(obj, element.id, multi);
|
||||
}
|
||||
}
|
||||
|
||||
public selectObject(obj: SceneObject, id: string, multi?: boolean) {
|
||||
const currentSelection = this.state.selectedObject?.resolve();
|
||||
if (currentSelection === obj) {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
this.setState({ selectedObject: dashboard.getRef() });
|
||||
} else {
|
||||
this.setState({ selectedObject: obj.getRef() });
|
||||
this.clearSelection();
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
selectedObject: obj.getRef(),
|
||||
selectionContext: {
|
||||
...this.state.selectionContext,
|
||||
selected: [{ id }],
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
public clearSelection() {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
this.setState({
|
||||
selectedObject: dashboard.getRef(),
|
||||
selectionContext: {
|
||||
...this.state.selectionContext,
|
||||
selected: [],
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,14 +93,20 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
const dashboard = getDashboardSceneFor(editPane);
|
||||
editPane.setState({ selectedObject: dashboard.getRef() });
|
||||
}
|
||||
editPane.activate();
|
||||
|
||||
editPane.enableSelection();
|
||||
|
||||
return () => {
|
||||
editPane.disableSelection();
|
||||
};
|
||||
}, [editPane]);
|
||||
|
||||
const { selectedObject } = editPane.useState();
|
||||
const { selectedObject } = useSceneObjectState(editPane, { shouldActivateOrKeepAlive: true });
|
||||
const styles = useStyles2(getStyles);
|
||||
const paneRef = useRef<HTMLDivElement>(null);
|
||||
const editableElement = useEditableElement(selectedObject?.resolve());
|
||||
|
||||
if (!selectedObject) {
|
||||
if (!editableElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -68,29 +125,13 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
);
|
||||
}
|
||||
|
||||
const element = getEditableElementFor(selectedObject.resolve());
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper} ref={paneRef}>
|
||||
<ElementEditPane element={element} key={element.getTypeName()} />
|
||||
<ElementEditPane element={editableElement} key={editableElement.getTypeName()} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function getEditableElementFor(obj: SceneObject): EditableDashboardElement {
|
||||
if (isEditableDashboardElement(obj)) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
for (const behavior of obj.state.$behaviors ?? []) {
|
||||
if (isEditableDashboardElement(behavior)) {
|
||||
return behavior;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error("Can't find editable element for selected object");
|
||||
}
|
||||
|
||||
function getStyles(theme: GrafanaTheme2) {
|
||||
return {
|
||||
wrapper: css({
|
||||
|
@ -3,7 +3,8 @@ import React, { CSSProperties, useEffect } from 'react';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { config, useChromeHeaderHeight } from '@grafana/runtime';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
import { useSceneObjectState } from '@grafana/scenes';
|
||||
import { ElementSelectionContext, useStyles2 } from '@grafana/ui';
|
||||
import NativeScrollbar from 'app/core/components/NativeScrollbar';
|
||||
|
||||
import { useSnappingSplitter } from '../panel-edit/splitter/useSnappingSplitter';
|
||||
@ -22,6 +23,7 @@ interface Props {
|
||||
|
||||
export function DashboardEditPaneSplitter({ dashboard, isEditing, body, controls }: Props) {
|
||||
const headerHeight = useChromeHeaderHeight();
|
||||
const { editPane } = dashboard.state;
|
||||
const styles = useStyles2(getStyles, headerHeight ?? 0);
|
||||
const [isCollapsed, setIsCollapsed] = useEditPaneCollapsed();
|
||||
|
||||
@ -55,6 +57,7 @@ export function DashboardEditPaneSplitter({ dashboard, isEditing, body, controls
|
||||
setIsCollapsed(splitterState.collapsed);
|
||||
}, [splitterState.collapsed, setIsCollapsed]);
|
||||
|
||||
const { selectionContext } = useSceneObjectState(editPane, { shouldActivateOrKeepAlive: true });
|
||||
const containerStyle: CSSProperties = {};
|
||||
|
||||
if (!isEditing) {
|
||||
@ -70,12 +73,16 @@ export function DashboardEditPaneSplitter({ dashboard, isEditing, body, controls
|
||||
|
||||
return (
|
||||
<div {...containerProps} style={containerStyle}>
|
||||
<div {...primaryProps} className={cx(primaryProps.className, styles.canvasWithSplitter)}>
|
||||
<div
|
||||
{...primaryProps}
|
||||
className={cx(primaryProps.className, styles.canvasWithSplitter)}
|
||||
onPointerDown={() => editPane.clearSelection()}
|
||||
>
|
||||
<NavToolbarActions dashboard={dashboard} />
|
||||
<div className={cx(!isEditing && styles.controlsWrapperSticky)}>{controls}</div>
|
||||
<div className={styles.bodyWrapper}>
|
||||
<div className={cx(styles.body, isEditing && styles.bodyEditing)} ref={onBodyRef}>
|
||||
{body}
|
||||
<ElementSelectionContext.Provider value={selectionContext}>{body}</ElementSelectionContext.Provider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -84,7 +91,7 @@ export function DashboardEditPaneSplitter({ dashboard, isEditing, body, controls
|
||||
<div {...splitterProps} data-edit-pane-splitter={true} />
|
||||
<div {...secondaryProps} className={cx(secondaryProps.className, styles.editPane)}>
|
||||
<DashboardEditPaneRenderer
|
||||
editPane={dashboard.state.editPane}
|
||||
editPane={editPane}
|
||||
isCollapsed={splitterState.collapsed}
|
||||
onToggleCollapse={onToggleCollapse}
|
||||
/>
|
||||
@ -136,6 +143,8 @@ function getStyles(theme: GrafanaTheme2, headerHeight: number) {
|
||||
bottom: 0,
|
||||
overflow: 'auto',
|
||||
scrollbarWidth: 'thin',
|
||||
// The fixed controls headers is otherwise rendered over the selection outlinem, Maybe there is an other solution
|
||||
paddingTop: '2px',
|
||||
}),
|
||||
editPane: css({
|
||||
flexDirection: 'column',
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { SceneObjectBase } from '@grafana/scenes';
|
||||
import { Input, TextArea } from '@grafana/ui';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
@ -8,13 +7,14 @@ import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/Pan
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { useLayoutCategory } from '../scene/layouts-shared/DashboardLayoutSelector';
|
||||
import { EditableDashboardElement } from '../scene/types';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
||||
export class DashboardEditPaneBehavior extends SceneObjectBase implements EditableDashboardElement {
|
||||
export class DashboardEditableElement implements EditableDashboardElement {
|
||||
public isEditableDashboardElement: true = true;
|
||||
|
||||
public constructor(private dashboard: DashboardScene) {}
|
||||
|
||||
public useEditPaneOptions(): OptionsPaneCategoryDescriptor[] {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
const dashboard = this.dashboard;
|
||||
|
||||
// When layout changes we need to update options list
|
||||
const { body } = dashboard.useState();
|
@ -1,7 +1,8 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { sceneGraph, SceneObjectBase, VizPanel } from '@grafana/scenes';
|
||||
import { sceneGraph, VizPanel } from '@grafana/scenes';
|
||||
import { Button } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
import { getVisualizationOptions2 } from 'app/features/dashboard/components/PanelEditor/getVisualizationOptions';
|
||||
@ -14,21 +15,13 @@ import {
|
||||
import { EditableDashboardElement, isDashboardLayoutItem } from '../scene/types';
|
||||
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
|
||||
|
||||
export class VizPanelEditPaneBehavior extends SceneObjectBase implements EditableDashboardElement {
|
||||
export class VizPanelEditableElement implements EditableDashboardElement {
|
||||
public isEditableDashboardElement: true = true;
|
||||
|
||||
private getPanel(): VizPanel {
|
||||
const panel = this.parent;
|
||||
|
||||
if (!(panel instanceof VizPanel)) {
|
||||
throw new Error('VizPanelEditPaneBehavior must have a VizPanel parent');
|
||||
}
|
||||
|
||||
return panel;
|
||||
}
|
||||
public constructor(private panel: VizPanel) {}
|
||||
|
||||
public useEditPaneOptions(): OptionsPaneCategoryDescriptor[] {
|
||||
const panel = this.getPanel();
|
||||
const panel = this.panel;
|
||||
const layoutElement = panel.parent!;
|
||||
|
||||
const panelOptions = useMemo(() => {
|
||||
@ -108,22 +101,18 @@ export class VizPanelEditPaneBehavior extends SceneObjectBase implements Editabl
|
||||
}
|
||||
|
||||
public onDelete = () => {
|
||||
const layout = dashboardSceneGraph.getLayoutManagerFor(this);
|
||||
layout.removePanel(this.getPanel());
|
||||
const layout = dashboardSceneGraph.getLayoutManagerFor(this.panel);
|
||||
layout.removePanel(this.panel);
|
||||
};
|
||||
|
||||
public renderActions(): React.ReactNode {
|
||||
return (
|
||||
<>
|
||||
<Button size="sm" variant="secondary">
|
||||
Edit
|
||||
</Button>
|
||||
<Button size="sm" variant="secondary">
|
||||
Copy
|
||||
</Button>
|
||||
<Button size="sm" variant="destructive" fill="outline" onClick={this.onDelete}>
|
||||
Delete
|
||||
<Trans i18nKey="panel.header-menu.edit">Edit</Trans>
|
||||
</Button>
|
||||
<Button size="sm" variant="secondary" icon="copy" />
|
||||
<Button size="sm" variant="destructive" fill="outline" onClick={this.onDelete} icon="trash-alt" />
|
||||
</>
|
||||
);
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { SceneObject, VizPanel } from '@grafana/scenes';
|
||||
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { EditableDashboardElement, isEditableDashboardElement } from '../scene/types';
|
||||
|
||||
import { DashboardEditableElement } from './DashboardEditableElement';
|
||||
import { VizPanelEditableElement } from './VizPanelEditableElement';
|
||||
|
||||
export function useEditableElement(sceneObj: SceneObject | undefined): EditableDashboardElement | undefined {
|
||||
return useMemo(() => {
|
||||
if (!sceneObj) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (isEditableDashboardElement(sceneObj)) {
|
||||
return sceneObj;
|
||||
}
|
||||
|
||||
if (sceneObj instanceof VizPanel) {
|
||||
return new VizPanelEditableElement(sceneObj);
|
||||
}
|
||||
|
||||
if (sceneObj instanceof DashboardScene) {
|
||||
return new DashboardEditableElement(sceneObj);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}, [sceneObj]);
|
||||
}
|
@ -188,7 +188,7 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
||||
body: state.body ?? DefaultGridLayoutManager.fromVizPanels(),
|
||||
links: state.links ?? [],
|
||||
...state,
|
||||
editPane: new DashboardEditPane({}),
|
||||
editPane: new DashboardEditPane(),
|
||||
});
|
||||
|
||||
this._scopesFacade = getClosestScopesFacade(this);
|
||||
@ -378,6 +378,7 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
||||
dashboard: new DashboardModel(version.data),
|
||||
meta: this.state.meta,
|
||||
};
|
||||
|
||||
const dashScene = transformSaveModelToScene(dashboardDTO);
|
||||
const newState = sceneUtils.cloneSceneObjectState(dashScene.state);
|
||||
newState.version = versionRsp.version;
|
||||
|
@ -4,7 +4,7 @@ import { useMemo, useRef } from 'react';
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { selectors } from '@grafana/e2e-selectors';
|
||||
import { SceneObjectState, SceneObjectBase, SceneComponentProps, sceneGraph } from '@grafana/scenes';
|
||||
import { Button, Icon, Input, RadioButtonGroup, Switch, useStyles2 } from '@grafana/ui';
|
||||
import { Button, Icon, Input, RadioButtonGroup, Switch, useElementSelection, useStyles2 } from '@grafana/ui';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
|
||||
@ -72,15 +72,8 @@ export class RowItem extends SceneObjectBase<RowItemState> implements LayoutPare
|
||||
public renderActions(): React.ReactNode {
|
||||
return (
|
||||
<>
|
||||
<Button size="sm" variant="secondary">
|
||||
Copy
|
||||
</Button>
|
||||
<Button size="sm" variant="primary" onClick={this.onAddPanel} fill="outline">
|
||||
Add panel
|
||||
</Button>
|
||||
<Button size="sm" variant="destructive" fill="outline" onClick={this.onDelete}>
|
||||
Delete
|
||||
</Button>
|
||||
<Button size="sm" variant="secondary" icon="copy" />
|
||||
<Button size="sm" variant="destructive" fill="outline" onClick={this.onDelete} icon="trash-alt" />
|
||||
</>
|
||||
);
|
||||
}
|
||||
@ -97,16 +90,10 @@ export class RowItem extends SceneObjectBase<RowItemState> implements LayoutPare
|
||||
this.setState({ isCollapsed: !this.state.isCollapsed });
|
||||
};
|
||||
|
||||
public onAddPanel = () => {
|
||||
const vizPanel = getDefaultVizPanel();
|
||||
public onAddPanel = (vizPanel = getDefaultVizPanel()) => {
|
||||
this.state.layout.addPanel(vizPanel);
|
||||
};
|
||||
|
||||
public onEdit = () => {
|
||||
const dashboard = getDashboardSceneFor(this);
|
||||
dashboard.state.editPane.selectObject(this);
|
||||
};
|
||||
|
||||
public static Component = ({ model }: SceneComponentProps<RowItem>) => {
|
||||
const { layout, title, isCollapsed, height = 'expand' } = model.useState();
|
||||
const { isEditing } = getDashboardSceneFor(model).useState();
|
||||
@ -114,10 +101,16 @@ export class RowItem extends SceneObjectBase<RowItemState> implements LayoutPare
|
||||
const titleInterpolated = sceneGraph.interpolate(model, title, undefined, 'text');
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
const shouldGrow = !isCollapsed && height === 'expand';
|
||||
const { isSelected, onSelect } = useElementSelection(model.state.key);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cx(styles.wrapper, isCollapsed && styles.wrapperCollapsed, shouldGrow && styles.wrapperGrow)}
|
||||
className={cx(
|
||||
styles.wrapper,
|
||||
isCollapsed && styles.wrapperCollapsed,
|
||||
shouldGrow && styles.wrapperGrow,
|
||||
isSelected && 'dashboard-selected-element'
|
||||
)}
|
||||
ref={ref}
|
||||
>
|
||||
<div className={styles.rowHeader}>
|
||||
@ -132,7 +125,9 @@ export class RowItem extends SceneObjectBase<RowItemState> implements LayoutPare
|
||||
{titleInterpolated}
|
||||
</span>
|
||||
</button>
|
||||
{isEditing && <Button icon="pen" variant="secondary" size="sm" fill="text" onClick={() => model.onEdit()} />}
|
||||
{isEditing && (
|
||||
<Button icon="pen" variant="secondary" size="sm" fill="text" onPointerDown={(evt) => onSelect?.(evt)} />
|
||||
)}
|
||||
</div>
|
||||
{!isCollapsed && <layout.Component model={layout} />}
|
||||
</div>
|
||||
|
@ -1,9 +1,10 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { SceneComponentProps, SceneObjectBase, SceneObjectState, VizPanel } from '@grafana/scenes';
|
||||
import { SceneComponentProps, sceneGraph, SceneObjectBase, SceneObjectState, VizPanel } from '@grafana/scenes';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
|
||||
import { DashboardScene } from '../DashboardScene';
|
||||
import { ResponsiveGridLayoutManager } from '../layout-responsive-grid/ResponsiveGridLayoutManager';
|
||||
import { DashboardLayoutManager, LayoutRegistryItem } from '../types';
|
||||
|
||||
@ -18,7 +19,22 @@ export class RowsLayoutManager extends SceneObjectBase<RowsLayoutManagerState> i
|
||||
|
||||
public editModeChanged(isEditing: boolean): void {}
|
||||
|
||||
public addPanel(vizPanel: VizPanel): void {}
|
||||
public addPanel(vizPanel: VizPanel): void {
|
||||
// Try to add new panels to the selected row
|
||||
const selectedObject = this.getSelectedObject();
|
||||
if (selectedObject instanceof RowItem) {
|
||||
return selectedObject.onAddPanel(vizPanel);
|
||||
}
|
||||
|
||||
// If we don't have selected row add it to the first row
|
||||
if (this.state.rows.length > 0) {
|
||||
return this.state.rows[0].onAddPanel(vizPanel);
|
||||
}
|
||||
|
||||
// Otherwise fallback to adding a new row and a panel
|
||||
this.addNewRow();
|
||||
this.state.rows[this.state.rows.length - 1].onAddPanel(vizPanel);
|
||||
}
|
||||
|
||||
public addNewRow(): void {
|
||||
this.setState({
|
||||
@ -67,6 +83,10 @@ export class RowsLayoutManager extends SceneObjectBase<RowsLayoutManagerState> i
|
||||
return RowsLayoutManager.getDescriptor();
|
||||
}
|
||||
|
||||
public getSelectedObject() {
|
||||
return sceneGraph.getAncestor(this, DashboardScene).state.editPane.state.selectedObject?.resolve();
|
||||
}
|
||||
|
||||
public static getDescriptor(): LayoutRegistryItem {
|
||||
return {
|
||||
name: 'Rows',
|
||||
@ -106,7 +126,7 @@ function getStyles(theme: GrafanaTheme2) {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: theme.spacing(1),
|
||||
height: '100%',
|
||||
flexGrow: 1,
|
||||
width: '100%',
|
||||
}),
|
||||
};
|
||||
|
@ -27,7 +27,6 @@ import { PanelModel } from 'app/features/dashboard/state/PanelModel';
|
||||
import { DashboardDTO, DashboardDataDTO } from 'app/types';
|
||||
|
||||
import { addPanelsOnLoadBehavior } from '../addToDashboard/addPanelsOnLoadBehavior';
|
||||
import { DashboardEditPaneBehavior } from '../edit-pane/DashboardEditPaneBehavior';
|
||||
import { AlertStatesDataLayer } from '../scene/AlertStatesDataLayer';
|
||||
import { DashboardAnnotationsDataLayer } from '../scene/DashboardAnnotationsDataLayer';
|
||||
import { DashboardControls } from '../scene/DashboardControls';
|
||||
@ -224,7 +223,6 @@ export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel,
|
||||
new behaviors.SceneQueryController(),
|
||||
registerDashboardMacro,
|
||||
registerPanelInteractionsReporter,
|
||||
new DashboardEditPaneBehavior({}),
|
||||
new behaviors.LiveNowTimer({ enabled: oldModel.liveNow }),
|
||||
preserveDashboardSceneStateInLocalStorage,
|
||||
addPanelsOnLoadBehavior,
|
||||
@ -238,11 +236,6 @@ export function createDashboardSceneFromDashboardModel(oldModel: DashboardModel,
|
||||
version: oldModel.version,
|
||||
}),
|
||||
];
|
||||
|
||||
if (config.featureToggles.dashboardNewLayouts) {
|
||||
behaviorList.push(new DashboardEditPaneBehavior({}));
|
||||
}
|
||||
|
||||
const dashboardScene = new DashboardScene({
|
||||
description: oldModel.description,
|
||||
editable: oldModel.editable,
|
||||
|
@ -176,7 +176,7 @@ describe('transformSceneToSaveModelSchemaV2', () => {
|
||||
}),
|
||||
}),
|
||||
meta: {},
|
||||
editPane: new DashboardEditPane({}),
|
||||
editPane: new DashboardEditPane(),
|
||||
$behaviors: [
|
||||
new behaviors.CursorSync({
|
||||
sync: DashboardCursorSyncV1.Crosshair,
|
||||
|
Loading…
Reference in New Issue
Block a user