Record filter greaterThan becomes inclusive as lowerThan (#12786)

# Introduction
Greater than filtering wasn't inclusive whereas lower than was,
resulting in sending empty array to filtering resolver

Also refactored the transpilation methods to avoid asserting on the
`RATING_VALUES` order

closes https://github.com/twentyhq/twenty/issues/12779
This commit is contained in:
Paul Rastoin
2025-06-23 17:15:30 +02:00
committed by GitHub
parent facd2fe26f
commit b6787c6fcd
3 changed files with 21 additions and 25 deletions

View File

@ -5,6 +5,7 @@ import { RatingInput } from '@/ui/field/input/components/RatingInput';
import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue'; import { useApplyObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useApplyObjectFilterDropdownFilterValue';
import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue'; import { useObjectFilterDropdownFilterValue } from '@/object-record/object-filter-dropdown/hooks/useObjectFilterDropdownFilterValue';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { isDefined } from 'twenty-shared/utils';
const StyledRatingInputContainer = styled.div` const StyledRatingInputContainer = styled.div`
padding: ${({ theme }) => theme.spacing(2)}; padding: ${({ theme }) => theme.spacing(2)};
@ -12,25 +13,24 @@ const StyledRatingInputContainer = styled.div`
const convertFieldRatingValueToNumber = ( const convertFieldRatingValueToNumber = (
rating: Exclude<FieldRatingValue, null>, rating: Exclude<FieldRatingValue, null>,
): string => { ): string => rating.split('_')[1];
return rating.split('_')[1];
};
export const convertGreaterThanRatingToArrayOfRatingValues = ( export const convertGreaterThanRatingToArrayOfRatingValues = (
greaterThanValue: number, greaterThanValue: number,
) => { ) =>
return RATING_VALUES.filter((_, index) => index + 1 > greaterThanValue); RATING_VALUES.filter(
}; (ratingValue) => +ratingValue.split('_')[1] >= greaterThanValue,
);
export const convertLessThanRatingToArrayOfRatingValues = ( export const convertLessThanRatingToArrayOfRatingValues = (
lessThanValue: number, lessThanValue: number,
) => { ) =>
return RATING_VALUES.filter((_, index) => index + 1 <= lessThanValue); RATING_VALUES.filter(
}; (ratingValue) => +ratingValue.split('_')[1] <= lessThanValue,
);
export const convertRatingToRatingValue = (rating: number) => { export const convertRatingToRatingValue = (rating: number) =>
return `RATING_${rating}` as FieldRatingValue; `RATING_${rating}` as FieldRatingValue;
};
export const ObjectFilterDropdownRatingInput = () => { export const ObjectFilterDropdownRatingInput = () => {
const { applyObjectFilterDropdownFilterValue } = const { applyObjectFilterDropdownFilterValue } =
@ -50,9 +50,11 @@ export const ObjectFilterDropdownRatingInput = () => {
applyObjectFilterDropdownFilterValue(ratingValueConverted); applyObjectFilterDropdownFilterValue(ratingValueConverted);
}; };
const currentFilterValueConvertedToRatingValue = convertRatingToRatingValue( const currentFilterValueConvertedToRatingValue = isDefined(
Number(objectFilterDropdownFilterValue), objectFilterDropdownFilterValue,
); )
? convertRatingToRatingValue(Number(objectFilterDropdownFilterValue))
: null;
return ( return (
<StyledRatingInputContainer> <StyledRatingInputContainer>

View File

@ -1,11 +1,8 @@
import { z } from 'zod';
import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues'; import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues';
import { FieldRatingValue } from '../FieldMetadata'; import { FieldRatingValue } from '../FieldMetadata';
const ratingSchema = z.string().pipe(z.enum(RATING_VALUES));
export const isFieldRatingValue = ( export const isFieldRatingValue = (
fieldValue: unknown, fieldValue: unknown,
): fieldValue is FieldRatingValue => ratingSchema.safeParse(fieldValue).success; ): fieldValue is FieldRatingValue =>
RATING_VALUES.includes(fieldValue as NonNullable<FieldRatingValue>);

View File

@ -1,4 +1,5 @@
import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues'; import { RATING_VALUES } from '@/object-record/record-field/meta-types/constants/RatingValues';
import { isFieldRatingValue } from '@/object-record/record-field/types/guards/isFieldRatingValue';
import { emailSchema } from '@/object-record/record-field/validation-schemas/emailSchema'; import { emailSchema } from '@/object-record/record-field/validation-schemas/emailSchema';
import { SpreadsheetImportFieldValidationDefinition } from '@/spreadsheet-import/types'; import { SpreadsheetImportFieldValidationDefinition } from '@/spreadsheet-import/types';
import { t } from '@lingui/core/macro'; import { t } from '@lingui/core/macro';
@ -221,11 +222,7 @@ export const getSpreadSheetFieldValidationDefinitions = (
return [ return [
{ {
rule: 'function', rule: 'function',
isValid: (value: string) => { isValid: isFieldRatingValue,
return RATING_VALUES.includes(
value as (typeof RATING_VALUES)[number],
);
},
errorMessage: `${fieldName} ${t` must be one of ${ratingValues} values`}`, errorMessage: `${fieldName} ${t` must be one of ${ratingValues} values`}`,
level: 'error', level: 'error',
}, },