DashboardOutline: Sync row collapse state with outline node collapse state (#103283)

DashboardOutline: Sync row expanded state with outline
pull/103332/head
Torkel Ödegaard 9 months ago committed by GitHub
parent 4918d8720c
commit a96f80312f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 41
      public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx
  2. 8
      public/app/features/dashboard-scene/scene/layout-rows/RowItem.tsx
  3. 10
      public/app/features/dashboard-scene/scene/types/EditableDashboardElement.ts

@ -1,5 +1,5 @@
import { css, cx } from '@emotion/css'; import { css, cx } from '@emotion/css';
import { useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
import { GrafanaTheme2 } from '@grafana/data'; import { GrafanaTheme2 } from '@grafana/data';
import { SceneObject, VizPanel } from '@grafana/scenes'; import { SceneObject, VizPanel } from '@grafana/scenes';
@ -22,12 +22,20 @@ export function DashboardOutline({ editPane }: Props) {
return ( return (
<Box padding={1} gap={0.25} display="flex" direction="column"> <Box padding={1} gap={0.25} display="flex" direction="column">
<DashboardOutlineNode sceneObject={dashboard} expandable /> <DashboardOutlineNode sceneObject={dashboard} editPane={editPane} expandable />
</Box> </Box>
); );
} }
function DashboardOutlineNode({ sceneObject, expandable }: { sceneObject: SceneObject; expandable: boolean }) { function DashboardOutlineNode({
sceneObject,
expandable,
editPane,
}: {
sceneObject: SceneObject;
expandable: boolean;
editPane: DashboardEditPane;
}) {
const [isExpanded, setIsExpanded] = useState(true); const [isExpanded, setIsExpanded] = useState(true);
const { key } = sceneObject.useState(); const { key } = sceneObject.useState();
const styles = useStyles2(getStyles); const styles = useStyles2(getStyles);
@ -38,17 +46,33 @@ function DashboardOutlineNode({ sceneObject, expandable }: { sceneObject: SceneO
const children = collectEditableElementChildren(sceneObject); const children = collectEditableElementChildren(sceneObject);
const elementInfo = editableElement.getEditableElementInfo(); const elementInfo = editableElement.getEditableElementInfo();
const instanceName = elementInfo.instanceName === '' ? '<empty title>' : elementInfo.instanceName; const instanceName = elementInfo.instanceName === '' ? '<empty title>' : elementInfo.instanceName;
const elementExpanded = !editableElement.getCollapsedState?.();
const onPointerDown = (evt: React.PointerEvent) => {
onSelect?.(evt);
setIsExpanded(!isExpanded);
editableElement.scrollIntoView?.();
// Sync expanded state with canvas element
if (editableElement.getCollapsedState) {
editableElement.setCollapsedState?.(isExpanded);
}
};
// Sync canvas element expanded state with outline element
useEffect(() => {
if (elementExpanded !== isExpanded) {
console.log('elementExpanded', elementExpanded);
setIsExpanded(elementExpanded);
}
}, [isExpanded, elementExpanded]);
return ( return (
<> <>
<button <button
role="treeitem" role="treeitem"
className={cx(styles.nodeButton, isCloned && styles.nodeButtonClone, isSelected && styles.nodeButtonSelected)} className={cx(styles.nodeButton, isCloned && styles.nodeButtonClone, isSelected && styles.nodeButtonSelected)}
onPointerDown={(evt) => { onPointerDown={onPointerDown}
onSelect?.(evt);
setIsExpanded(!isExpanded);
editableElement.scrollIntoView?.();
}}
> >
{expandable && <Icon name={isExpanded ? 'angle-down' : 'angle-right'} />} {expandable && <Icon name={isExpanded ? 'angle-down' : 'angle-right'} />}
<Icon size="sm" name={elementInfo.icon} /> <Icon size="sm" name={elementInfo.icon} />
@ -63,6 +87,7 @@ function DashboardOutlineNode({ sceneObject, expandable }: { sceneObject: SceneO
key={child.sceneObject.state.key} key={child.sceneObject.state.key}
sceneObject={child.sceneObject} sceneObject={child.sceneObject}
expandable={child.expandable} expandable={child.expandable}
editPane={editPane}
/> />
)) ))
) : ( ) : (

@ -202,4 +202,12 @@ export class RowItem
public scrollIntoView() { public scrollIntoView() {
scrollCanvasElementIntoView(this, this.containerRef); scrollCanvasElementIntoView(this, this.containerRef);
} }
public getCollapsedState(): boolean {
return this.state.collapse ?? false;
}
public setCollapsedState(collapse: boolean) {
this.setState({ collapse });
}
} }

@ -49,6 +49,16 @@ export interface EditableDashboardElement {
* scroll element into view (when selected from outline) * scroll element into view (when selected from outline)
*/ */
scrollIntoView?(): void; scrollIntoView?(): void;
/**
* Used to sync row collapsed state with outline
*/
getCollapsedState?(): boolean;
/**
* Used to sync row collapsed state with outline
*/
setCollapsedState?(collapsed: boolean): void;
} }
export interface EditableDashboardElementInfo { export interface EditableDashboardElementInfo {

Loading…
Cancel
Save