Power search config for framework event table

Summary: Basic config, added inferred enum support for the event type.

Reviewed By: aigoncharov

Differential Revision: D51113094

fbshipit-source-id: 13acd83e7f7a5d4ee6b62641b13616cc49377e0a
This commit is contained in:
Luke De Feo
2023-11-08 10:30:55 -08:00
committed by Facebook GitHub Bot
parent e461229075
commit 03c2828630
2 changed files with 132 additions and 50 deletions

View File

@@ -9,11 +9,13 @@
import {DeleteOutlined, PartitionOutlined} from '@ant-design/icons'; import {DeleteOutlined, PartitionOutlined} from '@ant-design/icons';
import { import {
DataTable, _DataTableWithPowerSearch as DataTable,
DataTableColumn, DataTableColumn,
DataTableManager,
DetailSidebar, DetailSidebar,
Layout, Layout,
_DataTableColumnWithPowerSearch,
_DataTableWithPowerSearchManager,
dataTablePowerSearchOperators,
usePlugin, usePlugin,
useValue, useValue,
} from 'flipper-plugin'; } from 'flipper-plugin';
@@ -41,9 +43,11 @@ export function FrameworkEventsTable({
const instance = usePlugin(plugin); const instance = usePlugin(plugin);
const focusedNode = useValue(instance.uiState.focusedNode); const focusedNode = useValue(instance.uiState.focusedNode);
const managerRef = useRef<DataTableManager<AugmentedFrameworkEvent> | null>(
null, const managerRef =
); useRef<_DataTableWithPowerSearchManager<AugmentedFrameworkEvent> | null>(
null,
);
useEffect(() => { useEffect(() => {
tracker.track('framework-event-table-opened', {}); tracker.track('framework-event-table-opened', {});
@@ -51,13 +55,31 @@ export function FrameworkEventsTable({
if (nodeId != null) { if (nodeId != null) {
managerRef.current?.resetFilters(); managerRef.current?.resetFilters();
if (isTree) { if (isTree) {
managerRef.current?.addColumnFilter('treeId', nodeId as string, { managerRef.current?.setSearchExpression([
exact: true, {
}); field: {
key: 'treeId',
label: 'TreeId',
},
operator: {
...dataTablePowerSearchOperators.int_equals(),
},
searchValue: nodeId,
},
]);
} else { } else {
managerRef.current?.addColumnFilter('nodeId', nodeId as string, { managerRef.current?.setSearchExpression([
exact: true, {
}); field: {
key: 'nodeId',
label: 'NodeId',
},
operator: {
...dataTablePowerSearchOperators.int_equals(),
},
searchValue: nodeId,
},
]);
} }
} }
}, [instance.uiActions, isTree, nodeId]); }, [instance.uiActions, isTree, nodeId]);
@@ -71,6 +93,7 @@ export function FrameworkEventsTable({
key: customKey, key: customKey,
title: startCase(customKey), title: startCase(customKey),
onRender: (row: AugmentedFrameworkEvent) => row.payload?.[customKey], onRender: (row: AugmentedFrameworkEvent) => row.payload?.[customKey],
powerSearchConfig: enumLikeString,
} as DataTableColumn<AugmentedFrameworkEvent>), } as DataTableColumn<AugmentedFrameworkEvent>),
); );
@@ -135,42 +158,98 @@ export function FrameworkEventsTable({
); );
} }
const staticColumns: DataTableColumn<AugmentedFrameworkEvent>[] = [ const MonoSpace = (t: any) => (
{ <span style={{fontFamily: 'monospace'}}>{t}</span>
key: 'timestamp', );
onRender: (row: FrameworkEvent) => formatTimestampMillis(row.timestamp),
title: 'Timestamp', const stringConfig = [
}, dataTablePowerSearchOperators.string_contains(),
{ dataTablePowerSearchOperators.string_not_contains(),
key: 'type', dataTablePowerSearchOperators.string_matches_exactly(),
title: 'Event type',
onRender: (row: FrameworkEvent) => eventTypeToName(row.type),
},
{
key: 'duration',
title: 'Duration',
onRender: (row: FrameworkEvent) =>
row.duration != null ? formatDuration(row.duration) : null,
},
{
key: 'treeId',
title: 'TreeId',
},
{
key: 'rootComponentName',
title: 'Root component name',
},
{
key: 'nodeId',
title: 'Component ID',
},
{
key: 'nodeName',
title: 'Component name',
},
{
key: 'thread',
title: 'Thread',
onRender: (row: FrameworkEvent) => startCase(row.thread),
},
]; ];
const idConfig = [dataTablePowerSearchOperators.int_equals()];
//todo replace with auto mode
const enumLikeString = [
dataTablePowerSearchOperators.string_matches_exactly(true),
dataTablePowerSearchOperators.string_not_matches_exactly(true),
];
const inferredEnum = [
dataTablePowerSearchOperators.enum_set_is_any_of({}),
dataTablePowerSearchOperators.enum_is({}),
dataTablePowerSearchOperators.enum_set_is_none_of({}),
dataTablePowerSearchOperators.enum_is_not({}),
];
const staticColumns: _DataTableColumnWithPowerSearch<AugmentedFrameworkEvent>[] =
[
{
key: 'timestamp',
sortable: true,
onRender: (row: FrameworkEvent) => formatTimestampMillis(row.timestamp),
title: 'Timestamp',
formatters: MonoSpace,
powerSearchConfig: [
dataTablePowerSearchOperators.newer_than_absolute_date(),
dataTablePowerSearchOperators.older_than_absolute_date(),
],
},
{
key: 'type',
title: 'Event type',
onRender: (row: FrameworkEvent) => eventTypeToName(row.type),
powerSearchConfig: {
inferEnumOptionsFromData: true,
operators: inferredEnum,
},
},
{
key: 'duration',
title: 'Duration (Nanos)',
onRender: (row: FrameworkEvent) =>
row.duration != null ? formatDuration(row.duration) : null,
formatters: MonoSpace,
powerSearchConfig: [
dataTablePowerSearchOperators.int_greater_or_equal(),
dataTablePowerSearchOperators.int_greater_than(),
dataTablePowerSearchOperators.int_equals(),
dataTablePowerSearchOperators.int_less_or_equal(),
dataTablePowerSearchOperators.int_less_than(),
],
},
{
key: 'treeId',
title: 'TreeId',
powerSearchConfig: idConfig,
formatters: MonoSpace,
},
{
key: 'rootComponentName',
title: 'Root component name',
powerSearchConfig: stringConfig,
formatters: MonoSpace,
},
{
key: 'nodeId',
title: 'Component ID',
powerSearchConfig: idConfig,
formatters: MonoSpace,
},
{
key: 'nodeName',
title: 'Component name',
powerSearchConfig: stringConfig,
formatters: MonoSpace,
},
{
key: 'thread',
title: 'Thread',
onRender: (row: FrameworkEvent) => startCase(row.thread),
powerSearchConfig: stringConfig,
formatters: MonoSpace,
},
];

View File

@@ -51,7 +51,10 @@ export function plugin(client: PluginClient<Events, Methods>) {
const snapshot = createState<SnapshotInfo | null>(null); const snapshot = createState<SnapshotInfo | null>(null);
const nodesAtom = createState<Map<Id, ClientNode>>(new Map()); const nodesAtom = createState<Map<Id, ClientNode>>(new Map());
const frameworkEvents = createDataSource<AugmentedFrameworkEvent>([], { const frameworkEvents = createDataSource<AugmentedFrameworkEvent>([], {
indices: [['nodeId']], indices: [
['nodeId'],
['type'], //for inferred values
],
limit: 10000, limit: 10000,
}); });
const frameworkEventsCustomColumns = createState<Set<string>>(new Set()); const frameworkEventsCustomColumns = createState<Set<string>>(new Set());