import { Global } from '@emotion/react'; import Tree from 'rc-tree'; import React, { Key, useEffect, useMemo, useState } from 'react'; import { SelectableValue, StandardEditorProps } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Button, HorizontalGroup, Icon, useTheme2 } from '@grafana/ui'; import { ElementState } from 'app/features/canvas/runtime/element'; import { AddLayerButton } from '../../../../core/components/Layers/AddLayerButton'; import { CanvasElementOptions, canvasElementRegistry } from '../../../../features/canvas'; import { notFoundItem } from '../../../../features/canvas/elements/notFound'; import { getGlobalStyles } from '../globalStyles'; import { PanelOptions } from '../models.gen'; import { getTreeData, onNodeDrop, TreeElement } from '../tree'; import { DragNode, DropNode } from '../types'; import { doSelect, getElementTypes } from '../utils'; import { TreeNodeTitle } from './TreeNodeTitle'; import { TreeViewEditorProps } from './elementEditor'; let allowSelection = true; export const TreeNavigationEditor = ({ item }: StandardEditorProps) => { const [treeData, setTreeData] = useState(getTreeData(item?.settings?.scene.root)); const [autoExpandParent, setAutoExpandParent] = useState(true); const [expandedKeys, setExpandedKeys] = useState([]); const [selectedKeys, setSelectedKeys] = useState([]); const theme = useTheme2(); const globalCSS = getGlobalStyles(theme); const selectedBgColor = theme.v1.colors.formInputBorderActive; const { settings } = item; const selection = useMemo( () => (settings?.selected ? settings.selected.map((v) => v.getName()) : []), [settings?.selected] ); const selectionByUID = useMemo( () => (settings?.selected ? settings.selected.map((v) => v.UID) : []), [settings?.selected] ); useEffect(() => { setTreeData(getTreeData(item?.settings?.scene.root, selection, selectedBgColor)); setSelectedKeys(selectionByUID); setAllowSelection(); }, [item?.settings?.scene.root, selectedBgColor, selection, selectionByUID]); if (!settings) { return
No settings
; } const layer = settings.layer; if (!layer) { return
Missing layer?
; } const onSelect = (selectedKeys: Key[], info: { node: { dataRef: ElementState } }) => { if (allowSelection && item.settings?.scene) { doSelect(item.settings.scene, info.node.dataRef); } }; const allowDrop = () => { return true; }; const onDrop = (info: { node: DropNode; dragNode: DragNode; dropPosition: number; dropToGap: boolean }) => { const destPos = info.node.pos.split('-'); const destPosition = info.dropPosition - Number(destPos[destPos.length - 1]); const srcEl = info.dragNode.dataRef; const destEl = info.node.dataRef; const data = onNodeDrop(info, treeData); setTreeData(data); destEl.parent?.scene.reorderElements(srcEl, destEl, info.dropToGap, destPosition); }; const onExpand = (expandedKeys: Key[]) => { setExpandedKeys(expandedKeys); setAutoExpandParent(false); }; const switcherIcon = (obj: { isLeaf: boolean; expanded: boolean }) => { if (obj.isLeaf) { // TODO: Implement element specific icons return <>; } return ( ); }; const setAllowSelection = (allow = true) => { allowSelection = allow; }; const onAddItem = (sel: SelectableValue) => { const newItem = canvasElementRegistry.getIfExists(sel.value) ?? notFoundItem; const newElementOptions = newItem.getNewOptions() as CanvasElementOptions; newElementOptions.type = newItem.id; const newElement = new ElementState(newItem, newElementOptions, layer); newElement.updateData(layer.scene.context); layer.elements.push(newElement); layer.scene.save(); layer.reinitializeMoveable(); }; const onClearSelection = () => { layer.scene.clearCurrentSelection(); }; const onTitleRender = (nodeData: TreeElement) => { return ; }; // TODO: This functionality is currently kinda broken / no way to decouple / delete created frames at this time const onFrameSelection = () => { if (layer.scene) { layer.scene.frameSelection(); } else { console.warn('no scene!'); } }; const typeOptions = getElementTypes(settings.scene.shouldShowAdvancedTypes); return ( <>
{selection.length > 0 && ( )} {selection.length > 1 && config.featureToggles.canvasPanelNesting && ( )}
); };