mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Canvas: Refactor group to frame (#48671)
This commit is contained in:
parent
0d60b1ce0a
commit
ff38f24044
@ -16,7 +16,7 @@ type LayerDragDropListProps<T extends LayerElement> = {
|
||||
onSelect: (element: T) => any;
|
||||
onDelete: (element: T) => any;
|
||||
onDuplicate?: (element: T) => any;
|
||||
isGroup?: (element: T) => boolean;
|
||||
isFrame?: (element: T) => boolean;
|
||||
selection?: string[]; // list of unique ids (names)
|
||||
excludeBaseLayer?: boolean;
|
||||
onNameChange: (element: T, newName: string) => any;
|
||||
@ -30,7 +30,7 @@ export const LayerDragDropList = <T extends LayerElement>({
|
||||
onSelect,
|
||||
onDelete,
|
||||
onDuplicate,
|
||||
isGroup,
|
||||
isFrame,
|
||||
selection,
|
||||
excludeBaseLayer,
|
||||
onNameChange,
|
||||
@ -74,7 +74,7 @@ export const LayerDragDropList = <T extends LayerElement>({
|
||||
/>
|
||||
<div className={style.textWrapper}> {getLayerInfo(element)}</div>
|
||||
|
||||
{!isGroup!(element) && (
|
||||
{!isFrame!(element) && (
|
||||
<>
|
||||
{onDuplicate ? (
|
||||
<IconButton
|
||||
|
6
public/app/features/canvas/frame.ts
Normal file
6
public/app/features/canvas/frame.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { CanvasElementOptions } from './element';
|
||||
|
||||
export interface CanvasFrameOptions extends CanvasElementOptions {
|
||||
type: 'frame';
|
||||
elements: CanvasElementOptions[];
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import { CanvasElementOptions } from './element';
|
||||
|
||||
export interface CanvasGroupOptions extends CanvasElementOptions {
|
||||
type: 'group';
|
||||
elements: CanvasElementOptions[];
|
||||
// layout? // absolute, list, grid?
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export * from './types';
|
||||
export * from './element';
|
||||
export { CanvasGroupOptions } from './group';
|
||||
export { CanvasFrameOptions } from './frame';
|
||||
export * from './registry';
|
||||
|
@ -13,7 +13,7 @@ import { DimensionContext } from 'app/features/dimensions';
|
||||
|
||||
import { HorizontalConstraint, Placement, VerticalConstraint } from '../types';
|
||||
|
||||
import { GroupState } from './group';
|
||||
import { FrameState } from './frame';
|
||||
import { RootElement } from './root';
|
||||
import { Scene } from './scene';
|
||||
|
||||
@ -32,7 +32,7 @@ export class ElementState implements LayerElement {
|
||||
// Calculated
|
||||
data?: any; // depends on the type
|
||||
|
||||
constructor(public item: CanvasElementItem, public options: CanvasElementOptions, public parent?: GroupState) {
|
||||
constructor(public item: CanvasElementItem, public options: CanvasElementOptions, public parent?: FrameState) {
|
||||
const fallbackName = `Element ${Date.now()}`;
|
||||
if (!options) {
|
||||
this.options = { type: item.id, name: fallbackName };
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { cloneDeep } from 'lodash';
|
||||
import React from 'react';
|
||||
|
||||
import { CanvasGroupOptions, canvasElementRegistry } from 'app/features/canvas';
|
||||
import { CanvasFrameOptions, canvasElementRegistry } from 'app/features/canvas';
|
||||
import { notFoundItem } from 'app/features/canvas/elements/notFound';
|
||||
import { DimensionContext } from 'app/features/dimensions';
|
||||
import { LayerActionID } from 'app/plugins/panel/canvas/types';
|
||||
@ -13,10 +13,10 @@ import { ElementState } from './element';
|
||||
import { RootElement } from './root';
|
||||
import { Scene } from './scene';
|
||||
|
||||
export const groupItemDummy: CanvasElementItem = {
|
||||
id: 'group',
|
||||
name: 'Group',
|
||||
description: 'Group',
|
||||
export const frameItemDummy: CanvasElementItem = {
|
||||
id: 'frame',
|
||||
name: 'Frame',
|
||||
description: 'Frame',
|
||||
|
||||
getNewOptions: () => ({
|
||||
config: {},
|
||||
@ -24,16 +24,16 @@ export const groupItemDummy: CanvasElementItem = {
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
display: () => {
|
||||
return <div>GROUP!</div>;
|
||||
return <div>FRAME!</div>;
|
||||
},
|
||||
};
|
||||
|
||||
export class GroupState extends ElementState {
|
||||
export class FrameState extends ElementState {
|
||||
elements: ElementState[] = [];
|
||||
scene: Scene;
|
||||
|
||||
constructor(public options: CanvasGroupOptions, scene: Scene, public parent?: GroupState) {
|
||||
super(groupItemDummy, options, parent);
|
||||
constructor(public options: CanvasFrameOptions, scene: Scene, public parent?: FrameState) {
|
||||
super(frameItemDummy, options, parent);
|
||||
|
||||
this.scene = scene;
|
||||
|
||||
@ -44,8 +44,8 @@ export class GroupState extends ElementState {
|
||||
}
|
||||
|
||||
for (const c of elements) {
|
||||
if (c.type === 'group') {
|
||||
this.elements.push(new GroupState(c as CanvasGroupOptions, scene, this));
|
||||
if (c.type === 'frame') {
|
||||
this.elements.push(new FrameState(c as CanvasFrameOptions, scene, this));
|
||||
} else {
|
||||
const item = canvasElementRegistry.getIfExists(c.type) ?? notFoundItem;
|
||||
this.elements.push(new ElementState(item, c, this));
|
||||
@ -91,8 +91,8 @@ export class GroupState extends ElementState {
|
||||
this.reinitializeMoveable();
|
||||
break;
|
||||
case LayerActionID.Duplicate:
|
||||
if (element.item.id === 'group') {
|
||||
console.log('Can not duplicate groups (yet)', action, element);
|
||||
if (element.item.id === 'frame') {
|
||||
console.log('Can not duplicate frames (yet)', action, element);
|
||||
return;
|
||||
}
|
||||
const opts = cloneDeep(element.options);
|
@ -1,12 +1,12 @@
|
||||
import React from 'react';
|
||||
|
||||
import { CanvasGroupOptions, CanvasElementOptions } from 'app/features/canvas';
|
||||
import { CanvasFrameOptions, CanvasElementOptions } from 'app/features/canvas';
|
||||
|
||||
import { GroupState } from './group';
|
||||
import { FrameState } from './frame';
|
||||
import { Scene } from './scene';
|
||||
|
||||
export class RootElement extends GroupState {
|
||||
constructor(public options: CanvasGroupOptions, public scene: Scene, private changeCallback: () => void) {
|
||||
export class RootElement extends FrameState {
|
||||
constructor(public options: CanvasFrameOptions, public scene: Scene, private changeCallback: () => void) {
|
||||
super(options, scene);
|
||||
|
||||
this.sizeStyle = {
|
||||
@ -22,11 +22,11 @@ export class RootElement extends GroupState {
|
||||
// root type can not change
|
||||
onChange(options: CanvasElementOptions) {
|
||||
this.revId++;
|
||||
this.options = { ...options } as CanvasGroupOptions;
|
||||
this.options = { ...options } as CanvasFrameOptions;
|
||||
this.changeCallback();
|
||||
}
|
||||
|
||||
getSaveModel(): CanvasGroupOptions {
|
||||
getSaveModel(): CanvasFrameOptions {
|
||||
const { placement, constraint, ...rest } = this.options;
|
||||
|
||||
return {
|
||||
|
@ -8,7 +8,7 @@ import Selecto from 'selecto';
|
||||
import { GrafanaTheme2, PanelData } from '@grafana/data';
|
||||
import { stylesFactory } from '@grafana/ui';
|
||||
import { config } from 'app/core/config';
|
||||
import { CanvasGroupOptions, DEFAULT_CANVAS_ELEMENT_CONFIG } from 'app/features/canvas';
|
||||
import { CanvasFrameOptions, DEFAULT_CANVAS_ELEMENT_CONFIG } from 'app/features/canvas';
|
||||
import {
|
||||
ColorDimensionConfig,
|
||||
ResourceDimensionConfig,
|
||||
@ -29,12 +29,12 @@ import { LayerActionID } from 'app/plugins/panel/canvas/types';
|
||||
import { Placement } from '../types';
|
||||
|
||||
import { ElementState } from './element';
|
||||
import { GroupState } from './group';
|
||||
import { FrameState } from './frame';
|
||||
import { RootElement } from './root';
|
||||
|
||||
export interface SelectionParams {
|
||||
targets: Array<HTMLElement | SVGElement>;
|
||||
group?: GroupState;
|
||||
frame?: FrameState;
|
||||
}
|
||||
|
||||
export class Scene {
|
||||
@ -53,15 +53,15 @@ export class Scene {
|
||||
selecto?: Selecto;
|
||||
moveable?: Moveable;
|
||||
div?: HTMLDivElement;
|
||||
currentLayer?: GroupState;
|
||||
currentLayer?: FrameState;
|
||||
isEditingEnabled?: boolean;
|
||||
|
||||
constructor(cfg: CanvasGroupOptions, enableEditing: boolean, public onSave: (cfg: CanvasGroupOptions) => void) {
|
||||
constructor(cfg: CanvasFrameOptions, enableEditing: boolean, public onSave: (cfg: CanvasFrameOptions) => void) {
|
||||
this.root = this.load(cfg, enableEditing);
|
||||
}
|
||||
|
||||
getNextElementName = (isGroup = false) => {
|
||||
const label = isGroup ? 'Group' : 'Element';
|
||||
getNextElementName = (isFrame = false) => {
|
||||
const label = isFrame ? 'Frame' : 'Element';
|
||||
let idx = this.byName.size + 1;
|
||||
|
||||
const max = idx + 100;
|
||||
@ -79,10 +79,10 @@ export class Scene {
|
||||
return !this.byName.has(v);
|
||||
};
|
||||
|
||||
load(cfg: CanvasGroupOptions, enableEditing: boolean) {
|
||||
load(cfg: CanvasFrameOptions, enableEditing: boolean) {
|
||||
this.root = new RootElement(
|
||||
cfg ?? {
|
||||
type: 'group',
|
||||
type: 'frame',
|
||||
elements: [DEFAULT_CANVAS_ELEMENT_CONFIG],
|
||||
},
|
||||
this,
|
||||
@ -126,13 +126,13 @@ export class Scene {
|
||||
}
|
||||
}
|
||||
|
||||
groupSelection() {
|
||||
frameSelection() {
|
||||
this.selection.pipe(first()).subscribe((currentSelectedElements) => {
|
||||
const currentLayer = currentSelectedElements[0].parent!;
|
||||
|
||||
const newLayer = new GroupState(
|
||||
const newLayer = new FrameState(
|
||||
{
|
||||
type: 'group',
|
||||
type: 'frame',
|
||||
name: this.getNextElementName(true),
|
||||
elements: [],
|
||||
},
|
||||
@ -140,18 +140,18 @@ export class Scene {
|
||||
currentSelectedElements[0].parent
|
||||
);
|
||||
|
||||
const groupPlacement = this.generateGroupContainer(currentSelectedElements);
|
||||
const framePlacement = this.generateFrameContainer(currentSelectedElements);
|
||||
|
||||
newLayer.options.placement = groupPlacement;
|
||||
newLayer.options.placement = framePlacement;
|
||||
|
||||
currentSelectedElements.forEach((element: ElementState) => {
|
||||
const elementContainer = element.div?.getBoundingClientRect();
|
||||
element.setPlacementFromConstraint(elementContainer, groupPlacement as DOMRect);
|
||||
element.setPlacementFromConstraint(elementContainer, framePlacement as DOMRect);
|
||||
currentLayer.doAction(LayerActionID.Delete, element);
|
||||
newLayer.doAction(LayerActionID.Duplicate, element, false, false);
|
||||
});
|
||||
|
||||
newLayer.setPlacementFromConstraint(groupPlacement as DOMRect, currentLayer.div?.getBoundingClientRect());
|
||||
newLayer.setPlacementFromConstraint(framePlacement as DOMRect, currentLayer.div?.getBoundingClientRect());
|
||||
|
||||
currentLayer.elements.push(newLayer);
|
||||
|
||||
@ -161,7 +161,7 @@ export class Scene {
|
||||
});
|
||||
}
|
||||
|
||||
private generateGroupContainer = (elements: ElementState[]): Placement => {
|
||||
private generateFrameContainer = (elements: ElementState[]): Placement => {
|
||||
let minTop = Infinity;
|
||||
let minLeft = Infinity;
|
||||
let maxRight = 0;
|
||||
@ -204,7 +204,7 @@ export class Scene {
|
||||
this.selecto?.clickTarget(event, this.div);
|
||||
}
|
||||
|
||||
updateCurrentLayer(newLayer: GroupState) {
|
||||
updateCurrentLayer(newLayer: FrameState) {
|
||||
this.currentLayer = newLayer;
|
||||
this.clearCurrentSelection();
|
||||
this.save();
|
||||
@ -233,7 +233,7 @@ export class Scene {
|
||||
return currentElement;
|
||||
}
|
||||
|
||||
const nestedElements = currentElement instanceof GroupState ? currentElement.elements : [];
|
||||
const nestedElements = currentElement instanceof FrameState ? currentElement.elements : [];
|
||||
for (const nestedElement of nestedElements) {
|
||||
stack.unshift(nestedElement);
|
||||
}
|
||||
@ -256,8 +256,8 @@ export class Scene {
|
||||
private updateSelection = (selection: SelectionParams) => {
|
||||
this.moveable!.target = selection.targets;
|
||||
|
||||
if (selection.group) {
|
||||
this.selection.next([selection.group]);
|
||||
if (selection.frame) {
|
||||
this.selection.next([selection.frame]);
|
||||
} else {
|
||||
const s = selection.targets.map((t) => this.findElementByTarget(t)!);
|
||||
this.selection.next(s);
|
||||
@ -275,7 +275,7 @@ export class Scene {
|
||||
targetElements.push(currentElement.div);
|
||||
}
|
||||
|
||||
const nestedElements = currentElement instanceof GroupState ? currentElement.elements : [];
|
||||
const nestedElements = currentElement instanceof FrameState ? currentElement.elements : [];
|
||||
for (const nestedElement of nestedElements) {
|
||||
stack.unshift(nestedElement);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { Subscription } from 'rxjs';
|
||||
|
||||
import { PanelProps } from '@grafana/data';
|
||||
import { PanelContext, PanelContextRoot } from '@grafana/ui';
|
||||
import { CanvasGroupOptions } from 'app/features/canvas';
|
||||
import { CanvasFrameOptions } from 'app/features/canvas';
|
||||
import { ElementState } from 'app/features/canvas/runtime/element';
|
||||
import { Scene } from 'app/features/canvas/runtime/scene';
|
||||
import { PanelEditEnteredEvent, PanelEditExitedEvent } from 'app/types/events';
|
||||
@ -85,7 +85,7 @@ export class CanvasPanel extends Component<Props, State> {
|
||||
|
||||
// NOTE, all changes to the scene flow through this function
|
||||
// even the editor gets current state from the same scene instance!
|
||||
onUpdateScene = (root: CanvasGroupOptions) => {
|
||||
onUpdateScene = (root: CanvasFrameOptions) => {
|
||||
const { onOptionsChange, options } = this.props;
|
||||
onOptionsChange({
|
||||
...options,
|
||||
|
@ -9,7 +9,7 @@ import { LayerDragDropList } from 'app/core/components/Layers/LayerDragDropList'
|
||||
import { CanvasElementOptions, canvasElementRegistry } from 'app/features/canvas';
|
||||
import { notFoundItem } from 'app/features/canvas/elements/notFound';
|
||||
import { ElementState } from 'app/features/canvas/runtime/element';
|
||||
import { GroupState } from 'app/features/canvas/runtime/group';
|
||||
import { FrameState } from 'app/features/canvas/runtime/frame';
|
||||
import { SelectionParams } from 'app/features/canvas/runtime/scene';
|
||||
import { ShowConfirmModalEvent } from 'app/types/events';
|
||||
|
||||
@ -53,11 +53,11 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
if (settings?.scene) {
|
||||
try {
|
||||
let selection: SelectionParams = { targets: [] };
|
||||
if (item instanceof GroupState) {
|
||||
if (item instanceof FrameState) {
|
||||
const targetElements: HTMLDivElement[] = [];
|
||||
targetElements.push(item?.div!);
|
||||
selection.targets = targetElements;
|
||||
selection.group = item;
|
||||
selection.frame = item;
|
||||
settings.scene.select(selection);
|
||||
} else if (item instanceof ElementState) {
|
||||
const targetElement = [item?.div!];
|
||||
@ -115,7 +115,7 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
}
|
||||
};
|
||||
|
||||
private decoupleGroup = () => {
|
||||
private decoupleFrame = () => {
|
||||
const settings = this.props.item.settings;
|
||||
|
||||
if (!settings?.layer) {
|
||||
@ -124,7 +124,7 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
|
||||
const { layer } = settings;
|
||||
|
||||
this.deleteGroup();
|
||||
this.deleteFrame();
|
||||
layer.elements.forEach((element: ElementState) => {
|
||||
const elementContainer = element.div?.getBoundingClientRect();
|
||||
element.setPlacementFromConstraint(elementContainer, layer.parent?.div?.getBoundingClientRect());
|
||||
@ -132,22 +132,22 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
});
|
||||
};
|
||||
|
||||
private onDecoupleGroup = () => {
|
||||
private onDecoupleFrame = () => {
|
||||
appEvents.publish(
|
||||
new ShowConfirmModalEvent({
|
||||
title: 'Decouple group',
|
||||
text: `Are you sure you want to decouple this group?`,
|
||||
text2: 'This will remove the group and push nested elements in the next level up.',
|
||||
title: 'Decouple frame',
|
||||
text: `Are you sure you want to decouple this frame?`,
|
||||
text2: 'This will remove the frame and push nested elements in the next level up.',
|
||||
confirmText: 'Yes',
|
||||
yesText: 'Decouple',
|
||||
onConfirm: async () => {
|
||||
this.decoupleGroup();
|
||||
this.decoupleFrame();
|
||||
},
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
private deleteGroup = () => {
|
||||
private deleteFrame = () => {
|
||||
const settings = this.props.item.settings;
|
||||
|
||||
if (!settings?.layer) {
|
||||
@ -164,26 +164,26 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
this.goUpLayer();
|
||||
};
|
||||
|
||||
private onGroupSelection = () => {
|
||||
private onFrameSelection = () => {
|
||||
const scene = this.getScene();
|
||||
if (scene) {
|
||||
scene.groupSelection();
|
||||
scene.frameSelection();
|
||||
} else {
|
||||
console.warn('no scene!');
|
||||
}
|
||||
};
|
||||
|
||||
private onDeleteGroup = () => {
|
||||
private onDeleteFrame = () => {
|
||||
appEvents.publish(
|
||||
new ShowConfirmModalEvent({
|
||||
title: 'Delete group',
|
||||
text: `Are you sure you want to delete this group?`,
|
||||
text2: 'This will delete the group and all nested elements.',
|
||||
title: 'Delete frame',
|
||||
text: `Are you sure you want to delete this frame?`,
|
||||
text2: 'This will delete the frame and all nested elements.',
|
||||
icon: 'trash-alt',
|
||||
confirmText: 'Delete',
|
||||
yesText: 'Delete',
|
||||
onConfirm: async () => {
|
||||
this.deleteGroup();
|
||||
this.deleteFrame();
|
||||
},
|
||||
})
|
||||
);
|
||||
@ -215,8 +215,8 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
element.onChange({ ...element.options, name });
|
||||
};
|
||||
|
||||
const isGroup = (element: ElementState) => {
|
||||
return element instanceof GroupState;
|
||||
const isFrame = (element: ElementState) => {
|
||||
return element instanceof FrameState;
|
||||
};
|
||||
|
||||
const verifyLayerNameUniqueness = (nameToVerify: string) => {
|
||||
@ -231,16 +231,16 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
{!layer.isRoot() && (
|
||||
<>
|
||||
<Button icon="angle-up" size="sm" variant="secondary" onClick={this.goUpLayer}>
|
||||
Go Up Level
|
||||
Go up level
|
||||
</Button>
|
||||
<Button size="sm" variant="secondary" onClick={() => this.onSelect(layer)}>
|
||||
Select Group
|
||||
Select frame
|
||||
</Button>
|
||||
<Button size="sm" variant="secondary" onClick={() => this.onDecoupleGroup()}>
|
||||
Decouple Group
|
||||
<Button size="sm" variant="secondary" onClick={() => this.onDecoupleFrame()}>
|
||||
Decouple frame
|
||||
</Button>
|
||||
<Button size="sm" variant="secondary" onClick={() => this.onDeleteGroup()}>
|
||||
Delete Group
|
||||
<Button size="sm" variant="secondary" onClick={() => this.onDeleteFrame()}>
|
||||
Delete frame
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
@ -252,7 +252,7 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
getLayerInfo={getLayerInfo}
|
||||
onNameChange={onNameChange}
|
||||
verifyLayerNameUniqueness={verifyLayerNameUniqueness}
|
||||
isGroup={isGroup}
|
||||
isFrame={isFrame}
|
||||
layers={layer.elements}
|
||||
selection={selection}
|
||||
/>
|
||||
@ -266,12 +266,12 @@ export class LayerElementListEditor extends PureComponent<Props> {
|
||||
/>
|
||||
{selection.length > 0 && (
|
||||
<Button size="sm" variant="secondary" onClick={this.onClearSelection}>
|
||||
Clear Selection
|
||||
Clear selection
|
||||
</Button>
|
||||
)}
|
||||
{selection.length > 1 && (
|
||||
<Button size="sm" variant="secondary" onClick={this.onGroupSelection}>
|
||||
Group items
|
||||
<Button size="sm" variant="secondary" onClick={this.onFrameSelection}>
|
||||
Frame selection
|
||||
</Button>
|
||||
)}
|
||||
</HorizontalGroup>
|
||||
|
@ -2,7 +2,7 @@ import { get as lodashGet } from 'lodash';
|
||||
|
||||
import { NestedPanelOptions, NestedValueAccess } from '@grafana/data/src/utils/OptionsUIBuilders';
|
||||
import { ElementState } from 'app/features/canvas/runtime/element';
|
||||
import { GroupState } from 'app/features/canvas/runtime/group';
|
||||
import { FrameState } from 'app/features/canvas/runtime/frame';
|
||||
import { Scene } from 'app/features/canvas/runtime/scene';
|
||||
import { setOptionImmutably } from 'app/features/dashboard/components/PanelEditor/utils';
|
||||
|
||||
@ -14,7 +14,7 @@ import { optionBuilder } from './options';
|
||||
|
||||
export interface LayerEditorProps {
|
||||
scene: Scene;
|
||||
layer: GroupState;
|
||||
layer: FrameState;
|
||||
selected: ElementState[];
|
||||
}
|
||||
|
||||
@ -22,12 +22,12 @@ export function getLayerEditor(opts: InstanceState): NestedPanelOptions<LayerEdi
|
||||
const { selected, scene } = opts;
|
||||
|
||||
if (!scene.currentLayer) {
|
||||
scene.currentLayer = scene.root as GroupState;
|
||||
scene.currentLayer = scene.root as FrameState;
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
for (const element of selected) {
|
||||
if (element instanceof GroupState) {
|
||||
if (element instanceof FrameState) {
|
||||
scene.currentLayer = element;
|
||||
break;
|
||||
}
|
||||
|
@ -3,13 +3,13 @@
|
||||
// It is currenty hand written but will serve as the target for cuetsy
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
import { CanvasGroupOptions, DEFAULT_CANVAS_ELEMENT_CONFIG } from 'app/features/canvas';
|
||||
import { CanvasFrameOptions, DEFAULT_CANVAS_ELEMENT_CONFIG } from 'app/features/canvas';
|
||||
|
||||
export const modelVersion = Object.freeze([1, 0]);
|
||||
|
||||
export interface PanelOptions {
|
||||
inlineEditing: boolean;
|
||||
root: CanvasGroupOptions;
|
||||
root: CanvasFrameOptions;
|
||||
}
|
||||
|
||||
export const defaultPanelOptions: PanelOptions = {
|
||||
@ -20,5 +20,5 @@ export const defaultPanelOptions: PanelOptions = {
|
||||
...DEFAULT_CANVAS_ELEMENT_CONFIG,
|
||||
},
|
||||
],
|
||||
} as unknown as CanvasGroupOptions,
|
||||
} as unknown as CanvasFrameOptions,
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { PanelPlugin } from '@grafana/data';
|
||||
import { GroupState } from 'app/features/canvas/runtime/group';
|
||||
import { FrameState } from 'app/features/canvas/runtime/frame';
|
||||
|
||||
import { CanvasPanel, InstanceState } from './CanvasPanel';
|
||||
import { getElementEditor } from './editor/elementEditor';
|
||||
@ -25,7 +25,7 @@ export const plugin = new PanelPlugin<PanelOptions>(CanvasPanel)
|
||||
const selection = state.selected;
|
||||
if (selection?.length === 1) {
|
||||
const element = selection[0];
|
||||
if (!(element instanceof GroupState)) {
|
||||
if (!(element instanceof FrameState)) {
|
||||
builder.addNestedOptions(
|
||||
getElementEditor({
|
||||
category: [`Selected element (${element.options.name})`],
|
||||
|
Loading…
Reference in New Issue
Block a user