Fix missing datetime filter type (#21451)

Currently datetime fields are only typed to be filtered by string

Add a proper typing to match gql filters

## Before
<img width="750" height="492" alt="image"
src="https://github.com/user-attachments/assets/ff3a5423-3bb0-4295-84c9-e404489354f6"
/>

## After
<img width="537" height="511" alt="image"
src="https://github.com/user-attachments/assets/d8c8219f-b7de-41b0-96cb-5adbfda7a91d"
/>
This commit is contained in:
martmull
2026-06-11 15:47:08 +02:00
committed by GitHub
parent 0ac4f237c0
commit d0884bd708
5 changed files with 80 additions and 4 deletions
@@ -25,12 +25,12 @@ describe('PostCard object', () => {
const { objects } = await client.query({
objects: {
__args: { paging: { first: 50 } },
__args: { paging: { first: 50 }, filter: {} },
edges: {
node: {
nameSingular: true,
fields: {
__args: { paging: { first: 500 } },
__args: { paging: { first: 500 }, filter: {} },
edges: { node: { name: true } },
},
},
@@ -39,13 +39,14 @@ describe('PostCard object', () => {
});
const obj = objects.edges
.map((e: { node: { nameSingular: string } }) => e.node)
.map((e) => e.node)
.find((n: { nameSingular: string }) => n.nameSingular === 'postCard');
expect(obj).toBeDefined();
const names = obj!.fields.edges.map(
(e: { node: { name: string } }) => e.node.name,
);
console.log('names', names);
expect(names).toContain('name');
expect(names).toContain('content');
expect(names).toContain('status');
@@ -0,0 +1,19 @@
import { GraphQLISODateTime } from '@nestjs/graphql';
import { GraphQLInputObjectType, GraphQLList, GraphQLNonNull } from 'graphql';
import { FilterIs } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/input/filter-is.input-type';
export const DateTimeFilterType = new GraphQLInputObjectType({
name: 'DateTimeFilter',
fields: {
eq: { type: GraphQLISODateTime },
gt: { type: GraphQLISODateTime },
gte: { type: GraphQLISODateTime },
in: { type: new GraphQLList(new GraphQLNonNull(GraphQLISODateTime)) },
lt: { type: GraphQLISODateTime },
lte: { type: GraphQLISODateTime },
neq: { type: GraphQLISODateTime },
is: { type: FilterIs },
},
});
@@ -3,6 +3,7 @@ export * from './big-float-filter.input-type';
export * from './big-int-filter.input-type';
export * from './boolean-filter.input-type';
export * from './date-filter.input-type';
export * from './date-time-filter.input-type';
export * from './float-filter.input-type';
export * from './int-filter.input-type';
export * from './raw-json-filter.input-type';
@@ -0,0 +1,54 @@
import { isInputObjectType } from 'graphql';
import { FieldMetadataType } from 'twenty-shared/types';
import { TypeMapperService } from 'src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service';
describe('TypeMapperService', () => {
const typeMapperService = new TypeMapperService();
describe('mapToFilterType', () => {
it('should map DATE_TIME to a DateTimeFilter input object with operators', () => {
const filterType = typeMapperService.mapToFilterType(
FieldMetadataType.DATE_TIME,
);
if (!isInputObjectType(filterType)) {
throw new Error('Expected DATE_TIME filter type to be an input object');
}
expect(filterType.name).toBe('DateTimeFilter');
const fields = filterType.getFields();
expect(Object.keys(fields).sort()).toEqual([
'eq',
'gt',
'gte',
'in',
'is',
'lt',
'lte',
'neq',
]);
for (const operator of ['eq', 'gt', 'gte', 'lt', 'lte', 'neq']) {
expect(fields[operator].type.toString()).toBe('DateTime');
}
expect(fields.in.type.toString()).toBe('[DateTime!]');
expect(fields.is.type.toString()).toBe('FilterIs');
});
it('should map DATE to a DateFilter input object', () => {
const filterType = typeMapperService.mapToFilterType(
FieldMetadataType.DATE,
);
if (!isInputObjectType(filterType)) {
throw new Error('Expected DATE filter type to be an input object');
}
expect(filterType.name).toBe('DateFilter');
});
});
});
@@ -27,6 +27,7 @@ import {
BigFloatFilterType,
BooleanFilterType,
DateFilterType,
DateTimeFilterType,
FloatFilterType,
RawJsonFilterType,
StringFilterType,
@@ -163,7 +164,7 @@ export class TypeMapperService {
>([
[FieldMetadataType.UUID, UUIDFilterType],
[FieldMetadataType.TEXT, StringFilterType],
[FieldMetadataType.DATE_TIME, GraphQLISODateTime],
[FieldMetadataType.DATE_TIME, DateTimeFilterType],
[FieldMetadataType.DATE, DateFilterType],
[FieldMetadataType.BOOLEAN, BooleanFilterType],
[