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
This commit is contained in:
Andrey Goncharov
2023-11-09 05:08:16 -08:00
committed by Facebook GitHub Bot
parent 284dee0460
commit b5cb7fcce2
2 changed files with 130 additions and 20 deletions

View File

@@ -9,7 +9,10 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import {OperatorConfig} from '../PowerSearch'; import {OperatorConfig} from '../PowerSearch';
import {FloatOperatorConfig} from '../PowerSearch/PowerSearchConfig'; import {
EnumLabels,
FloatOperatorConfig,
} from '../PowerSearch/PowerSearchConfig';
export type PowerSearchOperatorProcessor = ( export type PowerSearchOperatorProcessor = (
powerSearchOperatorConfig: OperatorConfig, powerSearchOperatorConfig: OperatorConfig,
@@ -110,38 +113,38 @@ export const dataTablePowerSearchOperators = {
valueType: 'FLOAT', valueType: 'FLOAT',
}), }),
// { [enumValue]: enumLabel } // { [enumValue]: enumLabel }
enum_is: (enumLabels: Record<string, string>) => ({ enum_is: (enumLabels: EnumLabels) => ({
label: 'is', label: 'is',
key: 'enum_is', key: 'enum_is',
valueType: 'ENUM', valueType: 'ENUM',
enumLabels, enumLabels,
}), }),
enum_is_nullish_or: (enumLabels: Record<string, string>) => ({ enum_is_nullish_or: (enumLabels: EnumLabels) => ({
label: 'is nullish or', label: 'is nullish or',
key: 'enum_is_nullish_or', key: 'enum_is_nullish_or',
valueType: 'ENUM', valueType: 'ENUM',
enumLabels, enumLabels,
}), }),
enum_is_not: (enumLabels: Record<string, string>) => ({ enum_is_not: (enumLabels: EnumLabels) => ({
label: 'is not', label: 'is not',
key: 'enum_is_not', key: 'enum_is_not',
valueType: 'ENUM', valueType: 'ENUM',
enumLabels, enumLabels,
}), }),
// TODO: Support logical operations (AND, OR, NOT) to combine primitive operators instead of adding new complex operators! // 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<string, string>) => ({ enum_set_is_nullish_or_any_of: (enumLabels: EnumLabels) => ({
label: 'is nullish or any of', label: 'is nullish or any of',
key: 'enum_set_is_nullish_or_any_of', key: 'enum_set_is_nullish_or_any_of',
valueType: 'ENUM_SET', valueType: 'ENUM_SET',
enumLabels, enumLabels,
}), }),
enum_set_is_any_of: (enumLabels: Record<string, string>) => ({ enum_set_is_any_of: (enumLabels: EnumLabels) => ({
label: 'is any of', label: 'is any of',
key: 'enum_set_is_any_of', key: 'enum_set_is_any_of',
valueType: 'ENUM_SET', valueType: 'ENUM_SET',
enumLabels, enumLabels,
}), }),
enum_set_is_none_of: (enumLabels: Record<string, string>) => ({ enum_set_is_none_of: (enumLabels: EnumLabels) => ({
label: 'is none of', label: 'is none of',
key: 'enum_set_is_none_of', key: 'enum_set_is_none_of',
valueType: 'ENUM_SET', valueType: 'ENUM_SET',

View File

@@ -143,6 +143,36 @@ type DataTableInput<T = any> =
dataSource?: undefined; 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<T = any> = { export type DataTableColumn<T = any> = {
//this can be a dotted path into a nest objects. e.g foo.bar //this can be a dotted path into a nest objects. e.g foo.bar
key: keyof T & string; key: keyof T & string;
@@ -157,18 +187,10 @@ export type DataTableColumn<T = any> = {
inversed?: boolean; inversed?: boolean;
sortable?: boolean; sortable?: boolean;
powerSearchConfig?: powerSearchConfig?:
| PowerSearchSimplifiedConfig
| OperatorConfig[] | OperatorConfig[]
| false | false
| { | 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;
};
}; };
export interface TableRowRenderContext<T = any> { export interface TableRowRenderContext<T = any> {
@@ -287,8 +309,7 @@ export function DataTable<T extends object>(
for (const column of columns) { for (const column of columns) {
if ( if (
typeof column.powerSearchConfig === 'object' && powerSearchConfigIsExtendedConfig(column.powerSearchConfig) &&
!Array.isArray(column.powerSearchConfig) &&
column.powerSearchConfig.inferEnumOptionsFromData column.powerSearchConfig.inferEnumOptionsFromData
) { ) {
if (!secondaryIndeciesKeys.has(column.key)) { if (!secondaryIndeciesKeys.has(column.key)) {
@@ -370,7 +391,7 @@ export function DataTable<T extends object>(
]; ];
} else if (Array.isArray(column.powerSearchConfig)) { } else if (Array.isArray(column.powerSearchConfig)) {
columnPowerSearchOperators = column.powerSearchConfig; columnPowerSearchOperators = column.powerSearchConfig;
} else { } else if (powerSearchConfigIsExtendedConfig(column.powerSearchConfig)) {
columnPowerSearchOperators = column.powerSearchConfig.operators; columnPowerSearchOperators = column.powerSearchConfig.operators;
useWholeRow = !!column.powerSearchConfig.useWholeRow; useWholeRow = !!column.powerSearchConfig.useWholeRow;
@@ -387,6 +408,92 @@ export function DataTable<T extends object>(
}), }),
); );
} }
} 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 = { const columnFieldConfig: FieldConfig = {