/** * 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 dayjs from 'dayjs'; import {OperatorConfig} from '../PowerSearch'; import {FloatOperatorConfig} from '../PowerSearch/PowerSearchConfig'; export type PowerSearchOperatorProcessor = ( powerSearchOperatorConfig: OperatorConfig, searchValue: any, value: any, ) => boolean; export const dataTablePowerSearchOperators = { string_contains: () => ({ label: 'contains', key: 'string_contains', valueType: 'STRING', }), string_not_contains: () => ({ label: 'does not contain', key: 'string_not_contains', valueType: 'STRING', }), string_matches_exactly: () => ({ label: 'is', key: 'string_matches_exactly', valueType: 'STRING', }), string_not_matches_exactly: () => ({ label: 'is not', key: 'string_not_matches_exactly', valueType: 'STRING', }), string_set_contains_any_of: () => ({ label: 'contains any of', key: 'string_set_contains_any_of', valueType: 'STRING_SET', }), string_set_contains_none_of: () => ({ label: 'contains none of', key: 'string_set_contains_none_of', valueType: 'STRING_SET', }), int_equals: () => ({ label: '=', key: 'int_equals', valueType: 'INTEGER', }), int_greater_than: () => ({ label: '>', key: 'int_greater_than', valueType: 'INTEGER', }), int_greater_or_equal: () => ({ label: '>=', key: 'int_greater_or_equal', valueType: 'INTEGER', }), int_less_than: () => ({ label: '<', key: 'int_less_than', valueType: 'INTEGER', }), int_less_or_equal: () => ({ label: '<=', key: 'int_less_or_equal', valueType: 'INTEGER', }), float_equals: (precision: number) => ({ label: '=', key: 'float_equals', valueType: 'FLOAT', precision, }), float_greater_than: () => ({ label: '>', key: 'float_greater_than', valueType: 'FLOAT', }), float_greater_or_equal: () => ({ label: '>=', key: 'float_greater_or_equal', valueType: 'FLOAT', }), float_less_than: () => ({ label: '<', key: 'float_less_than', valueType: 'FLOAT', }), float_less_or_equal: () => ({ label: '<=', key: 'float_less_or_equal', valueType: 'FLOAT', }), // { [enumValue]: enumLabel } enum_is: (enumLabels: Record) => ({ label: 'is', key: 'enum_is', valueType: 'ENUM', enumLabels, }), enum_is_not: (enumLabels: Record) => ({ label: 'is not', key: 'enum_is_not', valueType: 'ENUM', enumLabels, }), enum_set_is_any_of: (enumLabels: Record) => ({ label: 'is any of', key: 'enum_set_is_any_of', valueType: 'ENUM_SET', enumLabels, }), enum_set_is_none_of: (enumLabels: Record) => ({ label: 'is none of', key: 'enum_set_is_none_of', valueType: 'ENUM_SET', enumLabels, }), is_nullish: () => ({ label: 'is nullish', key: 'is_nullish', valueType: 'NO_VALUE', }), newer_than_absolute_date: () => ({ key: 'newer_than_absolute_date', label: 'is after', valueType: 'ABSOLUTE_DATE', dateOnly: false, }), newer_than_absolute_date_no_time: () => ({ key: 'newer_than_absolute_date_no_time', label: 'is after the day', valueType: 'ABSOLUTE_DATE', dateOnly: true, }), older_than_absolute_date: () => ({ key: 'older_than_absolute_date', label: 'is before', valueType: 'ABSOLUTE_DATE', dateOnly: false, }), older_than_absolute_date_no_time: () => ({ key: 'older_than_absolute_date_no_time', label: 'is before the day', valueType: 'ABSOLUTE_DATE', dateOnly: true, }), } satisfies { [key: string]: (...args: any[]) => OperatorConfig; }; export type PowerSearchOperatorProcessorConfig = { [K in keyof typeof dataTablePowerSearchOperators]: PowerSearchOperatorProcessor; }; export const dataTablePowerSearchOperatorProcessorConfig = { string_contains: (_operator, searchValue: string, value: string) => value.toLowerCase().includes(searchValue.toLowerCase()), string_not_contains: (_operator, searchValue: string, value: string) => !value.toLowerCase().includes(searchValue.toLowerCase()), string_matches_exactly: (_operator, searchValue: string, value: string) => value === searchValue, string_not_matches_exactly: (_operator, searchValue: string, value: string) => value !== searchValue, // See PowerSearchStringSetTerm string_set_contains_any_of: ( _operator, searchValue: string[], value: string, ) => searchValue.some((item) => value.toLowerCase().includes(item.toLowerCase()), ), string_set_contains_none_of: ( _operator, searchValue: string[], value: string, ) => !searchValue.some((item) => value.toLowerCase().includes(item.toLowerCase()), ), int_equals: (_operator, searchValue: number, value: number) => value === searchValue, int_greater_than: (_operator, searchValue: number, value: number) => value > searchValue, int_greater_or_equal: (_operator, searchValue: number, value: number) => value >= searchValue, int_less_than: (_operator, searchValue: number, value: number) => value < searchValue, int_less_or_equal: (_operator, searchValue: number, value: number) => value <= searchValue, float_equals: (operator, searchValue: number, value: number) => { const precision = (operator as FloatOperatorConfig).precision ?? 0.01; return value <= searchValue + precision && value >= searchValue - precision; }, float_greater_than: (_operator, searchValue: number, value: number) => value > searchValue, float_greater_or_equal: (_operator, searchValue: number, value: number) => value >= searchValue, float_less_than: (_operator, searchValue: number, value: number) => value < searchValue, float_less_or_equal: (_operator, searchValue: number, value: number) => value <= searchValue, enum_is: (_operator, searchValue: string, value: string) => searchValue === value, enum_is_not: (_operator, searchValue: string, value: string) => searchValue !== value, enum_set_is_any_of: (_operator, searchValue: string[], value: string) => searchValue.some((item) => value === item), enum_set_is_none_of: (_operator, searchValue: string[], value: string) => !searchValue.some((item) => value === item), is_nullish: (_operator, _searchValue, value) => value == null, // See PowerSearchAbsoluteDateTerm newer_than_absolute_date: (_operator, searchValue: Date, value: any) => { const valueNormalized = dayjs(value); return valueNormalized.isAfter(searchValue); }, newer_than_absolute_date_no_time: ( _operator, searchValue: Date, value: any, ) => { const valueNormalized = dayjs(value); return valueNormalized.isAfter(searchValue); }, older_than_absolute_date: (_operator, searchValue: Date, value: any) => { const valueNormalized = dayjs(value); return valueNormalized.isBefore(searchValue); }, older_than_absolute_date_no_time: ( _operator, searchValue: Date, value: any, ) => { const valueNormalized = dayjs(value); return valueNormalized.isBefore(searchValue); }, } satisfies PowerSearchOperatorProcessorConfig;