Fix on view filters (#14462)

Fixes https://github.com/twentyhq/twenty/issues/14058
This commit is contained in:
Charles Bochet
2025-09-12 22:45:26 +02:00
committed by GitHub
parent 894e599173
commit 1e97ad48c0
5 changed files with 36 additions and 7 deletions
@@ -16,7 +16,7 @@ import { type ViewFilter } from '@/views/types/ViewFilter';
import { convertViewFilterOperandToCore } from '@/views/utils/convertViewFilterOperandToCore';
import { useApolloClient } from '@apollo/client';
import { isNull } from '@sniptt/guards';
import { isDefined, parseJson } from 'twenty-shared/utils';
import { isDefined } from 'twenty-shared/utils';
import { type CoreViewFilter } from '~/generated/graphql';
export const usePersistViewFilterRecords = () => {
@@ -86,7 +86,7 @@ export const usePersistViewFilterRecords = () => {
variables: {
id: viewFilter.id,
input: {
value: parseJson(viewFilter.value),
value: viewFilter.value,
operand: convertViewFilterOperandToCore(viewFilter.operand),
positionInViewFilterGroup: viewFilter.positionInViewFilterGroup,
viewFilterGroupId: viewFilter.viewFilterGroupId,
@@ -1,3 +1,4 @@
import { FieldMetadataType } from 'twenty-shared/types';
import { capitalize } from 'twenty-shared/utils';
import {
@@ -51,7 +52,10 @@ export class GraphqlQueryOrderFieldParser {
Object.assign(acc, compositeOrder);
} else {
acc[`"${objectNameSingular}"."${key}"`] =
const orderByCasting =
this.getOptionalOrderByCasting(fieldMetadata);
acc[`"${objectNameSingular}"."${key}"${orderByCasting}`] =
this.convertOrderByToFindOptionsOrder(
value as OrderByDirection,
isForwardPagination,
@@ -65,6 +69,19 @@ export class GraphqlQueryOrderFieldParser {
);
}
private getOptionalOrderByCasting(
fieldMetadata: Pick<FieldMetadataEntity, 'type'>,
): string {
if (
fieldMetadata.type === FieldMetadataType.SELECT ||
fieldMetadata.type === FieldMetadataType.MULTI_SELECT
) {
return '::text';
}
return '';
}
private parseCompositeFieldForOrder(
fieldMetadata: FieldMetadataEntity,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -103,9 +103,7 @@ export class FieldMetadataRelatedRecordsService {
);
if (!existingViewGroup) {
throw new Error(
`View group not found for option "${oldOption.value}" during update.`,
);
continue;
}
this.viewGroupService.update(
@@ -6,6 +6,16 @@ describe('parseJson', () => {
expect(result).toBeNull();
});
it('if value is undefined', () => {
const result = parseJson(undefined);
expect(result).toBeNull();
});
it('if value is empty string null', () => {
const result = parseJson('');
expect(result).toBeNull();
});
it('if value is number', () => {
const result = parseJson(123);
expect(result).toBe(123);
@@ -1,11 +1,15 @@
import { isDefined } from "@/utils/validation";
export const parseJson = <T>(rawJson: string | boolean | null | number): T | null => {
export const parseJson = <T>(rawJson: string | boolean | null | number | undefined): T | null => {
try {
if (!isDefined(rawJson)) {
return null;
}
if (rawJson === '') {
return null;
}
// This is a hack to handle the case where the value is a scalar value which is part of JSON spec but not implemented before ES2019
return JSON.parse("[" + rawJson + "]")[0];
} catch {