Add monitored event summary

Summary: When an event is monitored show running total  in the tree

Reviewed By: lblasa

Differential Revision: D42996553

fbshipit-source-id: 9b7bd5d2e98d8775f28b0b541f4eb1bd8231cc3e
This commit is contained in:
Luke De Feo
2023-02-06 04:33:11 -08:00
committed by Facebook GitHub Bot
parent d93c9d45a9
commit 8fc97f2caa

View File

@@ -7,7 +7,7 @@
* @format * @format
*/ */
import {Id, UINode} from '../types'; import {FrameworkEvent, FrameworkEventType, Id, UINode} from '../types';
import React, {Ref, RefObject, useEffect, useMemo, useRef} from 'react'; import React, {Ref, RefObject, useEffect, useMemo, useRef} from 'react';
import { import {
Atom, Atom,
@@ -21,7 +21,7 @@ import {
} from 'flipper-plugin'; } from 'flipper-plugin';
import {plugin} from '../index'; import {plugin} from '../index';
import {Glyph} from 'flipper'; import {Glyph} from 'flipper';
import {head, last} from 'lodash'; import {groupBy, head, last} from 'lodash';
import {reverse} from 'lodash/fp'; import {reverse} from 'lodash/fp';
import {Dropdown, Menu, Typography} from 'antd'; import {Dropdown, Menu, Typography} from 'antd';
import {UIDebuggerMenuItem} from './util/UIDebuggerMenuItem'; import {UIDebuggerMenuItem} from './util/UIDebuggerMenuItem';
@@ -60,6 +60,11 @@ export function Tree2({
const isContextMenuOpen = useValue(instance.uiState.isContextMenuOpen); const isContextMenuOpen = useValue(instance.uiState.isContextMenuOpen);
const hoveredNode = head(useValue(instance.uiState.hoveredNodes)); const hoveredNode = head(useValue(instance.uiState.hoveredNodes));
const frameworkEvents = useValue(instance.frameworkEvents);
const frameworkEventsMonitoring = useValue(
instance.uiState.frameworkEventMonitoring,
);
const {treeNodes, refs} = useMemo(() => { const {treeNodes, refs} = useMemo(() => {
const treeNodes = toTreeNodes( const treeNodes = toTreeNodes(
nodes, nodes,
@@ -119,6 +124,8 @@ export function Tree2({
innerRef={refs[index]} innerRef={refs[index]}
key={treeNode.id} key={treeNode.id}
treeNode={treeNode} treeNode={treeNode}
frameworkEvents={frameworkEvents}
frameworkEventsMonitoring={frameworkEventsMonitoring}
selectedNode={selectedNode} selectedNode={selectedNode}
hoveredNode={hoveredNode} hoveredNode={hoveredNode}
isUsingKBToScroll={isUsingKBToScroll} isUsingKBToScroll={isUsingKBToScroll}
@@ -142,8 +149,10 @@ const MemoTreeItemContainer = React.memo(
return ( return (
prevProps.treeNode === nextProps.treeNode && prevProps.treeNode === nextProps.treeNode &&
prevProps.isContextMenuOpen === nextProps.isContextMenuOpen && prevProps.isContextMenuOpen === nextProps.isContextMenuOpen &&
//make sure that prev or next hover/selected node doesnt concern this tree node prevProps.frameworkEvents === nextProps.frameworkEvents &&
prevProps.hoveredNode !== id && prevProps.frameworkEventsMonitoring ===
nextProps.frameworkEventsMonitoring &&
prevProps.hoveredNode !== id && //make sure that prev or next hover/selected node doesnt concern this tree node
nextProps.hoveredNode !== id && nextProps.hoveredNode !== id &&
prevProps.selectedNode !== id && prevProps.selectedNode !== id &&
nextProps.selectedNode !== id nextProps.selectedNode !== id
@@ -189,6 +198,8 @@ function IndentGuide({indentGuide}: {indentGuide: NodeIndentGuide}) {
function TreeItemContainer({ function TreeItemContainer({
innerRef, innerRef,
treeNode, treeNode,
frameworkEvents,
frameworkEventsMonitoring,
selectedNode, selectedNode,
hoveredNode, hoveredNode,
isUsingKBToScroll, isUsingKBToScroll,
@@ -200,6 +211,8 @@ function TreeItemContainer({
}: { }: {
innerRef: Ref<any>; innerRef: Ref<any>;
treeNode: TreeNode; treeNode: TreeNode;
frameworkEvents: Map<Id, FrameworkEvent[]>;
frameworkEventsMonitoring: Map<FrameworkEventType, boolean>;
selectedNode?: Id; selectedNode?: Id;
hoveredNode?: Id; hoveredNode?: Id;
isUsingKBToScroll: RefObject<boolean>; isUsingKBToScroll: RefObject<boolean>;
@@ -244,6 +257,11 @@ function TreeItemContainer({
{nodeIcon(treeNode)} {nodeIcon(treeNode)}
<HighlightedText text={treeNode.name} /> <HighlightedText text={treeNode.name} />
<InlineAttributes attributes={treeNode.inlineAttributes} /> <InlineAttributes attributes={treeNode.inlineAttributes} />
<MonitoredEventSummary
node={treeNode}
frameworkEvents={frameworkEvents}
frameworkEventsMonitoring={frameworkEventsMonitoring}
/>
</TreeItemContent> </TreeItemContent>
</div> </div>
); );
@@ -256,6 +274,35 @@ const TreeAttributeContainer = styled(Text)({
fontSize: 12, fontSize: 12,
}); });
function MonitoredEventSummary({
node,
frameworkEvents,
frameworkEventsMonitoring,
}: {
node: UINode;
frameworkEvents: Map<Id, FrameworkEvent[]>;
frameworkEventsMonitoring: Map<FrameworkEventType, boolean>;
}) {
const events = frameworkEvents.get(node.id);
if (events) {
return (
<>
{Object.entries(groupBy(events, (e) => e.type))
.filter(([type]) => frameworkEventsMonitoring.get(type))
.map(([key, values]) => (
<TreeAttributeContainer key={key}>
<span style={{color: theme.errorColor}}>
{last(key.split(':'))}
</span>
<span>={values.length}</span>
</TreeAttributeContainer>
))}
</>
);
}
return null;
}
function InlineAttributes({attributes}: {attributes: Record<string, string>}) { function InlineAttributes({attributes}: {attributes: Record<string, string>}) {
const highlightManager: HighlightManager = useHighlighter(); const highlightManager: HighlightManager = useHighlighter();
@@ -326,7 +373,7 @@ function ExpandedIconOrSpace(props: {
function HighlightedText(props: {text: string}) { function HighlightedText(props: {text: string}) {
const highlightManager: HighlightManager = useHighlighter(); const highlightManager: HighlightManager = useHighlighter();
return <span>{highlightManager.render(props.text)}</span>; return <span>{highlightManager.render(props.text)} </span>;
} }
function nodeIcon(node: UINode) { function nodeIcon(node: UINode) {