grafana/public/app/features/scenes/editor/SceneObjectTree.tsx
Torkel Ödegaard 8c585a4ebf
Scene: Variables interpolation formats and multi value handling (#58591)
* Component that can cache and extract variable dependencies

* Component that can cache and extract variable dependencies

* Updates

* Refactoring

* Lots of refactoring and iterations of supporting both re-rendering and query re-execution

* Updated SceneCanvasText

* Updated name of file

* Updated

* Refactoring a bit

* Added back getName

* Added comment

* minor fix

* Minor fix

* Merge fixes

* Scene variable interpolation progress

* Merge fixes

* Added all format registeries

* Progress on multi value support

* Progress on multi value support

* Updates

* Progress on scoped vars

* Fixed circular dependency

* Updates

* Some review fixes

* Updated comment

* Added forceRender function

* Add back fail on console log

* Update public/app/features/scenes/variables/interpolation/sceneInterpolator.test.ts

* Moving functions from SceneObjectBase

* fixing tests

* Fixed e2e

Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
2022-11-16 11:36:30 +01:00

82 lines
2.1 KiB
TypeScript

import { css, cx } from '@emotion/css';
import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { Icon, useStyles2 } from '@grafana/ui';
import { sceneGraph } from '../core/sceneGraph';
import { SceneObject, isSceneObject, SceneLayoutChild } from '../core/types';
export interface Props {
node: SceneObject;
selectedObject?: SceneObject;
}
export function SceneObjectTree({ node, selectedObject }: Props) {
const styles = useStyles2(getStyles);
const state = node.useState();
let children: SceneLayoutChild[] = [];
for (const propKey of Object.keys(state)) {
const propValue = (state as any)[propKey];
if (isSceneObject(propValue)) {
children.push(propValue);
}
}
if ('children' in state) {
for (const child of state.children) {
children.push(child);
}
}
const name = node.constructor.name;
const isSelected = selectedObject === node;
const onSelectNode = () => sceneGraph.getSceneEditor(node).onSelectObject(node);
return (
<div className={styles.node}>
<div className={styles.header} onClick={onSelectNode}>
<div className={styles.icon}>{children.length > 0 && <Icon name="angle-down" size="sm" />}</div>
<div className={cx(styles.name, isSelected && styles.selected)}>{name}</div>
</div>
{children.length > 0 && (
<div className={styles.children}>
{children.map((child) => (
<SceneObjectTree node={child} selectedObject={selectedObject} key={child.state.key} />
))}
</div>
)}
</div>
);
}
const getStyles = (theme: GrafanaTheme2) => {
return {
node: css({
display: 'flex',
flexGrow: 0,
cursor: 'pointer',
flexDirection: 'column',
padding: '2px 4px',
}),
header: css({
display: 'flex',
fontWeight: 500,
}),
name: css({}),
selected: css({
color: theme.colors.error.text,
}),
icon: css({
width: theme.spacing(3),
color: theme.colors.text.secondary,
}),
children: css({
display: 'flex',
flexDirection: 'column',
paddingLeft: 8,
}),
};
};