mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Dashboards: Refactor types for dynamic dashboards (#100064)
This commit is contained in:
parent
bea62aa615
commit
f51571db5d
@ -3435,10 +3435,6 @@ exports[`better eslint`] = {
|
||||
"public/app/features/dashboard-scene/scene/UnlinkModal.tsx:5381": [
|
||||
[0, 0, 0, "No untranslated strings in text props. Wrap text with <Trans /> or use t()", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/types.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/serialization/angularMigration.test.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
|
@ -176,7 +176,7 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
|
||||
{openOverlay && (
|
||||
<Resizable className={cx(styles.fixed, styles.container)} defaultSize={{ height: '100%', width: '20vw' }}>
|
||||
<ElementEditPane element={editableElement} key={editableElement.getTypeName()} />
|
||||
<ElementEditPane element={editableElement} key={editableElement.typeName} />
|
||||
</Resizable>
|
||||
)}
|
||||
</>
|
||||
@ -185,7 +185,7 @@ export function DashboardEditPaneRenderer({ editPane, isCollapsed, onToggleColla
|
||||
|
||||
return (
|
||||
<div className={styles.wrapper} ref={paneRef}>
|
||||
<ElementEditPane element={editableElement} key={editableElement.getTypeName()} />
|
||||
<ElementEditPane element={editableElement} key={editableElement.typeName} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -6,10 +6,11 @@ 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 { EditableDashboardElement } from '../scene/types/EditableDashboardElement';
|
||||
|
||||
export class DashboardEditableElement implements EditableDashboardElement {
|
||||
public isEditableDashboardElement: true = true;
|
||||
public readonly isEditableDashboardElement = true;
|
||||
public readonly typeName = 'Dashboard';
|
||||
|
||||
public constructor(private dashboard: DashboardScene) {}
|
||||
|
||||
@ -47,10 +48,6 @@ export class DashboardEditableElement implements EditableDashboardElement {
|
||||
|
||||
return [dashboardOptions, layoutCategory];
|
||||
}
|
||||
|
||||
public getTypeName(): string {
|
||||
return 'Dashboard';
|
||||
}
|
||||
}
|
||||
|
||||
export function DashboardTitleInput({ dashboard }: { dashboard: DashboardScene }) {
|
||||
|
@ -4,7 +4,8 @@ import { GrafanaTheme2 } from '@grafana/data';
|
||||
import { Stack, useStyles2 } from '@grafana/ui';
|
||||
import { OptionsPaneCategory } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategory';
|
||||
|
||||
import { EditableDashboardElement, MultiSelectedEditableDashboardElement } from '../scene/types';
|
||||
import { EditableDashboardElement } from '../scene/types/EditableDashboardElement';
|
||||
import { MultiSelectedEditableDashboardElement } from '../scene/types/MultiSelectedEditableDashboardElement';
|
||||
|
||||
export interface Props {
|
||||
element: EditableDashboardElement | MultiSelectedEditableDashboardElement;
|
||||
@ -19,7 +20,7 @@ export function ElementEditPane({ element }: Props) {
|
||||
{element.renderActions && (
|
||||
<OptionsPaneCategory
|
||||
id="selected-item"
|
||||
title={element.getTypeName()}
|
||||
title={element.typeName}
|
||||
isOpenDefault={true}
|
||||
className={styles.noBorderTop}
|
||||
>
|
||||
|
@ -2,12 +2,9 @@ import { SceneObject, SceneObjectRef, VizPanel } from '@grafana/scenes';
|
||||
import { ElementSelectionContextItem } from '@grafana/ui';
|
||||
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import {
|
||||
EditableDashboardElement,
|
||||
isBulkActionElement,
|
||||
isEditableDashboardElement,
|
||||
MultiSelectedEditableDashboardElement,
|
||||
} from '../scene/types';
|
||||
import { isBulkActionElement } from '../scene/types/BulkActionElement';
|
||||
import { EditableDashboardElement, isEditableDashboardElement } from '../scene/types/EditableDashboardElement';
|
||||
import { MultiSelectedEditableDashboardElement } from '../scene/types/MultiSelectedEditableDashboardElement';
|
||||
|
||||
import { DashboardEditableElement } from './DashboardEditableElement';
|
||||
import { MultiSelectedObjectsEditableElement } from './MultiSelectedObjectsEditableElement';
|
||||
|
@ -3,10 +3,13 @@ import { ReactNode } from 'react';
|
||||
import { Stack, Text, Button } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
|
||||
import { BulkActionElement, MultiSelectedEditableDashboardElement } from '../scene/types';
|
||||
import { BulkActionElement } from '../scene/types/BulkActionElement';
|
||||
import { MultiSelectedEditableDashboardElement } from '../scene/types/MultiSelectedEditableDashboardElement';
|
||||
|
||||
export class MultiSelectedObjectsEditableElement implements MultiSelectedEditableDashboardElement {
|
||||
public isMultiSelectedEditableDashboardElement: true = true;
|
||||
public readonly isMultiSelectedEditableDashboardElement = true;
|
||||
public readonly typeName = 'Objects';
|
||||
|
||||
private items?: BulkActionElement[];
|
||||
|
||||
constructor(items: BulkActionElement[]) {
|
||||
@ -19,10 +22,6 @@ export class MultiSelectedObjectsEditableElement implements MultiSelectedEditabl
|
||||
}
|
||||
};
|
||||
|
||||
public getTypeName(): string {
|
||||
return 'Objects';
|
||||
}
|
||||
|
||||
renderActions(): ReactNode {
|
||||
return (
|
||||
<Stack direction="column">
|
||||
|
@ -5,11 +5,12 @@ import { Button, Stack, Text } from '@grafana/ui';
|
||||
import { Trans } from 'app/core/internationalization';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
|
||||
import { MultiSelectedEditableDashboardElement } from '../scene/types';
|
||||
import { MultiSelectedEditableDashboardElement } from '../scene/types/MultiSelectedEditableDashboardElement';
|
||||
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
|
||||
|
||||
export class MultiSelectedVizPanelsEditableElement implements MultiSelectedEditableDashboardElement {
|
||||
public isMultiSelectedEditableDashboardElement: true = true;
|
||||
public readonly isMultiSelectedEditableDashboardElement = true;
|
||||
public readonly typeName = 'Panels';
|
||||
|
||||
private items?: VizPanel[];
|
||||
|
||||
@ -34,10 +35,6 @@ export class MultiSelectedVizPanelsEditableElement implements MultiSelectedEdita
|
||||
}
|
||||
};
|
||||
|
||||
public getTypeName(): string {
|
||||
return 'Panels';
|
||||
}
|
||||
|
||||
renderActions(): ReactNode {
|
||||
return (
|
||||
<Stack direction="column">
|
||||
|
@ -12,11 +12,14 @@ import {
|
||||
PanelDescriptionTextArea,
|
||||
PanelFrameTitleInput,
|
||||
} from '../panel-edit/getPanelFrameOptions';
|
||||
import { BulkActionElement, EditableDashboardElement, isDashboardLayoutItem } from '../scene/types';
|
||||
import { BulkActionElement } from '../scene/types/BulkActionElement';
|
||||
import { isDashboardLayoutItem } from '../scene/types/DashboardLayoutItem';
|
||||
import { EditableDashboardElement } from '../scene/types/EditableDashboardElement';
|
||||
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
|
||||
|
||||
export class VizPanelEditableElement implements EditableDashboardElement, BulkActionElement {
|
||||
public isEditableDashboardElement: true = true;
|
||||
public readonly isEditableDashboardElement = true;
|
||||
public readonly typeName = 'Panel';
|
||||
|
||||
public constructor(private panel: VizPanel) {}
|
||||
|
||||
@ -96,10 +99,6 @@ export class VizPanelEditableElement implements EditableDashboardElement, BulkAc
|
||||
return categories;
|
||||
}
|
||||
|
||||
public getTypeName(): string {
|
||||
return 'Panel';
|
||||
}
|
||||
|
||||
public onDelete = () => {
|
||||
const layout = dashboardSceneGraph.getLayoutManagerFor(this.panel);
|
||||
layout.removePanel(this.panel);
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { EditableDashboardElement, MultiSelectedEditableDashboardElement } from '../scene/types';
|
||||
import { EditableDashboardElement } from '../scene/types/EditableDashboardElement';
|
||||
import { MultiSelectedEditableDashboardElement } from '../scene/types/MultiSelectedEditableDashboardElement';
|
||||
|
||||
import { ElementSelection } from './ElementSelection';
|
||||
|
||||
|
@ -21,7 +21,7 @@ import { saveLibPanel } from 'app/features/library-panels/state/api';
|
||||
|
||||
import { DashboardSceneChangeTracker } from '../saving/DashboardSceneChangeTracker';
|
||||
import { getPanelChanges } from '../saving/getDashboardChanges';
|
||||
import { DashboardLayoutItem, isDashboardLayoutItem } from '../scene/types';
|
||||
import { DashboardLayoutItem, isDashboardLayoutItem } from '../scene/types/DashboardLayoutItem';
|
||||
import { vizPanelToPanel } from '../serialization/transformSceneToSaveModel';
|
||||
import {
|
||||
activateSceneObjectAndParentTree,
|
||||
|
@ -10,7 +10,7 @@ import { getPanelLinksVariableSuggestions } from 'app/features/panel/panellinks/
|
||||
|
||||
import { VizPanelLinks } from '../scene/PanelLinks';
|
||||
import { PanelTimeRange } from '../scene/PanelTimeRange';
|
||||
import { isDashboardLayoutItem } from '../scene/types';
|
||||
import { isDashboardLayoutItem } from '../scene/types/DashboardLayoutItem';
|
||||
import { vizPanelToPanel, transformSceneToSaveModel } from '../serialization/transformSceneToSaveModel';
|
||||
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
|
||||
import { getDashboardSceneFor } from '../utils/utils';
|
||||
|
@ -71,7 +71,7 @@ import { isUsingAngularDatasourcePlugin, isUsingAngularPanelPlugin } from './ang
|
||||
import { setupKeyboardShortcuts } from './keyboardShortcuts';
|
||||
import { DashboardGridItem } from './layout-default/DashboardGridItem';
|
||||
import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutManager';
|
||||
import { DashboardLayoutManager } from './types';
|
||||
import { DashboardLayoutManager } from './types/DashboardLayoutManager';
|
||||
|
||||
export const PERSISTED_PROPS = ['title', 'description', 'tags', 'editable', 'graphTooltip', 'links', 'meta', 'preload'];
|
||||
export const PANEL_SEARCH_VAR = 'systemPanelFilterVar';
|
||||
@ -258,7 +258,7 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
||||
this.setState({ isEditing: true, showHiddenElements: true });
|
||||
|
||||
// Propagate change edit mode change to children
|
||||
this.state.body.editModeChanged(true);
|
||||
this.state.body.editModeChanged?.(true);
|
||||
|
||||
// Propagate edit mode to scopes
|
||||
this._scopesFacade?.enterReadOnly();
|
||||
@ -349,7 +349,7 @@ export class DashboardScene extends SceneObjectBase<DashboardSceneState> {
|
||||
}
|
||||
|
||||
// Disable grid dragging
|
||||
this.state.body.editModeChanged(false);
|
||||
this.state.body.editModeChanged?.(false);
|
||||
}
|
||||
|
||||
public canDiscard() {
|
||||
|
@ -8,7 +8,7 @@ import { getCloneKey } from '../utils/clone';
|
||||
import { DashboardScene } from './DashboardScene';
|
||||
import { DashboardGridItem } from './layout-default/DashboardGridItem';
|
||||
import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutManager';
|
||||
import { DashboardRepeatsProcessedEvent } from './types';
|
||||
import { DashboardRepeatsProcessedEvent } from './types/DashboardRepeatsProcessedEvent';
|
||||
|
||||
describe('DashboardSceneUrlSync', () => {
|
||||
describe('Given a standard scene', () => {
|
||||
|
@ -19,7 +19,7 @@ import { DashboardScene, DashboardSceneState } from './DashboardScene';
|
||||
import { LibraryPanelBehavior } from './LibraryPanelBehavior';
|
||||
import { ViewPanelScene } from './ViewPanelScene';
|
||||
import { DefaultGridLayoutManager } from './layout-default/DefaultGridLayoutManager';
|
||||
import { DashboardRepeatsProcessedEvent } from './types';
|
||||
import { DashboardRepeatsProcessedEvent } from './types/DashboardRepeatsProcessedEvent';
|
||||
|
||||
export class DashboardSceneUrlSync implements SceneObjectUrlSyncHandler {
|
||||
private _eventSub?: Unsubscribable;
|
||||
|
@ -25,7 +25,8 @@ import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components
|
||||
|
||||
import { getCloneKey } from '../../utils/clone';
|
||||
import { getMultiVariableValues, getQueryRunnerFor } from '../../utils/utils';
|
||||
import { DashboardLayoutItem, DashboardRepeatsProcessedEvent } from '../types';
|
||||
import { DashboardLayoutItem } from '../types/DashboardLayoutItem';
|
||||
import { DashboardRepeatsProcessedEvent } from '../types/DashboardRepeatsProcessedEvent';
|
||||
|
||||
import { getDashboardGridItemOptions } from './DashboardGridItemEditor';
|
||||
|
||||
@ -47,6 +48,8 @@ export class DashboardGridItem
|
||||
private _prevRepeatValues?: VariableValueSingle[];
|
||||
protected _variableDependency = new DashboardGridItemVariableDependencyHandler(this);
|
||||
|
||||
public readonly isDashboardLayoutItem = true;
|
||||
|
||||
public constructor(state: DashboardGridItemState) {
|
||||
super(state);
|
||||
|
||||
@ -188,11 +191,6 @@ export class DashboardGridItem
|
||||
this.setState(stateUpdate);
|
||||
}
|
||||
|
||||
/**
|
||||
* DashboardLayoutItem interface start
|
||||
*/
|
||||
public isDashboardLayoutItem: true = true;
|
||||
|
||||
/**
|
||||
* Returns options for panel edit
|
||||
*/
|
||||
|
@ -26,19 +26,19 @@ describe('DefaultGridLayoutManager', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getNextPanelId', () => {
|
||||
it('should get next panel id in a simple 3 panel layout', () => {
|
||||
describe('getMaxPanelId', () => {
|
||||
it('should get max panel id in a simple 3 panel layout', () => {
|
||||
const { manager } = setup();
|
||||
const id = manager.getNextPanelId();
|
||||
const id = manager.getMaxPanelId();
|
||||
|
||||
expect(id).toBe(4);
|
||||
expect(id).toBe(3);
|
||||
});
|
||||
|
||||
it('should return 1 if no panels are found', () => {
|
||||
it('should return 0 if no panels are found', () => {
|
||||
const { manager } = setup({ gridItems: [] });
|
||||
const id = manager.getNextPanelId();
|
||||
const id = manager.getMaxPanelId();
|
||||
|
||||
expect(id).toBe(1);
|
||||
expect(id).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -22,7 +22,7 @@ import {
|
||||
getGridItemKeyForPanelId,
|
||||
getDashboardSceneFor,
|
||||
} from '../../utils/utils';
|
||||
import { DashboardLayoutManager, LayoutRegistryItem } from '../types';
|
||||
import { DashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
|
||||
import { DashboardGridItem } from './DashboardGridItem';
|
||||
import { RowRepeaterBehavior } from './RowRepeaterBehavior';
|
||||
@ -39,7 +39,16 @@ export class DefaultGridLayoutManager
|
||||
extends SceneObjectBase<DefaultGridLayoutManagerState>
|
||||
implements DashboardLayoutManager
|
||||
{
|
||||
public isDashboardLayoutManager: true = true;
|
||||
public readonly isDashboardLayoutManager = true;
|
||||
|
||||
public static readonly descriptor = {
|
||||
name: 'Default grid',
|
||||
description: 'The default grid layout',
|
||||
id: 'default-grid',
|
||||
createFromLayout: DefaultGridLayoutManager.createFromLayout,
|
||||
};
|
||||
|
||||
public readonly descriptor = DefaultGridLayoutManager.descriptor;
|
||||
|
||||
public editModeChanged(isEditing: boolean): void {
|
||||
const updateResizeAndDragging = () => {
|
||||
@ -328,10 +337,6 @@ export class DefaultGridLayoutManager
|
||||
});
|
||||
}
|
||||
|
||||
public getDescriptor(): LayoutRegistryItem {
|
||||
return DefaultGridLayoutManager.getDescriptor();
|
||||
}
|
||||
|
||||
public cloneLayout(ancestorKey: string, isSource: boolean): DashboardLayoutManager {
|
||||
return this.clone({
|
||||
grid: this.state.grid.clone({
|
||||
@ -402,15 +407,6 @@ export class DefaultGridLayoutManager
|
||||
});
|
||||
}
|
||||
|
||||
public static getDescriptor(): LayoutRegistryItem {
|
||||
return {
|
||||
name: 'Default grid',
|
||||
description: 'The default grid layout',
|
||||
id: 'default-grid',
|
||||
createFromLayout: DefaultGridLayoutManager.createFromLayout,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle switching to the manual grid layout from other layouts
|
||||
* @param currentLayout
|
||||
|
@ -23,7 +23,7 @@ import {
|
||||
isClonedKey,
|
||||
} from '../../utils/clone';
|
||||
import { getMultiVariableValues } from '../../utils/utils';
|
||||
import { DashboardRepeatsProcessedEvent } from '../types';
|
||||
import { DashboardRepeatsProcessedEvent } from '../types/DashboardRepeatsProcessedEvent';
|
||||
|
||||
import { DashboardGridItem } from './DashboardGridItem';
|
||||
|
||||
|
@ -6,7 +6,7 @@ import { Switch, useStyles2 } from '@grafana/ui';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
|
||||
import { DashboardLayoutItem } from '../types';
|
||||
import { DashboardLayoutItem } from '../types/DashboardLayoutItem';
|
||||
|
||||
export interface ResponsiveGridItemState extends SceneObjectState {
|
||||
body: VizPanel;
|
||||
@ -14,6 +14,8 @@ export interface ResponsiveGridItemState extends SceneObjectState {
|
||||
}
|
||||
|
||||
export class ResponsiveGridItem extends SceneObjectBase<ResponsiveGridItemState> implements DashboardLayoutItem {
|
||||
public readonly isDashboardLayoutItem = true;
|
||||
|
||||
public constructor(state: ResponsiveGridItemState) {
|
||||
super(state);
|
||||
this.addActivationHandler(() => this._activationHandler());
|
||||
@ -29,11 +31,6 @@ export class ResponsiveGridItem extends SceneObjectBase<ResponsiveGridItemState>
|
||||
this.setState({ hideWhenNoData: !this.state.hideWhenNoData });
|
||||
}
|
||||
|
||||
/**
|
||||
* DashboardLayoutElement interface
|
||||
*/
|
||||
public isDashboardLayoutItem: true = true;
|
||||
|
||||
public getOptions?(): OptionsPaneCategoryDescriptor {
|
||||
const model = this;
|
||||
|
||||
|
@ -5,7 +5,7 @@ import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/Pan
|
||||
|
||||
import { getDashboardSceneFor, getPanelIdForVizPanel, getVizPanelKeyForPanelId } from '../../utils/utils';
|
||||
import { RowsLayoutManager } from '../layout-rows/RowsLayoutManager';
|
||||
import { DashboardLayoutManager, LayoutRegistryItem } from '../types';
|
||||
import { DashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
|
||||
import { ResponsiveGridItem } from './ResponsiveGridItem';
|
||||
|
||||
@ -17,7 +17,16 @@ export class ResponsiveGridLayoutManager
|
||||
extends SceneObjectBase<ResponsiveGridLayoutManagerState>
|
||||
implements DashboardLayoutManager
|
||||
{
|
||||
public isDashboardLayoutManager: true = true;
|
||||
public readonly isDashboardLayoutManager = true;
|
||||
|
||||
public static readonly descriptor = {
|
||||
name: 'Responsive grid',
|
||||
description: 'CSS layout that adjusts to the available space',
|
||||
id: 'responsive-grid',
|
||||
createFromLayout: ResponsiveGridLayoutManager.createFromLayout,
|
||||
};
|
||||
|
||||
public readonly descriptor = ResponsiveGridLayoutManager.descriptor;
|
||||
|
||||
public editModeChanged(isEditing: boolean): void {}
|
||||
|
||||
@ -83,19 +92,6 @@ export class ResponsiveGridLayoutManager
|
||||
return getOptions(this);
|
||||
}
|
||||
|
||||
public getDescriptor(): LayoutRegistryItem {
|
||||
return ResponsiveGridLayoutManager.getDescriptor();
|
||||
}
|
||||
|
||||
public static getDescriptor(): LayoutRegistryItem {
|
||||
return {
|
||||
name: 'Responsive grid',
|
||||
description: 'CSS layout that adjusts to the available space',
|
||||
id: 'responsive-grid',
|
||||
createFromLayout: ResponsiveGridLayoutManager.createFromLayout,
|
||||
};
|
||||
}
|
||||
|
||||
public static createEmpty() {
|
||||
return new ResponsiveGridLayoutManager({
|
||||
layout: new SceneCSSGridLayout({
|
||||
@ -123,10 +119,6 @@ export class ResponsiveGridLayoutManager
|
||||
});
|
||||
}
|
||||
|
||||
toSaveModel?() {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
||||
activateRepeaters?(): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
@ -6,12 +6,13 @@ import { t, Trans } from 'app/core/internationalization';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
|
||||
import { MultiSelectedEditableDashboardElement } from '../types';
|
||||
import { MultiSelectedEditableDashboardElement } from '../types/MultiSelectedEditableDashboardElement';
|
||||
|
||||
import { RowItem } from './RowItem';
|
||||
|
||||
export class MultiSelectedRowItemsElement implements MultiSelectedEditableDashboardElement {
|
||||
public isMultiSelectedEditableDashboardElement: true = true;
|
||||
public readonly isMultiSelectedEditableDashboardElement = true;
|
||||
public readonly typeName = 'Rows';
|
||||
|
||||
private items?: RowItem[];
|
||||
|
||||
@ -44,10 +45,6 @@ export class MultiSelectedRowItemsElement implements MultiSelectedEditableDashbo
|
||||
return [rowOptions];
|
||||
}
|
||||
|
||||
public getTypeName(): string {
|
||||
return 'Rows';
|
||||
}
|
||||
|
||||
public onDelete = () => {
|
||||
for (const item of this.items || []) {
|
||||
item.onDelete();
|
||||
|
@ -33,7 +33,10 @@ import { isClonedKey } from '../../utils/clone';
|
||||
import { getDashboardSceneFor, getDefaultVizPanel, getQueryRunnerFor } from '../../utils/utils';
|
||||
import { DashboardScene } from '../DashboardScene';
|
||||
import { useLayoutCategory } from '../layouts-shared/DashboardLayoutSelector';
|
||||
import { BulkActionElement, DashboardLayoutManager, EditableDashboardElement, LayoutParent } from '../types';
|
||||
import { BulkActionElement } from '../types/BulkActionElement';
|
||||
import { DashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
import { EditableDashboardElement } from '../types/EditableDashboardElement';
|
||||
import { LayoutParent } from '../types/LayoutParent';
|
||||
|
||||
import { MultiSelectedRowItemsElement } from './MultiSelectedRowItemsElement';
|
||||
import { RowItemRepeaterBehavior } from './RowItemRepeaterBehavior';
|
||||
@ -55,7 +58,8 @@ export class RowItem
|
||||
statePaths: ['title'],
|
||||
});
|
||||
|
||||
public isEditableDashboardElement: true = true;
|
||||
public readonly isEditableDashboardElement = true;
|
||||
public readonly typeName = 'Row';
|
||||
|
||||
public useEditPaneOptions(): OptionsPaneCategoryDescriptor[] {
|
||||
const row = this;
|
||||
@ -107,10 +111,6 @@ export class RowItem
|
||||
return [rowOptions, rowRepeatOptions, layoutOptions];
|
||||
}
|
||||
|
||||
public getTypeName(): string {
|
||||
return 'Row';
|
||||
}
|
||||
|
||||
public createMultiSelectedElement(items: SceneObject[]) {
|
||||
return new MultiSelectedRowItemsElement(items);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
|
||||
import { isClonedKeyOf, getCloneKey } from '../../utils/clone';
|
||||
import { getMultiVariableValues } from '../../utils/utils';
|
||||
import { DashboardRepeatsProcessedEvent } from '../types';
|
||||
import { DashboardRepeatsProcessedEvent } from '../types/DashboardRepeatsProcessedEvent';
|
||||
|
||||
import { RowItem } from './RowItem';
|
||||
import { RowsLayoutManager } from './RowsLayoutManager';
|
||||
|
@ -18,7 +18,7 @@ import { DashboardGridItem } from '../layout-default/DashboardGridItem';
|
||||
import { DefaultGridLayoutManager } from '../layout-default/DefaultGridLayoutManager';
|
||||
import { RowRepeaterBehavior } from '../layout-default/RowRepeaterBehavior';
|
||||
import { ResponsiveGridLayoutManager } from '../layout-responsive-grid/ResponsiveGridLayoutManager';
|
||||
import { DashboardLayoutManager, LayoutRegistryItem } from '../types';
|
||||
import { DashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
|
||||
import { RowItem } from './RowItem';
|
||||
import { RowItemRepeaterBehavior } from './RowItemRepeaterBehavior';
|
||||
@ -28,7 +28,16 @@ interface RowsLayoutManagerState extends SceneObjectState {
|
||||
}
|
||||
|
||||
export class RowsLayoutManager extends SceneObjectBase<RowsLayoutManagerState> implements DashboardLayoutManager {
|
||||
public isDashboardLayoutManager: true = true;
|
||||
public readonly isDashboardLayoutManager = true;
|
||||
|
||||
public static readonly descriptor = {
|
||||
name: 'Rows',
|
||||
description: 'Rows layout',
|
||||
id: 'rows-layout',
|
||||
createFromLayout: RowsLayoutManager.createFromLayout,
|
||||
};
|
||||
|
||||
public readonly descriptor = RowsLayoutManager.descriptor;
|
||||
|
||||
public editModeChanged(isEditing: boolean): void {}
|
||||
|
||||
@ -113,23 +122,10 @@ export class RowsLayoutManager extends SceneObjectBase<RowsLayoutManagerState> i
|
||||
});
|
||||
}
|
||||
|
||||
public getDescriptor(): LayoutRegistryItem {
|
||||
return RowsLayoutManager.getDescriptor();
|
||||
}
|
||||
|
||||
public getSelectedObject() {
|
||||
return sceneGraph.getAncestor(this, DashboardScene).state.editPane.state.selection?.getFirstObject();
|
||||
}
|
||||
|
||||
public static getDescriptor(): LayoutRegistryItem {
|
||||
return {
|
||||
name: 'Rows',
|
||||
description: 'Rows layout',
|
||||
id: 'rows-layout',
|
||||
createFromLayout: RowsLayoutManager.createFromLayout,
|
||||
};
|
||||
}
|
||||
|
||||
public static createEmpty() {
|
||||
return new RowsLayoutManager({ rows: [] });
|
||||
}
|
||||
|
@ -4,7 +4,9 @@ import { Select } from '@grafana/ui';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
|
||||
import { DashboardLayoutManager, isLayoutParent, LayoutRegistryItem } from '../types';
|
||||
import { DashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
import { isLayoutParent } from '../types/LayoutParent';
|
||||
import { LayoutRegistryItem } from '../types/LayoutRegistryItem';
|
||||
|
||||
import { layoutRegistry } from './layoutRegistry';
|
||||
import { findParentLayout } from './utils';
|
||||
@ -16,7 +18,7 @@ export interface Props {
|
||||
export function DashboardLayoutSelector({ layoutManager }: Props) {
|
||||
const options = useMemo(() => {
|
||||
const parentLayout = findParentLayout(layoutManager);
|
||||
const parentLayoutId = parentLayout?.getDescriptor().id;
|
||||
const parentLayoutId = parentLayout?.descriptor.id;
|
||||
|
||||
return layoutRegistry
|
||||
.list()
|
||||
@ -27,7 +29,7 @@ export function DashboardLayoutSelector({ layoutManager }: Props) {
|
||||
}));
|
||||
}, [layoutManager]);
|
||||
|
||||
const currentLayoutId = layoutManager.getDescriptor().id;
|
||||
const currentLayoutId = layoutManager.descriptor.id;
|
||||
const currentOption = options.find((option) => option.value.id === currentLayoutId);
|
||||
|
||||
return (
|
||||
|
@ -3,12 +3,8 @@ import { Registry } from '@grafana/data';
|
||||
import { DefaultGridLayoutManager } from '../layout-default/DefaultGridLayoutManager';
|
||||
import { ResponsiveGridLayoutManager } from '../layout-responsive-grid/ResponsiveGridLayoutManager';
|
||||
import { RowsLayoutManager } from '../layout-rows/RowsLayoutManager';
|
||||
import { LayoutRegistryItem } from '../types';
|
||||
import { LayoutRegistryItem } from '../types/LayoutRegistryItem';
|
||||
|
||||
export const layoutRegistry: Registry<LayoutRegistryItem> = new Registry<LayoutRegistryItem>(() => {
|
||||
return [
|
||||
DefaultGridLayoutManager.getDescriptor(),
|
||||
ResponsiveGridLayoutManager.getDescriptor(),
|
||||
RowsLayoutManager.getDescriptor(),
|
||||
];
|
||||
return [DefaultGridLayoutManager.descriptor, ResponsiveGridLayoutManager.descriptor, RowsLayoutManager.descriptor];
|
||||
});
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { SceneObject } from '@grafana/scenes';
|
||||
|
||||
import { DashboardLayoutManager, isDashboardLayoutManager } from '../types';
|
||||
import { DashboardLayoutManager, isDashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
|
||||
export function findParentLayout(sceneObject: SceneObject): DashboardLayoutManager | null {
|
||||
let parent = sceneObject.parent;
|
||||
|
@ -1,207 +0,0 @@
|
||||
import { BusEventWithPayload, RegistryItem } from '@grafana/data';
|
||||
import { SceneObject, VizPanel } from '@grafana/scenes';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
|
||||
/**
|
||||
* A scene object that usually wraps an underlying layout
|
||||
* Dealing with all the state management and editing of the layout
|
||||
*/
|
||||
export interface DashboardLayoutManager extends SceneObject {
|
||||
/** Marks it as a DashboardLayoutManager */
|
||||
isDashboardLayoutManager: true;
|
||||
|
||||
/**
|
||||
* Notify the layout manager that the edit mode has changed
|
||||
* @param isEditing
|
||||
*/
|
||||
editModeChanged(isEditing: boolean): void;
|
||||
|
||||
/**
|
||||
* Remove an element / panel
|
||||
* @param element
|
||||
*/
|
||||
removePanel(panel: VizPanel): void;
|
||||
|
||||
/**
|
||||
* Creates a copy of an existing element and adds it to the layout
|
||||
* @param element
|
||||
*/
|
||||
duplicatePanel(panel: VizPanel): void;
|
||||
|
||||
/**
|
||||
* Adds a new panel to the layout
|
||||
*/
|
||||
addPanel(panel: VizPanel): void;
|
||||
|
||||
/**
|
||||
* Add row
|
||||
*/
|
||||
addNewRow(): void;
|
||||
|
||||
/**
|
||||
* getVizPanels
|
||||
*/
|
||||
getVizPanels(): VizPanel[];
|
||||
|
||||
/**
|
||||
* Turn into a save model
|
||||
* @param saveModel
|
||||
*/
|
||||
toSaveModel?(): any;
|
||||
|
||||
/**
|
||||
* For dynamic panels that need to be viewed in isolation (SoloRoute)
|
||||
*/
|
||||
activateRepeaters?(): void;
|
||||
|
||||
/**
|
||||
* Gets the layout descriptor (which has the name and id)
|
||||
*/
|
||||
getDescriptor(): LayoutRegistryItem;
|
||||
|
||||
/**
|
||||
* Renders options and layout actions
|
||||
*/
|
||||
getOptions?(): OptionsPaneItemDescriptor[];
|
||||
|
||||
/**
|
||||
* Create a clone of the layout manager given an ancestor key
|
||||
* @param ancestorKey
|
||||
* @param isSource
|
||||
*/
|
||||
cloneLayout?(ancestorKey: string, isSource: boolean): DashboardLayoutManager;
|
||||
|
||||
/**
|
||||
* Returns the highest panel id in the layout
|
||||
*/
|
||||
getMaxPanelId(): number;
|
||||
}
|
||||
|
||||
export function isDashboardLayoutManager(obj: SceneObject): obj is DashboardLayoutManager {
|
||||
return 'isDashboardLayoutManager' in obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* The layout descriptor used when selecting / switching layouts
|
||||
*/
|
||||
export interface LayoutRegistryItem extends RegistryItem {
|
||||
/**
|
||||
* When switching between layouts
|
||||
* @param currentLayout
|
||||
*/
|
||||
createFromLayout(currentLayout: DashboardLayoutManager): DashboardLayoutManager;
|
||||
/**
|
||||
* Create from persisted state
|
||||
* @param saveModel
|
||||
*/
|
||||
createFromSaveModel?(saveModel: any): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* This interface is needed to support layouts existing on different levels of the scene (DashboardScene and inside the TabsLayoutManager)
|
||||
*/
|
||||
export interface LayoutParent extends SceneObject {
|
||||
switchLayout(newLayout: DashboardLayoutManager): void;
|
||||
}
|
||||
|
||||
export function isLayoutParent(obj: SceneObject): obj is LayoutParent {
|
||||
return 'switchLayout' in obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstraction to handle editing of different layout elements (wrappers for VizPanels and other objects)
|
||||
* Also useful to when rendering / viewing an element outside it's layout scope
|
||||
*/
|
||||
export interface DashboardLayoutItem extends SceneObject {
|
||||
/**
|
||||
* Marks this object as a layout item
|
||||
*/
|
||||
isDashboardLayoutItem: true;
|
||||
/**
|
||||
* Return layout item options (like repeat, repeat direction, etc for the default DashboardGridItem)
|
||||
*/
|
||||
getOptions?(): OptionsPaneCategoryDescriptor;
|
||||
/**
|
||||
* When going into panel edit
|
||||
**/
|
||||
editingStarted?(): void;
|
||||
/**
|
||||
* When coming out of panel edit
|
||||
*/
|
||||
editingCompleted?(withChanges: boolean): void;
|
||||
}
|
||||
|
||||
export function isDashboardLayoutItem(obj: SceneObject): obj is DashboardLayoutItem {
|
||||
return 'isDashboardLayoutItem' in obj;
|
||||
}
|
||||
|
||||
export interface DashboardRepeatsProcessedEventPayload {
|
||||
source: SceneObject;
|
||||
}
|
||||
|
||||
export class DashboardRepeatsProcessedEvent extends BusEventWithPayload<DashboardRepeatsProcessedEventPayload> {
|
||||
public static type = 'dashboard-repeats-processed';
|
||||
}
|
||||
|
||||
/**
|
||||
* Interface for elements that have options
|
||||
*/
|
||||
export interface EditableDashboardElement {
|
||||
/**
|
||||
* Marks this object as an element that can be selected and edited directly on the canvas
|
||||
*/
|
||||
isEditableDashboardElement: true;
|
||||
/**
|
||||
* Hook that returns edit pane options
|
||||
*/
|
||||
useEditPaneOptions(): OptionsPaneCategoryDescriptor[];
|
||||
/**
|
||||
* Get the type name of the element
|
||||
*/
|
||||
getTypeName(): string;
|
||||
/**
|
||||
* Panel Actions
|
||||
**/
|
||||
renderActions?(): React.ReactNode;
|
||||
/**
|
||||
* creates a new multi-selection element from a list of selected items
|
||||
*/
|
||||
createMultiSelectedElement?(items: SceneObject[]): MultiSelectedEditableDashboardElement;
|
||||
}
|
||||
|
||||
export function isEditableDashboardElement(obj: object): obj is EditableDashboardElement {
|
||||
return 'isEditableDashboardElement' in obj;
|
||||
}
|
||||
|
||||
export interface MultiSelectedEditableDashboardElement {
|
||||
/**
|
||||
* Marks this object as an element that can be selected and edited directly on the canvas
|
||||
*/
|
||||
isMultiSelectedEditableDashboardElement: true;
|
||||
/**
|
||||
* Get the type name of the element
|
||||
*/
|
||||
getTypeName(): string;
|
||||
/**
|
||||
* Hook that returns edit pane options
|
||||
*/
|
||||
useEditPaneOptions?(): OptionsPaneCategoryDescriptor[];
|
||||
/**
|
||||
* Panel Actions
|
||||
**/
|
||||
renderActions?(): React.ReactNode;
|
||||
}
|
||||
|
||||
export function isMultiSelectedEditableDashboardElement(obj: object): obj is MultiSelectedEditableDashboardElement {
|
||||
return 'isMultiSelectedEditableDashboardElement' in obj;
|
||||
}
|
||||
|
||||
export interface BulkActionElement {
|
||||
onDelete(): void;
|
||||
onCopy?(): void;
|
||||
}
|
||||
|
||||
export function isBulkActionElement(obj: object): obj is BulkActionElement {
|
||||
return 'onDelete' in obj;
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
export interface BulkActionElement {
|
||||
onDelete(): void;
|
||||
onCopy?(): void;
|
||||
}
|
||||
|
||||
export function isBulkActionElement(obj: object): obj is BulkActionElement {
|
||||
return 'onDelete' in obj;
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
import { SceneObject } from '@grafana/scenes';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
|
||||
/**
|
||||
* Abstraction to handle editing of different layout elements (wrappers for VizPanels and other objects)
|
||||
* Also useful to when rendering / viewing an element outside it's layout scope
|
||||
*/
|
||||
export interface DashboardLayoutItem extends SceneObject {
|
||||
/**
|
||||
* Marks this object as a layout item
|
||||
*/
|
||||
isDashboardLayoutItem: true;
|
||||
|
||||
/**
|
||||
* Return layout item options (like repeat, repeat direction, etc. for the default DashboardGridItem)
|
||||
*/
|
||||
getOptions?(): OptionsPaneCategoryDescriptor;
|
||||
|
||||
/**
|
||||
* When going into panel edit
|
||||
**/
|
||||
editingStarted?(): void;
|
||||
|
||||
/**
|
||||
* When coming out of panel edit
|
||||
*/
|
||||
editingCompleted?(withChanges: boolean): void;
|
||||
}
|
||||
|
||||
export function isDashboardLayoutItem(obj: SceneObject): obj is DashboardLayoutItem {
|
||||
return 'isDashboardLayoutItem' in obj;
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
import { SceneObject, VizPanel } from '@grafana/scenes';
|
||||
import { OptionsPaneItemDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneItemDescriptor';
|
||||
|
||||
import { LayoutRegistryItem } from './LayoutRegistryItem';
|
||||
|
||||
/**
|
||||
* A scene object that usually wraps an underlying layout
|
||||
* Dealing with all the state management and editing of the layout
|
||||
*/
|
||||
export interface DashboardLayoutManager<S = {}> extends SceneObject {
|
||||
/** Marks it as a DashboardLayoutManager */
|
||||
isDashboardLayoutManager: true;
|
||||
|
||||
/**
|
||||
* The layout descriptor (which has the name and id)
|
||||
*/
|
||||
descriptor: Readonly<LayoutRegistryItem>;
|
||||
|
||||
/**
|
||||
* Adds a new panel to the layout
|
||||
*/
|
||||
addPanel(panel: VizPanel): void;
|
||||
|
||||
/**
|
||||
* Remove an element / panel
|
||||
* @param panel
|
||||
*/
|
||||
removePanel(panel: VizPanel): void;
|
||||
|
||||
/**
|
||||
* Creates a copy of an existing element and adds it to the layout
|
||||
* @param panel
|
||||
*/
|
||||
duplicatePanel(panel: VizPanel): void;
|
||||
|
||||
/**
|
||||
* getVizPanels
|
||||
*/
|
||||
getVizPanels(): VizPanel[];
|
||||
|
||||
/**
|
||||
* Returns the highest panel id in the layout
|
||||
*/
|
||||
getMaxPanelId(): number;
|
||||
|
||||
/**
|
||||
* Add row
|
||||
*/
|
||||
addNewRow(): void;
|
||||
|
||||
/**
|
||||
* Notify the layout manager that the edit mode has changed
|
||||
* @param isEditing
|
||||
*/
|
||||
editModeChanged?(isEditing: boolean): void;
|
||||
|
||||
/**
|
||||
* Turn into a save model
|
||||
*/
|
||||
toSaveModel?(): S;
|
||||
|
||||
/**
|
||||
* For dynamic panels that need to be viewed in isolation (SoloRoute)
|
||||
*/
|
||||
activateRepeaters?(): void;
|
||||
|
||||
/**
|
||||
* Renders options and layout actions
|
||||
*/
|
||||
getOptions?(): OptionsPaneItemDescriptor[];
|
||||
|
||||
/**
|
||||
* Create a clone of the layout manager given an ancestor key
|
||||
* @param ancestorKey
|
||||
* @param isSource
|
||||
*/
|
||||
cloneLayout?(ancestorKey: string, isSource: boolean): DashboardLayoutManager;
|
||||
}
|
||||
|
||||
export function isDashboardLayoutManager(obj: SceneObject): obj is DashboardLayoutManager {
|
||||
return 'isDashboardLayoutManager' in obj;
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
import { BusEventWithPayload } from '@grafana/data';
|
||||
import { SceneObject } from '@grafana/scenes';
|
||||
|
||||
export interface DashboardRepeatsProcessedEventPayload {
|
||||
source: SceneObject;
|
||||
}
|
||||
|
||||
export class DashboardRepeatsProcessedEvent extends BusEventWithPayload<DashboardRepeatsProcessedEventPayload> {
|
||||
public static type = 'dashboard-repeats-processed';
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { SceneObject } from '@grafana/scenes';
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
|
||||
import { MultiSelectedEditableDashboardElement } from './MultiSelectedEditableDashboardElement';
|
||||
|
||||
/**
|
||||
* Interface for elements that have options
|
||||
*/
|
||||
export interface EditableDashboardElement {
|
||||
/**
|
||||
* Marks this object as an element that can be selected and edited directly on the canvas
|
||||
*/
|
||||
isEditableDashboardElement: true;
|
||||
|
||||
/**
|
||||
* Type name of the element
|
||||
*/
|
||||
typeName: Readonly<string>;
|
||||
|
||||
/**
|
||||
* Hook that returns edit pane options
|
||||
*/
|
||||
useEditPaneOptions(): OptionsPaneCategoryDescriptor[];
|
||||
|
||||
/**
|
||||
* Panel Actions
|
||||
**/
|
||||
renderActions?(): ReactNode;
|
||||
|
||||
/**
|
||||
* creates a new multi-selection element from a list of selected items
|
||||
*/
|
||||
createMultiSelectedElement?(items: SceneObject[]): MultiSelectedEditableDashboardElement;
|
||||
}
|
||||
|
||||
export function isEditableDashboardElement(obj: object): obj is EditableDashboardElement {
|
||||
return 'isEditableDashboardElement' in obj;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import { SceneObject } from '@grafana/scenes';
|
||||
|
||||
import { DashboardLayoutManager } from './DashboardLayoutManager';
|
||||
|
||||
/**
|
||||
* This interface is needed to support layouts existing on different levels of the scene (DashboardScene and inside the TabsLayoutManager)
|
||||
*/
|
||||
export interface LayoutParent extends SceneObject {
|
||||
switchLayout(newLayout: DashboardLayoutManager): void;
|
||||
}
|
||||
|
||||
export function isLayoutParent(obj: SceneObject): obj is LayoutParent {
|
||||
return 'switchLayout' in obj;
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import { RegistryItem } from '@grafana/data';
|
||||
|
||||
import { DashboardLayoutManager } from './DashboardLayoutManager';
|
||||
|
||||
/**
|
||||
* The layout descriptor used when selecting / switching layouts
|
||||
*/
|
||||
export interface LayoutRegistryItem<S = {}> extends RegistryItem {
|
||||
/**
|
||||
* When switching between layouts
|
||||
* @param currentLayout
|
||||
*/
|
||||
createFromLayout(currentLayout: DashboardLayoutManager): DashboardLayoutManager;
|
||||
|
||||
/**
|
||||
* Create from persisted state
|
||||
* @param saveModel
|
||||
*/
|
||||
createFromSaveModel?(saveModel: S): void;
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
import { ReactNode } from 'react';
|
||||
|
||||
import { OptionsPaneCategoryDescriptor } from 'app/features/dashboard/components/PanelEditor/OptionsPaneCategoryDescriptor';
|
||||
|
||||
export interface MultiSelectedEditableDashboardElement {
|
||||
/**
|
||||
* Marks this object as an element that can be selected and edited directly on the canvas
|
||||
*/
|
||||
isMultiSelectedEditableDashboardElement: true;
|
||||
|
||||
/**
|
||||
* Type name of the element
|
||||
*/
|
||||
typeName: Readonly<string>;
|
||||
|
||||
/**
|
||||
* Hook that returns edit pane options
|
||||
*/
|
||||
useEditPaneOptions?(): OptionsPaneCategoryDescriptor[];
|
||||
|
||||
/**
|
||||
* Panel Actions
|
||||
**/
|
||||
renderActions?(): ReactNode;
|
||||
}
|
||||
|
||||
export function isMultiSelectedEditableDashboardElement(obj: object): obj is MultiSelectedEditableDashboardElement {
|
||||
return 'isMultiSelectedEditableDashboardElement' in obj;
|
||||
}
|
@ -33,7 +33,7 @@ import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSou
|
||||
|
||||
import { DashboardDataLayerSet } from '../scene/DashboardDataLayerSet';
|
||||
import { DefaultGridLayoutManager } from '../scene/layout-default/DefaultGridLayoutManager';
|
||||
import { DashboardLayoutManager } from '../scene/types';
|
||||
import { DashboardLayoutManager } from '../scene/types/DashboardLayoutManager';
|
||||
import { dashboardSceneGraph } from '../utils/dashboardSceneGraph';
|
||||
import { getQueryRunnerFor } from '../utils/utils';
|
||||
import { validateVariable, validateVizPanel } from '../v2schema/test-helpers';
|
||||
|
@ -3,7 +3,7 @@ import { useState, useEffect } from 'react';
|
||||
import { VizPanel, UrlSyncManager } from '@grafana/scenes';
|
||||
|
||||
import { DashboardScene } from '../scene/DashboardScene';
|
||||
import { DashboardRepeatsProcessedEvent } from '../scene/types';
|
||||
import { DashboardRepeatsProcessedEvent } from '../scene/types/DashboardRepeatsProcessedEvent';
|
||||
import { containsCloneKey } from '../utils/clone';
|
||||
import { findVizPanelByKey } from '../utils/utils';
|
||||
|
||||
|
@ -19,7 +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 { DashboardLayoutManager, isDashboardLayoutManager } from '../scene/types';
|
||||
import { DashboardLayoutManager, isDashboardLayoutManager } from '../scene/types/DashboardLayoutManager';
|
||||
|
||||
import { getLastKeyFromClone, getOriginalKey } from './clone';
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user