Support primitive types in filters (#15402)

When using primitive types such as array, number and boolean, we display
a text field in filters because fieldmetadataId is empty. We should
instead support these as we would do for our own fields.

Adding also a fix for https://github.com/twentyhq/twenty/issues/15282

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
This commit is contained in:
Thomas Trompette
2025-10-28 14:13:10 +00:00
committed by GitHub
co-authored by greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
parent 98b4e8431b
commit da0e5ba342
7 changed files with 75 additions and 12 deletions
@@ -412,7 +412,12 @@ describe('evaluateFilterConditions', () => {
});
it('should handle truthy/falsy conversion', () => {
const filter = createFilter(ViewFilterOperand.IS, 1, true, 'BOOLEAN');
const filter = createFilter(
ViewFilterOperand.IS,
'true',
true,
'BOOLEAN',
);
const result = evaluateFilterConditions({ filters: [filter] });
expect(result).toBe(true);
@@ -11,6 +11,7 @@ import {
type ViewFilterOperandDeprecated,
} from 'twenty-shared/types';
import { convertViewFilterOperandToCoreOperand as convertViewFilterOperandDeprecated } from 'twenty-shared/utils';
import { parseBooleanFromStringValue } from 'twenty-shared/workflow';
import { parseAndEvaluateRelativeDateFilter } from 'src/modules/workflow/workflow-executor/workflow-actions/filter/utils/parse-and-evaluate-relative-date-filter.util';
@@ -43,6 +44,7 @@ function evaluateFilter(
switch (filter.type) {
case 'NUMBER':
case 'NUMERIC':
case 'number':
return evaluateNumberFilter(filterWithConvertedOperand);
case 'DATE':
case 'DATE_TIME':
@@ -55,11 +57,13 @@ function evaluateFilter(
case 'ADDRESS':
case 'LINKS':
case 'ARRAY':
case 'array':
case 'RAW_JSON':
return evaluateTextAndArrayFilter(filterWithConvertedOperand);
case 'SELECT':
return evaluateSelectFilter(filterWithConvertedOperand);
case 'BOOLEAN':
case 'boolean':
return evaluateBooleanFilter(filterWithConvertedOperand);
case 'UUID':
return evaluateUuidFilter(filterWithConvertedOperand);
@@ -168,7 +172,10 @@ function isNotEmptyTextOrArray(value: unknown): boolean {
function evaluateBooleanFilter(filter: ResolvedFilter): boolean {
switch (filter.operand) {
case ViewFilterOperand.IS:
return Boolean(filter.leftOperand) === Boolean(filter.rightOperand);
return (
parseBooleanFromStringValue(filter.leftOperand) ===
parseBooleanFromStringValue(filter.rightOperand)
);
default:
throw new Error(
`Operand ${filter.operand} not supported for boolean filter`,
@@ -263,6 +270,10 @@ function evaluateRelationFilter(filter: ResolvedFilter): boolean {
return leftValue === rightValue;
case ViewFilterOperand.IS_NOT:
return leftValue !== rightValue;
case ViewFilterOperand.IS_EMPTY:
return !isNonEmptyString(leftValue);
case ViewFilterOperand.IS_NOT_EMPTY:
return isNonEmptyString(leftValue);
default:
throw new Error(
`Operand ${filter.operand} not supported for relation filter`,