diff --git a/public/app/features/canvas/runtime/element.tsx b/public/app/features/canvas/runtime/element.tsx index 37000ed02bd..dd41cf89d99 100644 --- a/public/app/features/canvas/runtime/element.tsx +++ b/public/app/features/canvas/runtime/element.tsx @@ -14,6 +14,7 @@ import { DimensionContext } from 'app/features/dimensions'; import { HorizontalConstraint, Placement, VerticalConstraint } from '../types'; import { GroupState } from './group'; +import { RootElement } from './root'; import { Scene } from './scene'; let counter = 0; @@ -68,6 +69,11 @@ export class ElementState implements LayerElement { /** Use the configured options to update CSS style properties directly on the wrapper div **/ applyLayoutStylesToDiv() { + if (this.isRoot()) { + // Root supersedes layout engine and is always 100% width + height of panel + return; + } + const { constraint } = this.options; const { vertical, horizontal } = constraint ?? {}; const placement = this.options.placement ?? ({} as Placement); @@ -170,12 +176,16 @@ export class ElementState implements LayerElement { } } - setPlacementFromConstraint() { + setPlacementFromConstraint(elementContainer?: DOMRect, parentContainer?: DOMRect) { const { constraint } = this.options; const { vertical, horizontal } = constraint ?? {}; - const elementContainer = this.div && this.div.getBoundingClientRect(); - const parentContainer = this.div && this.div.parentElement?.getBoundingClientRect(); + if (!elementContainer) { + elementContainer = this.div && this.div.getBoundingClientRect(); + } + if (!parentContainer) { + parentContainer = this.div && this.div.parentElement?.getBoundingClientRect(); + } const relativeTop = elementContainer && parentContainer ? Math.abs(Math.round(elementContainer.top - parentContainer.top)) : 0; @@ -305,6 +315,11 @@ export class ElementState implements LayerElement { } this.dataStyle = css; + this.applyLayoutStylesToDiv(); + } + + isRoot(): this is RootElement { + return false; } /** Recursively visit all nodes */ diff --git a/public/app/features/canvas/runtime/group.tsx b/public/app/features/canvas/runtime/group.tsx index 35d38155a90..809dfc12fa4 100644 --- a/public/app/features/canvas/runtime/group.tsx +++ b/public/app/features/canvas/runtime/group.tsx @@ -82,7 +82,7 @@ export class GroupState extends ElementState { // ??? or should this be on the element directly? // are actions scoped to layers? - doAction = (action: LayerActionID, element: ElementState, updateName = true) => { + doAction = (action: LayerActionID, element: ElementState, updateName = true, shiftItemsOnDuplicate = true) => { switch (action) { case LayerActionID.Delete: this.elements = this.elements.filter((e) => e !== element); @@ -97,48 +97,50 @@ export class GroupState extends ElementState { } const opts = cloneDeep(element.options); - const { constraint, placement: oldPlacement } = element.options; - const { vertical, horizontal } = constraint ?? {}; - const placement = oldPlacement ?? ({} as Placement); + if (shiftItemsOnDuplicate) { + const { constraint, placement: oldPlacement } = element.options; + const { vertical, horizontal } = constraint ?? {}; + const placement = oldPlacement ?? ({} as Placement); - switch (vertical) { - case VerticalConstraint.Top: - case VerticalConstraint.TopBottom: - if (placement.top == null) { - placement.top = 25; - } else { - placement.top += 10; - } - break; - case VerticalConstraint.Bottom: - if (placement.bottom == null) { - placement.bottom = 100; - } else { - placement.bottom -= 10; - } - break; + switch (vertical) { + case VerticalConstraint.Top: + case VerticalConstraint.TopBottom: + if (placement.top == null) { + placement.top = 25; + } else { + placement.top += 10; + } + break; + case VerticalConstraint.Bottom: + if (placement.bottom == null) { + placement.bottom = 100; + } else { + placement.bottom -= 10; + } + break; + } + + switch (horizontal) { + case HorizontalConstraint.Left: + case HorizontalConstraint.LeftRight: + if (placement.left == null) { + placement.left = 50; + } else { + placement.left += 10; + } + break; + case HorizontalConstraint.Right: + if (placement.right == null) { + placement.right = 50; + } else { + placement.right -= 10; + } + break; + } + + opts.placement = placement; } - switch (horizontal) { - case HorizontalConstraint.Left: - case HorizontalConstraint.LeftRight: - if (placement.left == null) { - placement.left = 50; - } else { - placement.left += 10; - } - break; - case HorizontalConstraint.Right: - if (placement.right == null) { - placement.right = 50; - } else { - placement.right -= 10; - } - break; - } - - opts.placement = placement; - const copy = new ElementState(element.item, opts, this); copy.updateData(this.scene.context); if (updateName) { @@ -157,7 +159,7 @@ export class GroupState extends ElementState { render() { return ( -