Pushes
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { PointerEvent as ReactPointerEvent } from 'react';
|
||||
|
||||
import { sceneGraph, SceneObjectBase, SceneObjectState, VizPanel } from '@grafana/scenes';
|
||||
import { sceneGraph, SceneObjectBase, SceneObjectState } from '@grafana/scenes';
|
||||
import { createPointerDistance } from '@grafana/ui';
|
||||
|
||||
import { DashboardScene } from './DashboardScene';
|
||||
@@ -16,12 +16,13 @@ export class DashboardLayoutOrchestrator extends SceneObjectBase<DashboardLayout
|
||||
private _layoutItem: DashboardLayoutItem | null = null;
|
||||
private _pointerDistance = createPointerDistance();
|
||||
private _isSelectedObject = false;
|
||||
private _grids: DashboardLayoutGrid[] = [];
|
||||
|
||||
public constructor() {
|
||||
super({});
|
||||
|
||||
this._onPointerMove = this._onPointerMove.bind(this);
|
||||
this._stopDraggingSync = this._stopDraggingSync.bind(this);
|
||||
this._onPointerUp = this._onPointerUp.bind(this);
|
||||
|
||||
this.addActivationHandler(() => this._activationHandler());
|
||||
}
|
||||
@@ -29,12 +30,12 @@ export class DashboardLayoutOrchestrator extends SceneObjectBase<DashboardLayout
|
||||
private _activationHandler() {
|
||||
return () => {
|
||||
document.body.removeEventListener('pointermove', this._onPointerMove);
|
||||
document.body.removeEventListener('pointerup', this._stopDraggingSync);
|
||||
document.body.removeEventListener('pointerup', this._onPointerUp);
|
||||
document.body.classList.remove('dashboard-draggable-transparent-selection');
|
||||
};
|
||||
}
|
||||
|
||||
public getDashboard(): DashboardScene {
|
||||
private _getDashboard(): DashboardScene {
|
||||
if (!(this.parent instanceof DashboardScene)) {
|
||||
throw new Error('Parent is not a DashboardScene');
|
||||
}
|
||||
@@ -42,80 +43,18 @@ export class DashboardLayoutOrchestrator extends SceneObjectBase<DashboardLayout
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public startDraggingSync(evt: ReactPointerEvent, layoutItem: DashboardLayoutItem, layoutGrid: DashboardLayoutGrid) {
|
||||
this._pointerDistance.set(evt);
|
||||
|
||||
this._isSelectedObject = false;
|
||||
this._sourceGrid = layoutGrid;
|
||||
this._currentGrid = layoutGrid;
|
||||
this._layoutItem = layoutItem;
|
||||
|
||||
this._sourceGrid.setIsDropTarget?.(true, this._sourceGrid!, this._layoutItem!);
|
||||
|
||||
document.body.addEventListener('pointermove', this._onPointerMove);
|
||||
document.body.addEventListener('pointerup', this._stopDraggingSync);
|
||||
document.body.classList.add('dashboard-draggable-transparent-selection');
|
||||
}
|
||||
|
||||
private _onPointerMove(evt: PointerEvent) {
|
||||
this._selectVizPanelIfNeeded(evt);
|
||||
this._changeCurrentGridIfNeeded(evt);
|
||||
}
|
||||
|
||||
private _selectVizPanelIfNeeded(evt: PointerEvent) {
|
||||
if (!this._isSelectedObject && this._layoutItem && this._pointerDistance.check(evt)) {
|
||||
const panel = this._getVizPanelFromLayoutItem();
|
||||
|
||||
if (!panel) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._isSelectedObject = true;
|
||||
this.getDashboard().state.editPane.selectObject(panel, panel.state.key!, { force: true, multi: false });
|
||||
}
|
||||
}
|
||||
|
||||
private _getVizPanelFromLayoutItem(): VizPanel | null {
|
||||
if (
|
||||
this._layoutItem &&
|
||||
'state' in this._layoutItem &&
|
||||
'body' in this._layoutItem.state &&
|
||||
this._layoutItem.state.body instanceof VizPanel
|
||||
) {
|
||||
return this._layoutItem.state.body;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private _changeCurrentGridIfNeeded(evt: PointerEvent) {
|
||||
const currentGrid = this._getCurrentGrid(evt) ?? this._sourceGrid;
|
||||
|
||||
if (!currentGrid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentGrid !== this._currentGrid) {
|
||||
this._currentGrid?.setIsDropTarget?.(false, this._sourceGrid!, this._layoutItem!);
|
||||
this._currentGrid = currentGrid;
|
||||
|
||||
if (currentGrid !== this._sourceGrid) {
|
||||
currentGrid.setIsDropTarget?.(true, this._sourceGrid!, this._layoutItem!);
|
||||
}
|
||||
}
|
||||
private _findAllGrids(): DashboardLayoutGrid[] {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
return sceneGraph.findAllObjects(
|
||||
this._getDashboard(),
|
||||
(obj) => isDashboardLayoutManager(obj) && isDashboardLayoutGrid(obj)
|
||||
) as DashboardLayoutGrid[];
|
||||
}
|
||||
|
||||
private _getCurrentGrid(evt: MouseEvent): DashboardLayoutGrid | null {
|
||||
const elementsUnderPoint = document.elementsFromPoint(evt.clientX, evt.clientY);
|
||||
const cursorIsInSourceTarget = elementsUnderPoint.some(
|
||||
(el) => el.getAttribute('data-grid-manager-key') === this._sourceGrid?.state.key
|
||||
);
|
||||
|
||||
if (cursorIsInSourceTarget) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const key = elementsUnderPoint
|
||||
const key = document
|
||||
.elementsFromPoint(evt.clientX, evt.clientY)
|
||||
.reverse()
|
||||
?.find((element) => element.getAttribute('data-grid-manager-key'))
|
||||
?.getAttribute('data-grid-manager-key');
|
||||
|
||||
@@ -123,18 +62,57 @@ export class DashboardLayoutOrchestrator extends SceneObjectBase<DashboardLayout
|
||||
return null;
|
||||
}
|
||||
|
||||
const sceneObject = sceneGraph.findByKey(this.getDashboard(), key);
|
||||
const grid = this._grids.find((grid) => grid.state.key === key);
|
||||
|
||||
if (!sceneObject || !isDashboardLayoutManager(sceneObject) || !isDashboardLayoutGrid(sceneObject)) {
|
||||
if (!grid) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return sceneObject;
|
||||
return grid;
|
||||
}
|
||||
|
||||
private _stopDraggingSync(_evt: PointerEvent) {
|
||||
public startDragging(evt: ReactPointerEvent, layoutItem: DashboardLayoutItem, layoutGrid: DashboardLayoutGrid) {
|
||||
this._pointerDistance.set(evt);
|
||||
|
||||
this._isSelectedObject = false;
|
||||
this._sourceGrid = layoutGrid;
|
||||
this._currentGrid = layoutGrid;
|
||||
this._layoutItem = layoutItem;
|
||||
|
||||
this._grids = this._findAllGrids();
|
||||
|
||||
this._grids.forEach((grid) =>
|
||||
grid.onDragStart?.(this._sourceGrid!, this._layoutItem!, evt.nativeEvent)
|
||||
);
|
||||
|
||||
document.body.addEventListener('pointermove', this._onPointerMove);
|
||||
document.body.addEventListener('pointerup', this._onPointerUp);
|
||||
document.body.classList.add('dashboard-draggable-transparent-selection');
|
||||
}
|
||||
|
||||
private _onPointerMove(evt: PointerEvent) {
|
||||
// Select the panel if needed
|
||||
if (!this._isSelectedObject && this._pointerDistance.check(evt)) {
|
||||
this._isSelectedObject = true;
|
||||
|
||||
this._getDashboard().state.editPane.selectObject(
|
||||
this._layoutItem!.getElementBody()!,
|
||||
this._layoutItem!.getElementBody()!.state.key!,
|
||||
{
|
||||
force: true,
|
||||
multi: false,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
this._currentGrid = this._getCurrentGrid(evt) ?? this._currentGrid;
|
||||
|
||||
this._grids.forEach((grid) => grid.onDrag?.(this._sourceGrid!, this._currentGrid!, this._layoutItem!, evt));
|
||||
}
|
||||
|
||||
private _onPointerUp(evt: PointerEvent) {
|
||||
document.body.removeEventListener('pointermove', this._onPointerMove);
|
||||
document.body.removeEventListener('pointerup', this._stopDraggingSync);
|
||||
document.body.removeEventListener('pointerup', this._onPointerUp);
|
||||
document.body.classList.remove('dashboard-draggable-transparent-selection');
|
||||
|
||||
// Wrapped in setTimeout to ensure that any event handlers are called
|
||||
@@ -144,10 +122,7 @@ export class DashboardLayoutOrchestrator extends SceneObjectBase<DashboardLayout
|
||||
return;
|
||||
}
|
||||
|
||||
sceneGraph.findAllObjects(this.getDashboard(), (obj) => isDashboardLayoutManager(obj) && isDashboardLayoutGrid(obj)).forEach((obj) => {
|
||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
||||
(obj as DashboardLayoutGrid).stopOrchestratorSync?.(this._sourceGrid!, this._currentGrid!, this._layoutItem!);
|
||||
});
|
||||
this._grids.forEach((obj) => obj.onDragStop?.(this._sourceGrid!, this._currentGrid!, this._layoutItem!, evt));
|
||||
|
||||
this._isSelectedObject = false;
|
||||
this._sourceGrid = null;
|
||||
|
||||
@@ -74,6 +74,10 @@ export class AutoGridItem extends SceneObjectBase<AutoGridItemState> implements
|
||||
this.setState({ body });
|
||||
}
|
||||
|
||||
public getElementBody(): VizPanel {
|
||||
return this.state.body;
|
||||
}
|
||||
|
||||
public performRepeat() {
|
||||
if (!this.state.variableName || sceneGraph.hasVariableDependencyInLoadingState(this)) {
|
||||
return;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import { createRef, CSSProperties, PointerEvent as ReactPointerEvent } from 'react';
|
||||
|
||||
import { SceneLayout, SceneObjectBase, SceneObjectState, VizPanel, SceneGridItemLike } from '@grafana/scenes';
|
||||
import { SceneLayout, SceneObjectBase, SceneObjectState, VizPanel } from '@grafana/scenes';
|
||||
|
||||
import { isRepeatCloneOrChildOf } from '../../utils/clone';
|
||||
import { getLayoutOrchestratorFor } from '../../utils/utils';
|
||||
import { DashboardLayoutGrid } from '../types/DashboardLayoutGrid';
|
||||
import { DashboardLayoutItem } from '../types/DashboardLayoutItem';
|
||||
|
||||
import { AutoGridItem } from './AutoGridItem';
|
||||
import { AutoGridLayoutManager } from './AutoGridLayoutManager';
|
||||
import { AutoGridLayoutRenderer } from './AutoGridLayoutRenderer';
|
||||
import { DRAGGED_ITEM_HEIGHT, DRAGGED_ITEM_LEFT, DRAGGED_ITEM_TOP, DRAGGED_ITEM_WIDTH } from './const';
|
||||
|
||||
@@ -75,20 +78,6 @@ export class AutoGridLayout extends SceneObjectBase<AutoGridLayoutState> impleme
|
||||
children: state.children ?? [],
|
||||
...state,
|
||||
});
|
||||
|
||||
this._onDragStart = this._onDragStart.bind(this);
|
||||
this._onDragEnd = this._onDragEnd.bind(this);
|
||||
this._onDrag = this._onDrag.bind(this);
|
||||
|
||||
this.addActivationHandler(() => this._activationHandler());
|
||||
}
|
||||
|
||||
private _activationHandler() {
|
||||
return () => {
|
||||
this._resetPanelPositionAndSize();
|
||||
document.body.removeEventListener('pointermove', this._onDrag);
|
||||
document.body.removeEventListener('pointerup', this._onDragEnd);
|
||||
};
|
||||
}
|
||||
|
||||
public isDraggable(): boolean {
|
||||
@@ -112,78 +101,72 @@ export class AutoGridLayout extends SceneObjectBase<AutoGridLayoutState> impleme
|
||||
onDragStart: (evt: ReactPointerEvent, panel: VizPanel) => {
|
||||
const gridItem = panel.parent;
|
||||
if (gridItem instanceof AutoGridItem) {
|
||||
this._onDragStart(evt, gridItem);
|
||||
getLayoutOrchestratorFor(this)?.startDragging(evt, gridItem, this._getLayoutManager());
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
private _canDrag(evt: ReactPointerEvent): boolean {
|
||||
if (!this.isDraggable()) {
|
||||
return false;
|
||||
// private _canDrag(evt: PointerEvent): boolean {
|
||||
// if (!this.isDraggable()) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// if (!(evt.target instanceof Element)) {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// return !!evt.target.closest(`.${this.getDragClass()}`) && !evt.target.closest(`.${this.getDragClassCancel()}`);
|
||||
// }
|
||||
|
||||
private _getLayoutManager(): AutoGridLayoutManager {
|
||||
if (!(this.parent instanceof AutoGridLayoutManager)) {
|
||||
throw new Error('Parent of AutoGridLayout must be AutoGridLayoutManager');
|
||||
}
|
||||
|
||||
if (!(evt.target instanceof Element)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!evt.target.closest(`.${this.getDragClass()}`) && !evt.target.closest(`.${this.getDragClassCancel()}`);
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
// Start inside dragging
|
||||
private _onDragStart(evt: ReactPointerEvent, gridItem: SceneGridItemLike) {
|
||||
if (!this._canDrag(evt)) {
|
||||
return;
|
||||
public onDragStart(sourceGrid: DashboardLayoutGrid, layoutItem: DashboardLayoutItem, evt: PointerEvent) {
|
||||
// if (!this._canDrag(evt)) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (!(layoutItem instanceof AutoGridItem)) {
|
||||
// throw new Error('Dragging wrong item');
|
||||
// }
|
||||
|
||||
if (layoutItem instanceof AutoGridItem) {
|
||||
this._draggedGridItem = sourceGrid === this._getLayoutManager() ? layoutItem : layoutItem.clone();
|
||||
} else {
|
||||
this._draggedGridItem = new AutoGridItem({
|
||||
body: layoutItem.getElementBody().clone(),
|
||||
});
|
||||
}
|
||||
|
||||
// evt.preventDefault();
|
||||
// evt.stopPropagation();
|
||||
|
||||
if (!(gridItem instanceof AutoGridItem)) {
|
||||
throw new Error('Dragging wrong item');
|
||||
if (!this.state.children.includes(this._draggedGridItem)) {
|
||||
this.setState({ children: [...this.state.children, this._draggedGridItem] });
|
||||
}
|
||||
|
||||
this._draggedGridItem = gridItem;
|
||||
setTimeout(() => {
|
||||
const { top, left, width, height } = this._draggedGridItem!.getBoundingBox();
|
||||
this._initialGridItemPosition = { pageX: evt.pageX, pageY: evt.pageY, top, left: left };
|
||||
this._updatePanelSize(width, height);
|
||||
this._updatePanelPosition(top, left);
|
||||
|
||||
const { top, left, width, height } = this._draggedGridItem.getBoundingBox();
|
||||
this._initialGridItemPosition = { pageX: evt.pageX, pageY: evt.pageY, top, left: left };
|
||||
this._updatePanelSize(width, height);
|
||||
this._updatePanelPosition(top, left);
|
||||
|
||||
this.setState({ draggingKey: this._draggedGridItem.state.key });
|
||||
|
||||
document.body.addEventListener('pointermove', this._onDrag);
|
||||
document.body.addEventListener('pointerup', this._onDragEnd);
|
||||
document.body.classList.add('dashboard-draggable-transparent-selection');
|
||||
|
||||
getLayoutOrchestratorFor(this)?.startDraggingSync(evt, this._draggedGridItem, this);
|
||||
this.setState({ draggingKey: this._draggedGridItem!.state.key });
|
||||
});
|
||||
}
|
||||
|
||||
// Stop inside dragging
|
||||
private _onDragEnd() {
|
||||
window.getSelection()?.removeAllRanges();
|
||||
|
||||
this._draggedGridItem = null;
|
||||
this._initialGridItemPosition = null;
|
||||
this._resetPanelPositionAndSize();
|
||||
|
||||
this.setState({ draggingKey: undefined });
|
||||
|
||||
document.body.removeEventListener('pointermove', this._onDrag);
|
||||
document.body.removeEventListener('pointerup', this._onDragEnd);
|
||||
document.body.classList.remove('dashboard-draggable-transparent-selection');
|
||||
}
|
||||
|
||||
// Handle inside drag moves
|
||||
private _onDrag(evt: PointerEvent) {
|
||||
if (!this._draggedGridItem || !this._initialGridItemPosition) {
|
||||
this._onDragEnd();
|
||||
return;
|
||||
}
|
||||
|
||||
public onDrag(
|
||||
sourceGrid: DashboardLayoutGrid,
|
||||
targetGrid: DashboardLayoutGrid,
|
||||
layoutItem: DashboardLayoutItem,
|
||||
evt: PointerEvent
|
||||
) {
|
||||
this._updatePanelPosition(
|
||||
this._initialGridItemPosition.top + (evt.pageY - this._initialGridItemPosition.pageY),
|
||||
this._initialGridItemPosition.left + (evt.pageX - this._initialGridItemPosition.pageX)
|
||||
this._initialGridItemPosition!.top + (evt.pageY - this._initialGridItemPosition!.pageY),
|
||||
this._initialGridItemPosition!.left + (evt.pageX - this._initialGridItemPosition!.pageX)
|
||||
);
|
||||
|
||||
const dropTargetGridItemKey = document
|
||||
@@ -200,6 +183,31 @@ export class AutoGridLayout extends SceneObjectBase<AutoGridLayoutState> impleme
|
||||
}
|
||||
}
|
||||
|
||||
public onDragStop(sourceGrid: DashboardLayoutGrid,
|
||||
targetGrid: DashboardLayoutGrid,
|
||||
layoutItem: DashboardLayoutItem,
|
||||
evt: PointerEvent) {
|
||||
if (targetGrid !== this._getLayoutManager()) {
|
||||
this.setState({ children: this.state.children.filter((child) => child !== this._draggedGridItem!) });
|
||||
}
|
||||
|
||||
this._draggedGridItem = null;
|
||||
}
|
||||
|
||||
// public onDragStop() {
|
||||
// window.getSelection()?.removeAllRanges();
|
||||
//
|
||||
// this._draggedGridItem = null;
|
||||
// this._initialGridItemPosition = null;
|
||||
// this._resetPanelPositionAndSize();
|
||||
//
|
||||
// this.setState({ draggingKey: undefined });
|
||||
//
|
||||
// document.body.removeEventListener('pointermove', this._onDrag);
|
||||
// document.body.removeEventListener('pointerup', this._onDragEnd);
|
||||
// document.body.classList.remove('dashboard-draggable-transparent-selection');
|
||||
// }
|
||||
|
||||
// Handle dragging an item from the same grid over another item from the same grid
|
||||
private _onDragOverItem(key: string) {
|
||||
const children = [...this.state.children];
|
||||
@@ -226,18 +234,18 @@ export class AutoGridLayout extends SceneObjectBase<AutoGridLayoutState> impleme
|
||||
this._setContainerStyle(DRAGGED_ITEM_HEIGHT, `${Math.floor(height)}px`);
|
||||
}
|
||||
|
||||
private _resetPanelPositionAndSize() {
|
||||
this._removeContainerStyle(DRAGGED_ITEM_TOP);
|
||||
this._removeContainerStyle(DRAGGED_ITEM_LEFT);
|
||||
this._removeContainerStyle(DRAGGED_ITEM_WIDTH);
|
||||
this._removeContainerStyle(DRAGGED_ITEM_HEIGHT);
|
||||
}
|
||||
// private _resetPanelPositionAndSize() {
|
||||
// this._removeContainerStyle(DRAGGED_ITEM_TOP);
|
||||
// this._removeContainerStyle(DRAGGED_ITEM_LEFT);
|
||||
// this._removeContainerStyle(DRAGGED_ITEM_WIDTH);
|
||||
// this._removeContainerStyle(DRAGGED_ITEM_HEIGHT);
|
||||
// }
|
||||
|
||||
private _setContainerStyle(name: string, value: string) {
|
||||
this.containerRef.current?.style.setProperty(name, value);
|
||||
}
|
||||
|
||||
private _removeContainerStyle(name: string) {
|
||||
this.containerRef.current?.style.removeProperty(name);
|
||||
}
|
||||
// private _removeContainerStyle(name: string) {
|
||||
// this.containerRef.current?.style.removeProperty(name);
|
||||
// }
|
||||
}
|
||||
|
||||
+20
-1
@@ -24,6 +24,7 @@ import {
|
||||
import { DashboardGridItem } from '../layout-default/DashboardGridItem';
|
||||
import { clearClipboard, getAutoGridItemFromClipboard } from '../layouts-shared/paste';
|
||||
import { DashboardLayoutGrid } from '../types/DashboardLayoutGrid';
|
||||
import { DashboardLayoutItem } from '../types/DashboardLayoutItem';
|
||||
import { DashboardLayoutManager } from '../types/DashboardLayoutManager';
|
||||
import { LayoutRegistryItem } from '../types/LayoutRegistryItem';
|
||||
|
||||
@@ -360,8 +361,26 @@ export class AutoGridLayoutManager extends SceneObjectBase<AutoGridLayoutManager
|
||||
this.state.layout.setState({ children: [...this.state.layout.state.children, gridItem] });
|
||||
}
|
||||
|
||||
public startOrchestratorSync() {
|
||||
public onDragStart(sourceGrid: DashboardLayoutGrid, layoutItem: DashboardLayoutItem, evt: PointerEvent) {
|
||||
this.state.layout.onDragStart(sourceGrid, layoutItem, evt);
|
||||
}
|
||||
|
||||
public onDrag(
|
||||
sourceGrid: DashboardLayoutGrid,
|
||||
targetGrid: DashboardLayoutGrid,
|
||||
layoutItem: DashboardLayoutItem,
|
||||
evt: PointerEvent,
|
||||
) {
|
||||
this.state.layout.onDrag(sourceGrid, targetGrid, layoutItem, evt);
|
||||
}
|
||||
|
||||
public onDragStop(
|
||||
sourceGrid: DashboardLayoutGrid,
|
||||
targetGrid: DashboardLayoutGrid,
|
||||
layoutItem: DashboardLayoutItem,
|
||||
evt: PointerEvent,
|
||||
) {
|
||||
// this.state.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,6 +117,10 @@ export class DashboardGridItem
|
||||
this.setState({ body });
|
||||
}
|
||||
|
||||
public getElementBody(): VizPanel {
|
||||
return this.state.body;
|
||||
}
|
||||
|
||||
public handleEditChange() {
|
||||
this._prevRepeatValues = undefined;
|
||||
|
||||
|
||||
+36
-29
@@ -16,7 +16,7 @@ import {
|
||||
useSceneObjectState,
|
||||
SceneObject,
|
||||
SceneGridLayoutDragStartEvent,
|
||||
SceneGridPlaceholderItem
|
||||
SceneGridPlaceholderItem,
|
||||
} from '@grafana/scenes';
|
||||
import { Spec as DashboardV2Spec } from '@grafana/schema/dist/esm/schema/dashboard/v2';
|
||||
import { useStyles2 } from '@grafana/ui';
|
||||
@@ -90,6 +90,8 @@ export class DefaultGridLayoutManager
|
||||
|
||||
public readonly descriptor = DefaultGridLayoutManager.descriptor;
|
||||
|
||||
private _draggingGridItem: DashboardLayoutItem | undefined;
|
||||
|
||||
public constructor(state: DefaultGridLayoutManagerState) {
|
||||
super(state);
|
||||
|
||||
@@ -127,14 +129,13 @@ export class DefaultGridLayoutManager
|
||||
private _activationHandler() {
|
||||
if (config.featureToggles.dashboardNewLayouts) {
|
||||
this._subs.add(
|
||||
this.subscribeToEvent(SceneGridLayoutDragStartEvent, ({ payload: { evt, panel }}) => {
|
||||
this.subscribeToEvent(SceneGridLayoutDragStartEvent, ({ payload: { evt, panel } }) => {
|
||||
const gridItem = panel.parent;
|
||||
if (gridItem instanceof DashboardGridItem) {
|
||||
this.state.grid.setPlaceholderSize(gridItem.state.width ?? NEW_PANEL_WIDTH, gridItem.state.height ?? NEW_PANEL_HEIGHT);
|
||||
getLayoutOrchestratorFor(this)?.startDraggingSync(evt, gridItem, this);
|
||||
getLayoutOrchestratorFor(this)?.startDragging(evt, gridItem, this);
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
this._subs.add(
|
||||
@@ -367,7 +368,11 @@ export class DefaultGridLayoutManager
|
||||
const panels: VizPanel[] = [];
|
||||
|
||||
this.state.grid.forEachChild((child) => {
|
||||
if (!(child instanceof DashboardGridItem) && !(child instanceof SceneGridRow) && !(child instanceof SceneGridPlaceholderItem)) {
|
||||
if (
|
||||
!(child instanceof DashboardGridItem) &&
|
||||
!(child instanceof SceneGridRow) &&
|
||||
!(child instanceof SceneGridPlaceholderItem)
|
||||
) {
|
||||
throw new Error('Child is not a DashboardGridItem or SceneGridRow, invalid scene');
|
||||
}
|
||||
|
||||
@@ -566,34 +571,33 @@ export class DefaultGridLayoutManager
|
||||
this.state.grid.setState({ children: [...this.state.grid.state.children, gridItem] });
|
||||
}
|
||||
|
||||
public setIsDropTarget(flag: boolean, sourceGrid: DashboardLayoutGrid) {
|
||||
const newState = {
|
||||
isDragging: flag,
|
||||
isOutsideDragging: sourceGrid !== this,
|
||||
};
|
||||
public onDragStart(sourceGrid: DashboardLayoutGrid, layoutItem: DashboardLayoutItem) {
|
||||
if (layoutItem instanceof DashboardGridItem) {
|
||||
this._draggingGridItem = sourceGrid === this ? layoutItem : layoutItem.clone();
|
||||
} else {
|
||||
const width = layoutItem instanceof DashboardGridItem ? layoutItem.state.width : NEW_PANEL_WIDTH;
|
||||
const height = layoutItem instanceof DashboardGridItem ? layoutItem.state.height : NEW_PANEL_HEIGHT;
|
||||
|
||||
if (newState.isDragging !== this.state.grid.state.isDragging || newState.isOutsideDragging !== this.state.grid.state.isOutsideDragging) {
|
||||
this.state.grid.setState(newState);
|
||||
this._draggingGridItem = new DashboardGridItem({
|
||||
width: width ?? NEW_PANEL_WIDTH,
|
||||
height: height ?? NEW_PANEL_HEIGHT,
|
||||
body: layoutItem.getElementBody().clone(),
|
||||
});
|
||||
}
|
||||
|
||||
this.state.grid.setPlaceholder(this._draggingGridItem);
|
||||
}
|
||||
|
||||
public stopOrchestratorSync(sourceGrid: DashboardLayoutGrid, targetGrid: DashboardLayoutGrid, layoutItem: DashboardLayoutItem) {
|
||||
console.log('stop orchestrator sync');
|
||||
|
||||
const isSourceGrid = sourceGrid === this;
|
||||
const isTargetGrid = targetGrid === this;
|
||||
|
||||
if (!isSourceGrid && !isTargetGrid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSourceGrid && !isTargetGrid) {
|
||||
public onDragStop(sourceGrid: DashboardLayoutGrid, targetGrid: DashboardLayoutGrid, layoutItem: DashboardLayoutItem) {
|
||||
if (sourceGrid !== this && targetGrid === this) {
|
||||
const panel = layoutItem.getElementBody();
|
||||
panel.clearParent();
|
||||
this._draggingGridItem?.setElementBody(panel);
|
||||
} else if (sourceGrid === this && targetGrid !== this) {
|
||||
this.state.grid.setState({ children: this.state.grid.state.children.filter((child) => child !== layoutItem) });
|
||||
} else if (!isSourceGrid && isTargetGrid) {
|
||||
// From outside drag
|
||||
} else {
|
||||
// Inside drag
|
||||
}
|
||||
|
||||
this._draggingGridItem = undefined;
|
||||
}
|
||||
|
||||
public static createFromLayout(currentLayout: DashboardLayoutManager): DefaultGridLayoutManager {
|
||||
@@ -690,7 +694,10 @@ function DefaultGridLayoutManagerRenderer({ model }: SceneComponentProps<Default
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={cx(styles.container, isEditing && styles.containerEditing)} data-grid-manager-key={model.state.key!}>
|
||||
<div
|
||||
className={cx(styles.container, isEditing && styles.containerEditing)}
|
||||
data-grid-manager-key={model.state.key!}
|
||||
>
|
||||
{model.state.grid.Component && <model.state.grid.Component model={model.state.grid} />}
|
||||
{showCanvasActions && (
|
||||
<div className={styles.actionsWrapper}>
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { SceneObject, SceneGridItemLike } from '@grafana/scenes';
|
||||
|
||||
export interface DashboardDropTarget extends SceneObject {
|
||||
isDashboardDropTarget: Readonly<true>;
|
||||
setIsDropTarget?(isDropTarget: boolean): void;
|
||||
draggedGridItemOutside?(gridItem: SceneGridItemLike): void;
|
||||
draggedGridItemInside?(gridItem: SceneGridItemLike): void;
|
||||
}
|
||||
|
||||
export function isDashboardDropTarget(scene: SceneObject): scene is DashboardDropTarget {
|
||||
return 'isDashboardDropTarget' in scene && scene.isDashboardDropTarget === true;
|
||||
}
|
||||
@@ -16,15 +16,25 @@ export interface DashboardLayoutGrid extends DashboardLayoutManager {
|
||||
/**
|
||||
* Start the synchronization of the orchestrator with the grid drag
|
||||
*/
|
||||
startOrchestratorSync?(): void;
|
||||
onDragStart?(sourceGrid: DashboardLayoutGrid, layoutItem: DashboardLayoutItem, evt: PointerEvent): void;
|
||||
|
||||
stopOrchestratorSync?(sourceGrid: DashboardLayoutGrid, targetGrid: DashboardLayoutGrid, layoutItem: DashboardLayoutItem): void;
|
||||
onDragStop?(
|
||||
sourceGrid: DashboardLayoutGrid,
|
||||
targetGrid: DashboardLayoutGrid,
|
||||
layoutItem: DashboardLayoutItem,
|
||||
evt: PointerEvent
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Toggle the grid as the current drop target
|
||||
* Useful for toggling between inner drag and outer drag
|
||||
*/
|
||||
setIsDropTarget?(flag: boolean, sourceGrid: DashboardLayoutGrid, layoutItem: DashboardLayoutItem): void;
|
||||
onDrag?(
|
||||
sourceGrid: DashboardLayoutGrid,
|
||||
targetGrid: DashboardLayoutGrid,
|
||||
layoutItem: DashboardLayoutItem,
|
||||
evt: PointerEvent
|
||||
): void;
|
||||
}
|
||||
|
||||
export function isDashboardLayoutGrid(obj: DashboardLayoutManager): obj is DashboardLayoutGrid {
|
||||
|
||||
@@ -19,6 +19,11 @@ export interface DashboardLayoutItem extends SceneObject {
|
||||
* Change inner body / viz panel
|
||||
*/
|
||||
setElementBody(body: VizPanel): void;
|
||||
|
||||
/**
|
||||
* Access inner body / viz panel
|
||||
*/
|
||||
getElementBody(): VizPanel;
|
||||
}
|
||||
|
||||
export function isDashboardLayoutItem(obj: SceneObject): obj is DashboardLayoutItem {
|
||||
|
||||
Reference in New Issue
Block a user