Add Framework event table
Summary: Very basic framework events table, quite useful for debugging will add more to this soon Reviewed By: lblasa Differential Revision: D47520035 fbshipit-source-id: 10f4572dd4ed3529324f03a969773c7e91fde030
This commit is contained in:
committed by
Facebook GitHub Bot
parent
db7aa9eeaf
commit
4df0ad4d35
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {PartitionOutlined} from '@ant-design/icons';
|
||||
import {
|
||||
DataTable,
|
||||
DataTableColumn,
|
||||
DataTableManager,
|
||||
Layout,
|
||||
usePlugin,
|
||||
} from 'flipper-plugin';
|
||||
import React, {useEffect, useRef} from 'react';
|
||||
import {FrameworkEvent, Id} from '../types';
|
||||
import {plugin} from '../index';
|
||||
import {Button, Tooltip} from 'antd';
|
||||
|
||||
export function FrameworkEventsTable({rootTreeId}: {rootTreeId?: Id}) {
|
||||
const instance = usePlugin(plugin);
|
||||
|
||||
const managerRef = useRef<DataTableManager<FrameworkEvent> | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (rootTreeId != null) {
|
||||
managerRef.current?.resetFilters();
|
||||
managerRef.current?.addColumnFilter('nodeId', rootTreeId as string);
|
||||
}
|
||||
}, [rootTreeId]);
|
||||
|
||||
return (
|
||||
<Layout.Container grow>
|
||||
<DataTable<FrameworkEvent>
|
||||
dataSource={instance.frameworkEvents}
|
||||
tableManagerRef={managerRef}
|
||||
columns={columns}
|
||||
extraActions={
|
||||
<Tooltip title="Back to tree">
|
||||
<Button
|
||||
onClick={() => {
|
||||
instance.uiActions.onSetViewMode({mode: 'default'});
|
||||
}}
|
||||
icon={<PartitionOutlined />}></Button>
|
||||
</Tooltip>
|
||||
}
|
||||
/>
|
||||
</Layout.Container>
|
||||
);
|
||||
}
|
||||
|
||||
const columns: DataTableColumn<FrameworkEvent>[] = [
|
||||
{
|
||||
key: 'timestamp',
|
||||
onRender: (row: FrameworkEvent) => {
|
||||
return new Date(row.timestamp).toLocaleTimeString();
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'nodeId',
|
||||
},
|
||||
{
|
||||
key: 'type',
|
||||
},
|
||||
{
|
||||
key: 'thread',
|
||||
},
|
||||
];
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
Id,
|
||||
OnSelectNode,
|
||||
UINode,
|
||||
ViewMode,
|
||||
} from '../types';
|
||||
import React, {
|
||||
ReactNode,
|
||||
@@ -52,6 +53,7 @@ import {
|
||||
FullscreenExitOutlined,
|
||||
FullscreenOutlined,
|
||||
SnippetsOutlined,
|
||||
TableOutlined,
|
||||
} from '@ant-design/icons';
|
||||
|
||||
const {Text} = Typography;
|
||||
@@ -216,9 +218,11 @@ export function Tree2({nodes, rootId}: {nodes: Map<Id, UINode>; rootId: Id}) {
|
||||
text={searchTerm}
|
||||
highlightColor={theme.searchHighlightBackground.yellow}>
|
||||
<ContextMenu
|
||||
frameworkEvents={instance.frameworkEvents}
|
||||
focusedNodeId={focusedNode}
|
||||
hoveredNodeId={hoveredNode}
|
||||
nodes={nodes}
|
||||
onSetViewMode={instance.uiActions.onSetViewMode}
|
||||
onContextMenuOpen={instance.uiActions.onContextMenuOpen}
|
||||
onFocusNode={instance.uiActions.onFocusNode}>
|
||||
<div
|
||||
@@ -504,18 +508,22 @@ const DecorationImage = styled.img({
|
||||
const renderDepthOffset = 12;
|
||||
|
||||
const ContextMenu: React.FC<{
|
||||
frameworkEvents: DataSource<FrameworkEvent>;
|
||||
nodes: Map<Id, UINode>;
|
||||
hoveredNodeId?: Id;
|
||||
focusedNodeId?: Id;
|
||||
onFocusNode: (id?: Id) => void;
|
||||
onContextMenuOpen: (open: boolean) => void;
|
||||
onSetViewMode: (viewMode: ViewMode) => void;
|
||||
}> = ({
|
||||
nodes,
|
||||
frameworkEvents,
|
||||
hoveredNodeId,
|
||||
children,
|
||||
focusedNodeId,
|
||||
onFocusNode,
|
||||
onContextMenuOpen,
|
||||
onSetViewMode,
|
||||
}) => {
|
||||
const copyItems: ReactNode[] = [];
|
||||
const hoveredNode = nodes.get(hoveredNodeId ?? Number.MAX_SAFE_INTEGER);
|
||||
@@ -579,6 +587,25 @@ const ContextMenu: React.FC<{
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
const matchingFrameworkEvents =
|
||||
(hoveredNode &&
|
||||
frameworkEvents.getAllRecordsByIndex({nodeId: hoveredNode.id})) ??
|
||||
[];
|
||||
|
||||
const frameworkEventsTable = matchingFrameworkEvents.length > 0 && (
|
||||
<UIDebuggerMenuItem
|
||||
text="Explore events"
|
||||
onClick={() => {
|
||||
onSetViewMode({
|
||||
mode: 'frameworkEventsTable',
|
||||
treeRootId: hoveredNode?.id ?? '',
|
||||
});
|
||||
}}
|
||||
icon={<TableOutlined />}
|
||||
/>
|
||||
);
|
||||
|
||||
return (
|
||||
<Dropdown
|
||||
onVisibleChange={(visible) => {
|
||||
@@ -588,8 +615,12 @@ const ContextMenu: React.FC<{
|
||||
<Menu>
|
||||
{focus}
|
||||
{removeFocus}
|
||||
{(focus || removeFocus) && <Menu.Divider key="divider-focus" />}
|
||||
{frameworkEventsTable}
|
||||
{(focus || removeFocus || frameworkEventsTable) && (
|
||||
<Menu.Divider key="divider-focus" />
|
||||
)}
|
||||
{copyItems}
|
||||
|
||||
{hoveredNode && <IDEContextMenuItems key="ide" node={hoveredNode} />}
|
||||
</Menu>
|
||||
)}
|
||||
|
||||
@@ -28,6 +28,7 @@ import {QueryClientProvider} from 'react-query';
|
||||
import {Tree2} from './Tree';
|
||||
import {StreamInterceptorErrorView} from './StreamInterceptorErrorView';
|
||||
import {queryClient} from '../reactQuery';
|
||||
import {FrameworkEventsTable} from './FrameworkEventsTable';
|
||||
|
||||
export function Component() {
|
||||
const instance = usePlugin(plugin);
|
||||
@@ -41,6 +42,7 @@ export function Component() {
|
||||
|
||||
useHotkeys('ctrl+i', () => setShowPerfStats((show) => !show));
|
||||
|
||||
const viewMode = useValue(instance.uiState.viewMode);
|
||||
const [bottomPanelComponent, setBottomPanelComponent] = useState<
|
||||
ReactNode | undefined
|
||||
>();
|
||||
@@ -96,7 +98,12 @@ export function Component() {
|
||||
<Spin data-testid="loading-indicator" />
|
||||
</Centered>
|
||||
);
|
||||
} else {
|
||||
}
|
||||
|
||||
if (viewMode.mode === 'frameworkEventsTable') {
|
||||
return <FrameworkEventsTable rootTreeId={viewMode.treeRootId} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Layout.Container grow padh="small" padv="medium">
|
||||
@@ -139,7 +146,6 @@ export function Component() {
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function Centered(props: {children: React.ReactNode}) {
|
||||
return (
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
UIActions,
|
||||
UINode,
|
||||
UIState,
|
||||
ViewMode,
|
||||
} from './types';
|
||||
import {Draft} from 'immer';
|
||||
import {tracker} from './tracker';
|
||||
@@ -202,6 +203,8 @@ export function plugin(client: PluginClient<Events>) {
|
||||
const uiState: UIState = {
|
||||
isConnected: createState(false),
|
||||
|
||||
viewMode: createState({mode: 'default'}),
|
||||
|
||||
//used to disabled hover effects which cause rerenders and mess up the existing context menu
|
||||
isContextMenuOpen: createState<boolean>(false),
|
||||
|
||||
@@ -461,6 +464,10 @@ function uiActions(uiState: UIState, nodes: Atom<Map<Id, UINode>>): UIActions {
|
||||
uiState.filterMainThreadMonitoring.set(toggled);
|
||||
};
|
||||
|
||||
const onSetViewMode = (viewMode: ViewMode) => {
|
||||
uiState.viewMode.set(viewMode);
|
||||
};
|
||||
|
||||
return {
|
||||
onExpandNode,
|
||||
onCollapseNode,
|
||||
@@ -470,6 +477,7 @@ function uiActions(uiState: UIState, nodes: Atom<Map<Id, UINode>>): UIActions {
|
||||
onFocusNode,
|
||||
setVisualiserWidth,
|
||||
onSetFilterMainThreadMonitoring,
|
||||
onSetViewMode,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
import {Atom} from 'flipper-plugin';
|
||||
|
||||
export type UIState = {
|
||||
viewMode: Atom<ViewMode>;
|
||||
isConnected: Atom<boolean>;
|
||||
isPaused: Atom<boolean>;
|
||||
streamState: Atom<StreamState>;
|
||||
@@ -25,6 +26,10 @@ export type UIState = {
|
||||
filterMainThreadMonitoring: Atom<boolean>;
|
||||
};
|
||||
|
||||
export type ViewMode =
|
||||
| {mode: 'default'}
|
||||
| {mode: 'frameworkEventsTable'; treeRootId: Id};
|
||||
|
||||
export type NodeSelection = {
|
||||
id: Id;
|
||||
source: SelectionSource;
|
||||
@@ -44,7 +49,9 @@ export type UIActions = {
|
||||
onCollapseNode: (node: Id) => void;
|
||||
setVisualiserWidth: (width: number) => void;
|
||||
onSetFilterMainThreadMonitoring: (toggled: boolean) => void;
|
||||
onSetViewMode: (viewMode: ViewMode) => void;
|
||||
};
|
||||
|
||||
export type SelectionSource = 'visualiser' | 'tree' | 'keyboard';
|
||||
|
||||
export type StreamState =
|
||||
|
||||
Reference in New Issue
Block a user