From 268c20203be804de3a60dc103be07d2de53b50f6 Mon Sep 17 00:00:00 2001 From: Nathan Marrs Date: Fri, 29 Oct 2021 14:32:52 -0700 Subject: [PATCH] Canvas: Improve Selection System (#41065) --- .../app/features/canvas/elements/button.tsx | 62 +++++++++++++++++++ public/app/features/canvas/runtime/scene.tsx | 14 +++-- .../app/plugins/panel/canvas/CanvasPanel.tsx | 3 +- .../canvas/editor/LayerElementListEditor.tsx | 2 +- .../panel/canvas/editor/elementEditor.tsx | 2 - .../panel/canvas/editor/layerEditor.tsx | 2 - public/app/plugins/panel/canvas/module.tsx | 2 - 7 files changed, 72 insertions(+), 15 deletions(-) create mode 100644 public/app/features/canvas/elements/button.tsx diff --git a/public/app/features/canvas/elements/button.tsx b/public/app/features/canvas/elements/button.tsx new file mode 100644 index 00000000000..6e0a6559e49 --- /dev/null +++ b/public/app/features/canvas/elements/button.tsx @@ -0,0 +1,62 @@ +import React, { PureComponent } from 'react'; +import { Button } from '@grafana/ui'; + +import { DimensionContext } from 'app/features/dimensions/context'; +import { TextDimensionEditor } from 'app/features/dimensions/editors/TextDimensionEditor'; +import { TextDimensionConfig } from 'app/features/dimensions/types'; +import { CanvasElementItem, CanvasElementProps } from '../element'; + +interface ButtonData { + text?: string; +} + +interface ButtonConfig { + text?: TextDimensionConfig; +} + +class ButtonDisplay extends PureComponent> { + render() { + const { data } = this.props; + const onClick = () => console.log('button being clicked :)'); + + return ; + } +} + +export const buttonItem: CanvasElementItem = { + id: 'button', + name: 'Button', + description: 'Button', + + display: ButtonDisplay, + + defaultSize: { + width: 200, + height: 50, + }, + + getNewOptions: (options) => ({ + ...options, + }), + + // Called when data changes + prepareData: (ctx: DimensionContext, cfg: ButtonConfig) => { + const data: ButtonData = { + text: cfg?.text ? ctx.getText(cfg.text).value() : '', + }; + + return data; + }, + + // Heatmap overlay options + registerOptionsUI: (builder) => { + const category = ['Button']; + builder.addCustomEditor({ + category, + id: 'textSelector', + path: 'config.text', + name: 'Text', + editor: TextDimensionEditor, + }); + }, +}; diff --git a/public/app/features/canvas/runtime/scene.tsx b/public/app/features/canvas/runtime/scene.tsx index df7b33cb8b3..ffe9307660b 100644 --- a/public/app/features/canvas/runtime/scene.tsx +++ b/public/app/features/canvas/runtime/scene.tsx @@ -54,8 +54,10 @@ export class Scene { ); setTimeout(() => { - if (this.div && enableEditing) { - this.initMoveable(); + if (this.div) { + // If editing is enabled, clear selecto instance + const destroySelecto = enableEditing; + this.initMoveable(destroySelecto, enableEditing); } }, 100); return this.root; @@ -138,7 +140,7 @@ export class Scene { this.div = sceneContainer; }; - initMoveable = (destroySelecto = false) => { + initMoveable = (destroySelecto = false, allowChanges = true) => { const targetElements: HTMLDivElement[] = []; this.root.elements.forEach((element: ElementState) => { targetElements.push(element.div!); @@ -155,8 +157,9 @@ export class Scene { }); const moveable = new Moveable(this.div!, { - draggable: true, - resizable: true, + draggable: allowChanges, + resizable: allowChanges, + origin: false, }) .on('clickGroup', (event) => { this.selecto!.clickTarget(event.inputEvent, event.inputTarget); @@ -212,7 +215,6 @@ export class Scene { const s = event.selected.map((t) => this.findElementByTarget(t)!); this.selection.next(s); - console.log('UPDATE selection', s); if (event.isDragStart) { event.inputEvent.preventDefault(); diff --git a/public/app/plugins/panel/canvas/CanvasPanel.tsx b/public/app/plugins/panel/canvas/CanvasPanel.tsx index 05072c55a3c..7e42bd01b06 100644 --- a/public/app/plugins/panel/canvas/CanvasPanel.tsx +++ b/public/app/plugins/panel/canvas/CanvasPanel.tsx @@ -44,8 +44,7 @@ export class CanvasPanel extends Component { this.subs.add( this.props.eventBus.subscribe(PanelEditEnteredEvent, (evt) => { // Remove current selection when entering edit mode for any panel in dashboard - let event: MouseEvent = new MouseEvent('click'); - this.scene?.selecto?.clickTarget(event, this.scene?.div); + this.scene.clearCurrentSelection(); }) ); diff --git a/public/app/plugins/panel/canvas/editor/LayerElementListEditor.tsx b/public/app/plugins/panel/canvas/editor/LayerElementListEditor.tsx index 1e4402c2109..0c8e21e0bc6 100644 --- a/public/app/plugins/panel/canvas/editor/LayerElementListEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/LayerElementListEditor.tsx @@ -44,7 +44,7 @@ export class LayerElementListEditor extends PureComponent { try { settings.scene.selecto.clickTarget(item, item?.div); } catch (error) { - appEvents.emit(AppEvents.alertError, ['Unable to select element with inline editing disabled']); + appEvents.emit(AppEvents.alertError, ['Unable to select element, try selecting element in panel instead']); } } }; diff --git a/public/app/plugins/panel/canvas/editor/elementEditor.tsx b/public/app/plugins/panel/canvas/editor/elementEditor.tsx index b9795cb74e4..0d8469ad9ba 100644 --- a/public/app/plugins/panel/canvas/editor/elementEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/elementEditor.tsx @@ -46,8 +46,6 @@ export function getElementEditor(opts: CanvasEditorOptions): NestedPanelOptions< // Dynamically fill the selected element build: (builder, context) => { - console.log('MAKE element editor', opts.element.UID); - const { options } = opts.element; const layerTypes = canvasElementRegistry.selectOptions( options?.type // the selected value diff --git a/public/app/plugins/panel/canvas/editor/layerEditor.tsx b/public/app/plugins/panel/canvas/editor/layerEditor.tsx index 2a2255e4703..68a1329f2da 100644 --- a/public/app/plugins/panel/canvas/editor/layerEditor.tsx +++ b/public/app/plugins/panel/canvas/editor/layerEditor.tsx @@ -30,8 +30,6 @@ export function getLayerEditor(opts: InstanceState): NestedPanelOptions { - console.log('MAKE layer editor', layer.UID); - builder.addCustomEditor({ id: 'content', path: 'root', diff --git a/public/app/plugins/panel/canvas/module.tsx b/public/app/plugins/panel/canvas/module.tsx index 0525400ee02..28945967402 100644 --- a/public/app/plugins/panel/canvas/module.tsx +++ b/public/app/plugins/panel/canvas/module.tsx @@ -28,8 +28,6 @@ export const plugin = new PanelPlugin(CanvasPanel) scene: state.scene, }) ); - } else { - console.log('NO Single seleciton', selection?.length); } builder.addNestedOptions(getLayerEditor(state));