mirror of
https://github.com/grafana/grafana.git
synced 2026-09-05 04:40:13 -05:00
Canvas: Tree View Navigation (#51855)
* tree navigation using rc-tree library
This commit is contained in:
@@ -74,6 +74,19 @@ export class FrameState extends ElementState {
|
||||
this.reinitializeMoveable();
|
||||
}
|
||||
|
||||
// used for tree view
|
||||
reorderTree(src: ElementState, dest: ElementState, firstPosition = false) {
|
||||
const result = Array.from(this.elements);
|
||||
const srcIndex = this.elements.indexOf(src);
|
||||
const destIndex = firstPosition ? this.elements.length - 1 : this.elements.indexOf(dest);
|
||||
|
||||
const [removed] = result.splice(srcIndex, 1);
|
||||
result.splice(destIndex, 0, removed);
|
||||
this.elements = result;
|
||||
|
||||
this.reinitializeMoveable();
|
||||
}
|
||||
|
||||
doMove(child: ElementState, action: LayerActionID) {
|
||||
const vals = this.elements.filter((v) => v !== child);
|
||||
if (action === LayerActionID.MoveBottom) {
|
||||
@@ -176,7 +189,7 @@ export class FrameState extends ElementState {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div key={this.UID} ref={this.initElement} style={{ overflow: 'hidden' }}>
|
||||
<div key={this.UID} ref={this.initElement}>
|
||||
{this.elements.map((v) => v.render())}
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -417,6 +417,65 @@ export class Scene {
|
||||
});
|
||||
};
|
||||
|
||||
reorderElements = (src: ElementState, dest: ElementState, dragToGap: boolean, destPosition: number) => {
|
||||
switch (dragToGap) {
|
||||
case true:
|
||||
switch (destPosition) {
|
||||
case -1:
|
||||
// top of the tree
|
||||
if (src.parent instanceof FrameState) {
|
||||
// move outside the frame
|
||||
if (dest.parent) {
|
||||
this.updateElements(src, dest.parent, dest.parent.elements.length);
|
||||
src.updateData(dest.parent.scene.context);
|
||||
}
|
||||
} else {
|
||||
dest.parent?.reorderTree(src, dest, true);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (dest.parent) {
|
||||
this.updateElements(src, dest.parent, dest.parent.elements.indexOf(dest));
|
||||
src.updateData(dest.parent.scene.context);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case false:
|
||||
if (dest instanceof FrameState) {
|
||||
if (src.parent === dest) {
|
||||
// same frame parent
|
||||
src.parent?.reorderTree(src, dest, true);
|
||||
} else {
|
||||
this.updateElements(src, dest);
|
||||
src.updateData(dest.scene.context);
|
||||
}
|
||||
} else if (src.parent === dest.parent) {
|
||||
src.parent?.reorderTree(src, dest);
|
||||
} else {
|
||||
if (dest.parent) {
|
||||
this.updateElements(src, dest.parent);
|
||||
src.updateData(dest.parent.scene.context);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
private updateElements = (src: ElementState, dest: FrameState | RootElement, idx: number | null = null) => {
|
||||
src.parent?.doAction(LayerActionID.Delete, src);
|
||||
src.parent = dest;
|
||||
|
||||
const elementContainer = src.div?.getBoundingClientRect();
|
||||
src.setPlacementFromConstraint(elementContainer, dest.div?.getBoundingClientRect());
|
||||
|
||||
const destIndex = idx ?? dest.elements.length - 1;
|
||||
dest.elements.splice(destIndex, 0, src);
|
||||
dest.scene.save();
|
||||
|
||||
dest.reinitializeMoveable();
|
||||
};
|
||||
|
||||
render() {
|
||||
const canShowContextMenu = this.isPanelEditing || (!this.isPanelEditing && this.isEditingEnabled);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user