From b5cb7fcce21fe375f16a5c4019d5176dbe563d29 Mon Sep 17 00:00:00 2001 From: Andrey Goncharov Date: Thu, 9 Nov 2023 05:08:16 -0800 Subject: [PATCH] Support simplified power search config Summary: It is quite cumbersome to list all of the operators. Much simpler to use a predefined set of power search operators we set up for each specific filed type Reviewed By: lblasa Differential Revision: D51116029 fbshipit-source-id: 5dd0b7f4176097109666107dfc3cab996379b818 --- .../DataTableDefaultPowerSearchOperators.tsx | 17 ++- .../data-table/DataTableWithPowerSearch.tsx | 133 ++++++++++++++++-- 2 files changed, 130 insertions(+), 20 deletions(-) diff --git a/desktop/flipper-plugin/src/ui/data-table/DataTableDefaultPowerSearchOperators.tsx b/desktop/flipper-plugin/src/ui/data-table/DataTableDefaultPowerSearchOperators.tsx index 82384ad18..6b8d8d250 100644 --- a/desktop/flipper-plugin/src/ui/data-table/DataTableDefaultPowerSearchOperators.tsx +++ b/desktop/flipper-plugin/src/ui/data-table/DataTableDefaultPowerSearchOperators.tsx @@ -9,7 +9,10 @@ import dayjs from 'dayjs'; import {OperatorConfig} from '../PowerSearch'; -import {FloatOperatorConfig} from '../PowerSearch/PowerSearchConfig'; +import { + EnumLabels, + FloatOperatorConfig, +} from '../PowerSearch/PowerSearchConfig'; export type PowerSearchOperatorProcessor = ( powerSearchOperatorConfig: OperatorConfig, @@ -110,38 +113,38 @@ export const dataTablePowerSearchOperators = { valueType: 'FLOAT', }), // { [enumValue]: enumLabel } - enum_is: (enumLabels: Record) => ({ + enum_is: (enumLabels: EnumLabels) => ({ label: 'is', key: 'enum_is', valueType: 'ENUM', enumLabels, }), - enum_is_nullish_or: (enumLabels: Record) => ({ + enum_is_nullish_or: (enumLabels: EnumLabels) => ({ label: 'is nullish or', key: 'enum_is_nullish_or', valueType: 'ENUM', enumLabels, }), - enum_is_not: (enumLabels: Record) => ({ + enum_is_not: (enumLabels: EnumLabels) => ({ label: 'is not', key: 'enum_is_not', valueType: 'ENUM', enumLabels, }), // TODO: Support logical operations (AND, OR, NOT) to combine primitive operators instead of adding new complex operators! - enum_set_is_nullish_or_any_of: (enumLabels: Record) => ({ + enum_set_is_nullish_or_any_of: (enumLabels: EnumLabels) => ({ label: 'is nullish or any of', key: 'enum_set_is_nullish_or_any_of', valueType: 'ENUM_SET', enumLabels, }), - enum_set_is_any_of: (enumLabels: Record) => ({ + enum_set_is_any_of: (enumLabels: EnumLabels) => ({ label: 'is any of', key: 'enum_set_is_any_of', valueType: 'ENUM_SET', enumLabels, }), - enum_set_is_none_of: (enumLabels: Record) => ({ + enum_set_is_none_of: (enumLabels: EnumLabels) => ({ label: 'is none of', key: 'enum_set_is_none_of', valueType: 'ENUM_SET', diff --git a/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearch.tsx b/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearch.tsx index 6082a1f14..e2a38c57e 100644 --- a/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearch.tsx +++ b/desktop/flipper-plugin/src/ui/data-table/DataTableWithPowerSearch.tsx @@ -143,6 +143,36 @@ type DataTableInput = dataSource?: undefined; }; +type PowerSearchSimplifiedConfig = + | {type: 'enum'; enumLabels: EnumLabels} + | {type: 'int'} + | {type: 'float'} + | {type: 'string'} + | {type: 'date'} + | {type: 'dateTime'} + | {type: 'object'}; +type PowerSearchExtendedConfig = { + operators: OperatorConfig[]; + useWholeRow?: boolean; + /** + * Auto-generate enum options based on the data. + * Requires the column to be set as a secondary "index" (single column, not a compound multi-column index). + * See https://fburl.com/code/0waicx6p + */ + inferEnumOptionsFromData?: boolean; +}; + +const powerSearchConfigIsExtendedConfig = ( + powerSearchConfig: + | undefined + | PowerSearchSimplifiedConfig + | OperatorConfig[] + | false + | PowerSearchExtendedConfig, +): powerSearchConfig is PowerSearchExtendedConfig => + !!powerSearchConfig && + Array.isArray((powerSearchConfig as PowerSearchExtendedConfig).operators); + export type DataTableColumn = { //this can be a dotted path into a nest objects. e.g foo.bar key: keyof T & string; @@ -157,18 +187,10 @@ export type DataTableColumn = { inversed?: boolean; sortable?: boolean; powerSearchConfig?: + | PowerSearchSimplifiedConfig | OperatorConfig[] | false - | { - operators: OperatorConfig[]; - useWholeRow?: boolean; - /** - * Auto-generate enum options based on the data. - * Requires the column to be set as a secondary "index" (single column, not a compound multi-column index). - * See https://fburl.com/code/0waicx6p - */ - inferEnumOptionsFromData?: boolean; - }; + | PowerSearchExtendedConfig; }; export interface TableRowRenderContext { @@ -287,8 +309,7 @@ export function DataTable( for (const column of columns) { if ( - typeof column.powerSearchConfig === 'object' && - !Array.isArray(column.powerSearchConfig) && + powerSearchConfigIsExtendedConfig(column.powerSearchConfig) && column.powerSearchConfig.inferEnumOptionsFromData ) { if (!secondaryIndeciesKeys.has(column.key)) { @@ -370,7 +391,7 @@ export function DataTable( ]; } else if (Array.isArray(column.powerSearchConfig)) { columnPowerSearchOperators = column.powerSearchConfig; - } else { + } else if (powerSearchConfigIsExtendedConfig(column.powerSearchConfig)) { columnPowerSearchOperators = column.powerSearchConfig.operators; useWholeRow = !!column.powerSearchConfig.useWholeRow; @@ -387,6 +408,92 @@ export function DataTable( }), ); } + } else { + switch (column.powerSearchConfig.type) { + case 'date': { + columnPowerSearchOperators = [ + dataTablePowerSearchOperators.same_as_absolute_date_no_time(), + dataTablePowerSearchOperators.older_than_absolute_date_no_time(), + dataTablePowerSearchOperators.newer_than_absolute_date_no_time(), + ]; + break; + } + case 'dateTime': { + columnPowerSearchOperators = [ + dataTablePowerSearchOperators.older_than_absolute_date(), + dataTablePowerSearchOperators.newer_than_absolute_date(), + ]; + break; + } + case 'string': { + columnPowerSearchOperators = [ + dataTablePowerSearchOperators.string_contains(), + dataTablePowerSearchOperators.string_not_contains(), + dataTablePowerSearchOperators.string_matches_exactly(), + dataTablePowerSearchOperators.string_not_matches_exactly(), + dataTablePowerSearchOperators.string_set_contains_any_of(), + dataTablePowerSearchOperators.string_set_contains_none_of(), + ]; + break; + } + case 'int': { + columnPowerSearchOperators = [ + dataTablePowerSearchOperators.int_equals(), + dataTablePowerSearchOperators.int_greater_or_equal(), + dataTablePowerSearchOperators.int_greater_than(), + dataTablePowerSearchOperators.int_less_or_equal(), + dataTablePowerSearchOperators.int_less_than(), + ]; + break; + } + case 'float': { + columnPowerSearchOperators = [ + dataTablePowerSearchOperators.float_equals(), + dataTablePowerSearchOperators.float_greater_or_equal(), + dataTablePowerSearchOperators.float_greater_than(), + dataTablePowerSearchOperators.float_less_or_equal(), + dataTablePowerSearchOperators.float_less_than(), + ]; + break; + } + case 'enum': { + columnPowerSearchOperators = [ + dataTablePowerSearchOperators.enum_is( + column.powerSearchConfig.enumLabels, + ), + dataTablePowerSearchOperators.enum_is_not( + column.powerSearchConfig.enumLabels, + ), + dataTablePowerSearchOperators.enum_is_nullish_or( + column.powerSearchConfig.enumLabels, + ), + dataTablePowerSearchOperators.enum_set_is_any_of( + column.powerSearchConfig.enumLabels, + ), + dataTablePowerSearchOperators.enum_set_is_none_of( + column.powerSearchConfig.enumLabels, + ), + dataTablePowerSearchOperators.enum_set_is_nullish_or_any_of( + column.powerSearchConfig.enumLabels, + ), + ]; + break; + } + case 'object': { + columnPowerSearchOperators = [ + dataTablePowerSearchOperators.searializable_object_contains(), + dataTablePowerSearchOperators.searializable_object_not_contains(), + ]; + break; + } + default: { + throw new Error( + `Unknown power search config type ${JSON.stringify( + column.powerSearchConfig, + )}`, + ); + } + } } const columnFieldConfig: FieldConfig = {