Submit
Path:
~
/
/
usr
/
share
/
grafana
/
public
/
app
/
plugins
/
panel
/
canvas
/
editor
/
layer
/
File Content:
TreeNavigationEditor.tsx
import { css } from '@emotion/css'; import { Global } from '@emotion/react'; import Tree, { TreeNodeProps } from 'rc-tree'; import React, { Key, useEffect, useMemo, useState } from 'react'; import { GrafanaTheme2, StandardEditorProps } from '@grafana/data'; import { config } from '@grafana/runtime'; import { Button, HorizontalGroup, Icon, useStyles2, useTheme2 } from '@grafana/ui'; import { AddLayerButton } from 'app/core/components/Layers/AddLayerButton'; import { ElementState } from 'app/features/canvas/runtime/element'; import { getGlobalStyles } from '../../globalStyles'; import { Options } from '../../panelcfg.gen'; import { DragNode, DropNode } from '../../types'; import { doSelect, getElementTypes, onAddItem } from '../../utils'; import { TreeViewEditorProps } from '../element/elementEditor'; import { TreeNodeTitle } from './TreeNodeTitle'; import { getTreeData, onNodeDrop, TreeElement } from './tree'; let allowSelection = true; export const TreeNavigationEditor = ({ item }: StandardEditorProps<any, TreeViewEditorProps, Options>) => { const [treeData, setTreeData] = useState(getTreeData(item?.settings?.scene.root)); const [autoExpandParent, setAutoExpandParent] = useState(true); const [expandedKeys, setExpandedKeys] = useState<Key[]>([]); const [selectedKeys, setSelectedKeys] = useState<Key[]>([]); const theme = useTheme2(); const globalCSS = getGlobalStyles(theme); const styles = useStyles2(getStyles); const selectedBgColor = theme.colors.primary.border; 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 <div>No settings</div>; } const layer = settings.layer; if (!layer) { return <div>Missing layer?</div>; } 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: TreeNodeProps) => { if (obj.isLeaf) { // TODO: Implement element specific icons return <></>; } return ( <Icon name="angle-right" title={'Node Icon'} style={{ transform: `rotate(${obj.expanded ? 90 : 0}deg)`, fill: theme.colors.text.primary, }} /> ); }; const setAllowSelection = (allow = true) => { allowSelection = allow; }; const onClearSelection = () => { layer.scene.clearCurrentSelection(); }; const onTitleRender = (nodeData: TreeElement) => { return <TreeNodeTitle nodeData={nodeData} setAllowSelection={setAllowSelection} settings={settings} />; }; // 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).options; return ( <> <Global styles={globalCSS} /> <Tree selectable={true} onSelect={onSelect} draggable={true} defaultExpandAll={true} autoExpandParent={autoExpandParent} showIcon={false} allowDrop={allowDrop} onDrop={onDrop} expandedKeys={expandedKeys} onExpand={onExpand} treeData={treeData} titleRender={onTitleRender} switcherIcon={switcherIcon} selectedKeys={selectedKeys} multiple={true} /> <HorizontalGroup justify="space-between"> <div className={styles.addLayerButton}> <AddLayerButton onChange={(sel) => onAddItem(sel, layer)} options={typeOptions} label={'Add item'} /> </div> {selection.length > 0 && ( <Button size="sm" variant="secondary" onClick={onClearSelection}> Clear selection </Button> )} {selection.length > 1 && config.featureToggles.canvasPanelNesting && ( <Button size="sm" variant="secondary" onClick={onFrameSelection}> Frame selection </Button> )} </HorizontalGroup> </> ); }; const getStyles = (theme: GrafanaTheme2) => ({ addLayerButton: css({ marginLeft: '18px', minWidth: '150px', }), });
Submit
FILE
FOLDER
INFO
Name
Size
Permission
Action
TreeNavigationEditor.tsx
5455 bytes
0644
TreeNodeTitle.tsx
3120 bytes
0644
layerEditor.tsx
2855 bytes
0644
tree.ts
2592 bytes
0644
N4ST4R_ID | Naxtarrr