+
+ {
+ const inputValue = e.target.value;
+ setDateValue(inputValue);
+
+ if (!isDateTimeInput) {
+ const parsedInputDate = DateTime.fromFormat(
+ inputValue,
+ PICKER_DATE_FORMAT,
+ { zone: 'utc' },
+ );
+
+ const isValid = parsedInputDate.isValid;
+
+ if (isValid) {
+ onChange?.(parsedInputDate.toJSDate());
+ }
+ } else {
+ // TODO: implement time also
+ const parsedInputDate = DateTime.fromFormat(
+ inputValue,
+ PICKER_DATE_FORMAT,
+ { zone: 'utc' },
+ );
+
+ const isValid = parsedInputDate.isValid;
+
+ if (isValid) {
+ onChange?.(parsedInputDate.toJSDate());
+ }
+ }
+ }}
+ />
+
+
{
@@ -268,10 +345,18 @@ export const InternalDatePicker = ({
}}
customInput={<>>}
onSelect={(date: Date, event) => {
+ // Setting the time to midnight might sometimes return the previous day
+ // We set to 21:00 to avoid any timezone issues
+ const dateForDateField = new Date(date.setHours(21, 0, 0, 0));
+
+ setDateValue(
+ DateTime.fromJSDate(date).toFormat(PICKER_DATE_FORMAT),
+ );
+
if (event?.type === 'click') {
- onMouseSelect?.(date);
+ onMouseSelect?.(isDateTimeInput ? date : dateForDateField);
} else {
- onChange?.(date);
+ onChange?.(isDateTimeInput ? date : dateForDateField);
}
}}
>
diff --git a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts
index 3d5ca2f1b..9b3eb2dee 100644
--- a/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts
+++ b/packages/twenty-server/src/engine/api/graphql/workspace-schema-builder/services/type-mapper.service.ts
@@ -65,6 +65,7 @@ export class TypeMapperService {
[FieldMetadataType.PHONE, GraphQLString],
[FieldMetadataType.EMAIL, GraphQLString],
[FieldMetadataType.DATE_TIME, dateScalar],
+ [FieldMetadataType.DATE, dateScalar],
[FieldMetadataType.BOOLEAN, GraphQLBoolean],
[FieldMetadataType.NUMBER, numberScalar],
[FieldMetadataType.NUMERIC, BigFloatScalarType],
@@ -96,6 +97,7 @@ export class TypeMapperService {
[FieldMetadataType.PHONE, StringFilterType],
[FieldMetadataType.EMAIL, StringFilterType],
[FieldMetadataType.DATE_TIME, dateFilter],
+ [FieldMetadataType.DATE, DateFilterType],
[FieldMetadataType.BOOLEAN, BooleanFilterType],
[FieldMetadataType.NUMBER, numberScalar],
[FieldMetadataType.NUMERIC, BigFloatFilterType],
@@ -117,6 +119,7 @@ export class TypeMapperService {
[FieldMetadataType.PHONE, OrderByDirectionType],
[FieldMetadataType.EMAIL, OrderByDirectionType],
[FieldMetadataType.DATE_TIME, OrderByDirectionType],
+ [FieldMetadataType.DATE, OrderByDirectionType],
[FieldMetadataType.BOOLEAN, OrderByDirectionType],
[FieldMetadataType.NUMBER, OrderByDirectionType],
[FieldMetadataType.NUMERIC, OrderByDirectionType],
diff --git a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts
index 54d1fa83e..eec9a40c3 100644
--- a/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts
+++ b/packages/twenty-server/src/engine/api/rest/api-rest-query-builder/utils/map-field-metadata-to-graphql-query.utils.ts
@@ -20,6 +20,7 @@ export const mapFieldMetadataToGraphqlQuery = (
FieldMetadataType.TEXT,
FieldMetadataType.PHONE,
FieldMetadataType.DATE_TIME,
+ FieldMetadataType.DATE,
FieldMetadataType.EMAIL,
FieldMetadataType.NUMBER,
FieldMetadataType.SELECT,
diff --git a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts
index 07401cb78..8cba00761 100644
--- a/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts
+++ b/packages/twenty-server/src/engine/core-modules/open-api/utils/components.utils.ts
@@ -31,6 +31,7 @@ const getSchemaComponentsProperties = (
case FieldMetadataType.PHONE:
case FieldMetadataType.EMAIL:
case FieldMetadataType.DATE_TIME:
+ case FieldMetadataType.DATE:
itemProperty.type = 'string';
break;
case FieldMetadataType.NUMBER:
diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts
index c5666fda9..421227303 100644
--- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/dtos/default-value.input.ts
@@ -58,6 +58,12 @@ export class FieldMetadataDefaultValueDateTime {
value: Date | null;
}
+export class FieldMetadataDefaultValueDate {
+ @ValidateIf((object, value) => value !== null)
+ @IsDate()
+ value: Date | null;
+}
+
export class FieldMetadataDefaultValueLink {
@ValidateIf((object, value) => value !== null)
@IsQuotedString()
diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts
index 1678b3388..ede4e44b1 100644
--- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/field-metadata.entity.ts
@@ -23,6 +23,7 @@ export enum FieldMetadataType {
PHONE = 'PHONE',
EMAIL = 'EMAIL',
DATE_TIME = 'DATE_TIME',
+ DATE = 'DATE',
BOOLEAN = 'BOOLEAN',
NUMBER = 'NUMBER',
NUMERIC = 'NUMERIC',
diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts
index ca96eb8f4..5ca1ce6d4 100644
--- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/interfaces/field-metadata-default-value.interface.ts
@@ -27,6 +27,9 @@ type FieldMetadataDefaultValueMapping = {
[FieldMetadataType.DATE_TIME]:
| FieldMetadataDefaultValueDateTime
| FieldMetadataDefaultValueNowFunction;
+ [FieldMetadataType.DATE]:
+ | FieldMetadataDefaultValueDateTime
+ | FieldMetadataDefaultValueNowFunction;
[FieldMetadataType.BOOLEAN]: FieldMetadataDefaultValueBoolean;
[FieldMetadataType.NUMBER]: FieldMetadataDefaultValueNumber;
[FieldMetadataType.POSITION]: FieldMetadataDefaultValueNumber;
diff --git a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts
index 5cd428bb0..ab22f3c00 100644
--- a/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/field-metadata/utils/validate-default-value-for-type.util.ts
@@ -20,6 +20,7 @@ import {
FieldMetadataDefaultValueStringArray,
FieldMetadataDefaultValueNowFunction,
FieldMetadataDefaultValueUuidFunction,
+ FieldMetadataDefaultValueDate,
} from 'src/engine/metadata-modules/field-metadata/dtos/default-value.input';
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
@@ -35,6 +36,7 @@ export const defaultValueValidatorsMap = {
FieldMetadataDefaultValueDateTime,
FieldMetadataDefaultValueNowFunction,
],
+ [FieldMetadataType.DATE]: [FieldMetadataDefaultValueDate],
[FieldMetadataType.BOOLEAN]: [FieldMetadataDefaultValueBoolean],
[FieldMetadataType.NUMBER]: [FieldMetadataDefaultValueNumber],
[FieldMetadataType.NUMERIC]: [FieldMetadataDefaultValueString],
diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts
index 5c2903f64..093b3cba9 100644
--- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/factories/basic-column-action.factory.ts
@@ -25,6 +25,7 @@ export type BasicFieldMetadataType =
| FieldMetadataType.BOOLEAN
| FieldMetadataType.POSITION
| FieldMetadataType.DATE_TIME
+ | FieldMetadataType.DATE
| FieldMetadataType.POSITION;
@Injectable()
diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts
index c4d84d2b3..f3999fd7f 100644
--- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/utils/field-metadata-type-to-column-type.util.ts
@@ -25,6 +25,8 @@ export const fieldMetadataTypeToColumnType = (
return 'boolean';
case FieldMetadataType.DATE_TIME:
return 'timestamptz';
+ case FieldMetadataType.DATE:
+ return 'date';
case FieldMetadataType.RATING:
case FieldMetadataType.SELECT:
case FieldMetadataType.MULTI_SELECT:
diff --git a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts
index ac178277a..43eeae07a 100644
--- a/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts
+++ b/packages/twenty-server/src/engine/metadata-modules/workspace-migration/workspace-migration.factory.ts
@@ -74,6 +74,7 @@ export class WorkspaceMigrationFactory {
],
[FieldMetadataType.BOOLEAN, { factory: this.basicColumnActionFactory }],
[FieldMetadataType.DATE_TIME, { factory: this.basicColumnActionFactory }],
+ [FieldMetadataType.DATE, { factory: this.basicColumnActionFactory }],
[FieldMetadataType.RATING, { factory: this.enumColumnActionFactory }],
[FieldMetadataType.SELECT, { factory: this.enumColumnActionFactory }],
[
diff --git a/packages/twenty-zapier/src/utils/computeInputFields.ts b/packages/twenty-zapier/src/utils/computeInputFields.ts
index dc60091c1..7b8afbc58 100644
--- a/packages/twenty-zapier/src/utils/computeInputFields.ts
+++ b/packages/twenty-zapier/src/utils/computeInputFields.ts
@@ -18,6 +18,8 @@ const getTypeFromFieldMetadataType = (
return 'string';
case FieldMetadataType.DATE_TIME:
return 'datetime';
+ case FieldMetadataType.DATE:
+ return 'date';
case FieldMetadataType.BOOLEAN:
return 'boolean';
case FieldMetadataType.NUMBER:
@@ -177,6 +179,7 @@ export const computeInputFields = (
case FieldMetadataType.PHONE:
case FieldMetadataType.EMAIL:
case FieldMetadataType.DATE_TIME:
+ case FieldMetadataType.DATE:
case FieldMetadataType.BOOLEAN:
case FieldMetadataType.NUMBER:
case FieldMetadataType.NUMERIC:
diff --git a/packages/twenty-zapier/src/utils/data.types.ts b/packages/twenty-zapier/src/utils/data.types.ts
index 0d9a8056d..d7b38d487 100644
--- a/packages/twenty-zapier/src/utils/data.types.ts
+++ b/packages/twenty-zapier/src/utils/data.types.ts
@@ -36,6 +36,7 @@ export enum FieldMetadataType {
PHONE = 'PHONE',
EMAIL = 'EMAIL',
DATE_TIME = 'DATE_TIME',
+ DATE = 'DATE',
BOOLEAN = 'BOOLEAN',
NUMBER = 'NUMBER',
NUMERIC = 'NUMERIC',