Make as manything as inferred enum as possible

changelog: [Logs] Improve power search config to populate dropdown for level, PID & Tag

Reviewed By: aigoncharov

Differential Revision: D51199644

fbshipit-source-id: 383b61abca5d91a8e318bbfb1aac7d3852074167
This commit is contained in:
Luke De Feo
2023-11-13 04:43:05 -08:00
committed by Facebook GitHub Bot
parent a400eb2872
commit 4ada8b9322
2 changed files with 66 additions and 15 deletions

View File

@@ -57,6 +57,7 @@ test('it will merge equal rows', () => {
"date": 2021-01-28T17:15:12.859Z, "date": 2021-01-28T17:15:12.859Z,
"message": "test1", "message": "test1",
"pid": 0, "pid": 0,
"pidStr": "0",
"tag": "test", "tag": "test",
"tid": 1, "tid": 1,
"type": "error", "type": "error",
@@ -67,6 +68,7 @@ test('it will merge equal rows', () => {
"date": 2021-01-28T17:15:17.859Z, "date": 2021-01-28T17:15:17.859Z,
"message": "test2", "message": "test2",
"pid": 2, "pid": 2,
"pidStr": "2",
"tag": "test", "tag": "test",
"tid": 3, "tid": 3,
"type": "warn", "type": "warn",
@@ -77,6 +79,7 @@ test('it will merge equal rows', () => {
"date": 2021-01-28T17:15:12.859Z, "date": 2021-01-28T17:15:12.859Z,
"message": "test3", "message": "test3",
"pid": 0, "pid": 0,
"pidStr": "0",
"tag": "test", "tag": "test",
"tid": 1, "tid": 1,
"type": "error", "type": "error",
@@ -103,9 +106,12 @@ test('it supports deeplink and select nodes + navigating to bottom', async () =>
await sleep(1000); await sleep(1000);
expect(instance.tableManagerRef.current?.getSelectedItems()).toEqual([ const current = instance.tableManagerRef.current;
console.error('ref', current);
expect(current?.getSelectedItems()).toEqual([
{ {
...entry2, ...entry2,
pidStr: '2',
count: 1, count: 1,
}, },
]); ]);
@@ -116,6 +122,7 @@ test('it supports deeplink and select nodes + navigating to bottom', async () =>
expect(instance.tableManagerRef.current?.getSelectedItems()).toEqual([ expect(instance.tableManagerRef.current?.getSelectedItems()).toEqual([
{ {
...entry3, ...entry3,
pidStr: '0',
count: 1, count: 1,
}, },
]); ]);
@@ -138,6 +145,7 @@ test('export / import plugin does work', async () => {
"date": 2021-01-28T17:15:12.859Z, "date": 2021-01-28T17:15:12.859Z,
"message": "test1", "message": "test1",
"pid": 0, "pid": 0,
"pidStr": "0",
"tag": "test", "tag": "test",
"tid": 1, "tid": 1,
"type": "error", "type": "error",
@@ -148,6 +156,7 @@ test('export / import plugin does work', async () => {
"date": 2021-01-28T17:15:17.859Z, "date": 2021-01-28T17:15:17.859Z,
"message": "test2", "message": "test2",
"pid": 2, "pid": 2,
"pidStr": "2",
"tag": "test", "tag": "test",
"tid": 3, "tid": 3,
"type": "warn", "type": "warn",

View File

@@ -12,13 +12,16 @@ import {
DeviceLogEntry, DeviceLogEntry,
usePlugin, usePlugin,
createDataSource, createDataSource,
DataTableColumn, dataTablePowerSearchOperators,
_DataTableColumnWithPowerSearch,
_DataTableWithPowerSearch,
theme, theme,
DataTableManager, _DataTableWithPowerSearchManager,
createState, createState,
useValue, useValue,
DataFormatter, DataFormatter,
DataTable, EnumLabels,
SearchExpressionTerm,
} from 'flipper-plugin'; } from 'flipper-plugin';
import { import {
PlayCircleOutlined, PlayCircleOutlined,
@@ -32,28 +35,31 @@ import {baseRowStyle, logTypes} from './logTypes';
export type ExtendedLogEntry = DeviceLogEntry & { export type ExtendedLogEntry = DeviceLogEntry & {
count: number; count: number;
pidStr: string; //for the purposes of inferring (only supports string type)
}; };
const logLevelEnumLabels = Object.entries(logTypes).reduce(
(res, [key, {label}]) => {
res[key] = label;
return res;
},
{} as EnumLabels,
);
function createColumnConfig( function createColumnConfig(
_os: 'iOS' | 'Android' | 'Metro', _os: 'iOS' | 'Android' | 'Metro',
): DataTableColumn<ExtendedLogEntry>[] { ): _DataTableColumnWithPowerSearch<ExtendedLogEntry>[] {
return [ return [
{ {
key: 'type', key: 'type',
title: '', title: 'Level',
width: 30, width: 30,
filters: Object.entries(logTypes).map(([value, config]) => ({
label: config.label,
value,
enabled: config.enabled,
})),
onRender(entry) { onRender(entry) {
return entry.count > 1 ? ( return entry.count > 1 ? (
<Badge <Badge
count={entry.count} count={entry.count}
size="small" size="small"
style={{ style={{
marginTop: 4,
color: theme.white, color: theme.white,
background: background:
(logTypes[entry.type]?.style as any)?.color ?? (logTypes[entry.type]?.style as any)?.color ??
@@ -64,6 +70,12 @@ function createColumnConfig(
logTypes[entry.type]?.icon logTypes[entry.type]?.icon
); );
}, },
powerSearchConfig: {
operators: [
dataTablePowerSearchOperators.enum_set_is_any_of(logLevelEnumLabels),
dataTablePowerSearchOperators.enum_set_is_none_of(logLevelEnumLabels),
],
},
}, },
{ {
key: 'date', key: 'date',
@@ -71,10 +83,11 @@ function createColumnConfig(
width: 120, width: 120,
}, },
{ {
key: 'pid', key: 'pidStr',
title: 'PID', title: 'PID',
width: 60, width: 60,
visible: true, visible: true,
powerSearchConfig: enumPowerSearchConfig,
}, },
{ {
key: 'tid', key: 'tid',
@@ -86,6 +99,7 @@ function createColumnConfig(
key: 'tag', key: 'tag',
title: 'Tag', title: 'Tag',
width: 160, width: 160,
powerSearchConfig: enumPowerSearchConfig,
}, },
{ {
key: 'app', key: 'app',
@@ -106,22 +120,47 @@ function createColumnConfig(
]; ];
} }
const enumPowerSearchConfig = {
inferEnumOptionsFromData: true,
operators: [
dataTablePowerSearchOperators.enum_set_is_any_of({}),
dataTablePowerSearchOperators.enum_set_is_none_of({}),
],
};
function getRowStyle(entry: DeviceLogEntry): CSSProperties | undefined { function getRowStyle(entry: DeviceLogEntry): CSSProperties | undefined {
return (logTypes[entry.type]?.style as any) ?? baseRowStyle; return (logTypes[entry.type]?.style as any) ?? baseRowStyle;
} }
const powerSearchInitialState: SearchExpressionTerm[] = [
{
field: {
key: 'type',
label: 'Level',
},
operator:
dataTablePowerSearchOperators.enum_set_is_any_of(logLevelEnumLabels),
searchValue: Object.entries(logTypes)
.filter(([_, item]) => item.enabled)
.map(([key]) => key),
},
];
export function devicePlugin(client: DevicePluginClient) { export function devicePlugin(client: DevicePluginClient) {
const rows = createDataSource<ExtendedLogEntry>([], { const rows = createDataSource<ExtendedLogEntry>([], {
limit: 200000, limit: 200000,
persist: 'logs', persist: 'logs',
indices: [['pid'], ['tag']], //there are for inferring enum types
}); });
const isPaused = createState(true); const isPaused = createState(true);
const tableManagerRef = createRef< const tableManagerRef = createRef<
undefined | DataTableManager<ExtendedLogEntry> undefined | _DataTableWithPowerSearchManager<ExtendedLogEntry>
>(); >();
client.onDeepLink((payload: unknown) => { client.onDeepLink((payload: unknown) => {
if (typeof payload === 'string') { if (typeof payload === 'string') {
tableManagerRef.current?.setSearchExpression(powerSearchInitialState);
// timeout as we want to await restoring any previous scroll positin first, then scroll to the // timeout as we want to await restoring any previous scroll positin first, then scroll to the
setTimeout(() => { setTimeout(() => {
let hasMatch = false; let hasMatch = false;
@@ -168,11 +207,13 @@ export function devicePlugin(client: DevicePluginClient) {
) { ) {
rows.update(lastIndex, { rows.update(lastIndex, {
...previousRow, ...previousRow,
pidStr: previousRow.pid.toString(),
count: previousRow.count + 1, count: previousRow.count + 1,
}); });
} else { } else {
rows.append({ rows.append({
...entry, ...entry,
pidStr: entry.pid.toString(),
count: 1, count: 1,
}); });
} }
@@ -225,7 +266,7 @@ export function Component() {
const plugin = usePlugin(devicePlugin); const plugin = usePlugin(devicePlugin);
const paused = useValue(plugin.isPaused); const paused = useValue(plugin.isPaused);
return ( return (
<DataTable<ExtendedLogEntry> <_DataTableWithPowerSearch<ExtendedLogEntry>
dataSource={plugin.rows} dataSource={plugin.rows}
columns={plugin.columns} columns={plugin.columns}
enableAutoScroll enableAutoScroll
@@ -248,6 +289,7 @@ export function Component() {
) : undefined ) : undefined
} }
tableManagerRef={plugin.tableManagerRef} tableManagerRef={plugin.tableManagerRef}
powerSearchInitialState={powerSearchInitialState}
/> />
); );
} }