diff --git a/front/src/modules/metadata/hooks/useFindManyObjects.ts b/front/src/modules/metadata/hooks/useFindManyObjects.ts index baf415983cf..4f508bc6a34 100644 --- a/front/src/modules/metadata/hooks/useFindManyObjects.ts +++ b/front/src/modules/metadata/hooks/useFindManyObjects.ts @@ -6,6 +6,7 @@ import { logError } from '~/utils/logError'; import { ObjectMetadataItemIdentifier } from '../types/ObjectMetadataItemIdentifier'; import { PaginatedObjectType } from '../types/PaginatedObjectType'; +import { PaginatedObjectTypeResults } from '../types/PaginatedObjectTypeResults'; import { formatPagedObjectsToObjects } from '../utils/formatPagedObjectsToObjects'; import { useFindOneObjectMetadataItem } from './useFindOneObjectMetadataItem'; @@ -23,7 +24,7 @@ export const useFindManyObjects = < }: Pick & { filter?: any; orderBy?: any; - onCompleted?: (data: any) => void; + onCompleted?: (data: PaginatedObjectTypeResults) => void; skip?: boolean; }) => { const { foundObjectMetadataItem, objectNotFoundInMetadata, findManyQuery } = diff --git a/front/src/modules/settings/data-model/components/SettingsObjectFieldTypeSelectSection.tsx b/front/src/modules/settings/data-model/components/SettingsObjectFieldTypeSelectSection.tsx index b8c5e0619f8..48983aef6ec 100644 --- a/front/src/modules/settings/data-model/components/SettingsObjectFieldTypeSelectSection.tsx +++ b/front/src/modules/settings/data-model/components/SettingsObjectFieldTypeSelectSection.tsx @@ -64,7 +64,9 @@ export const SettingsObjectFieldTypeSelectSection = ({ }), )} /> - {['BOOLEAN', 'MONEY', 'NUMBER', 'TEXT'].includes(fieldType) && ( + {['BOOLEAN', 'DATE', 'MONEY', 'NUMBER', 'TEXT', 'URL'].includes( + fieldType, + ) && ( ( + + + + ), + ], + args: { + fieldIconKey: 'IconWorldWww', + fieldLabel: 'Website', + fieldType: 'URL', + }, +}; + export const Number: Story = { args: { fieldIconKey: 'IconUsers', diff --git a/front/src/modules/settings/data-model/constants/dataTypes.ts b/front/src/modules/settings/data-model/constants/dataTypes.ts index 1e25259a8f7..4f23c1756b8 100644 --- a/front/src/modules/settings/data-model/constants/dataTypes.ts +++ b/front/src/modules/settings/data-model/constants/dataTypes.ts @@ -1,4 +1,5 @@ import { + IconCalendarEvent, IconCheck, IconCoins, IconLink, @@ -11,23 +12,35 @@ import { Currency } from '~/generated-metadata/graphql'; import { MetadataFieldDataType } from '../types/ObjectFieldDataType'; +const defaultDateValue = new Date(); +defaultDateValue.setFullYear(defaultDateValue.getFullYear() + 2); + export const dataTypes: Record< MetadataFieldDataType, { label: string; Icon: IconComponent; defaultValue?: unknown } > = { - BOOLEAN: { label: 'True/False', Icon: IconCheck, defaultValue: true }, - MONEY: { - label: 'Currency', - Icon: IconCoins, - defaultValue: { amount: 2000, currency: Currency.Usd }, - }, - NUMBER: { label: 'Number', Icon: IconNumbers, defaultValue: 2000 }, - RELATION: { label: 'Relation', Icon: IconPlug }, TEXT: { label: 'Text', Icon: IconTextSize, defaultValue: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum magna enim, dapibus non enim in, lacinia faucibus nunc. Sed interdum ante sed felis facilisis, eget ultricies neque molestie. Mauris auctor, justo eu volutpat cursus, libero erat tempus nulla, non sodales lorem lacus a est.', }, - URL: { label: 'Link', Icon: IconLink }, + NUMBER: { label: 'Number', Icon: IconNumbers, defaultValue: 2000 }, + URL: { + label: 'Link', + Icon: IconLink, + defaultValue: { link: 'www.twenty.com', text: '' }, + }, + BOOLEAN: { label: 'True/False', Icon: IconCheck, defaultValue: true }, + DATE: { + label: 'Date', + Icon: IconCalendarEvent, + defaultValue: defaultDateValue.toISOString(), + }, + MONEY: { + label: 'Currency', + Icon: IconCoins, + defaultValue: { amount: 2000, currency: Currency.Usd }, + }, + RELATION: { label: 'Relation', Icon: IconPlug }, }; diff --git a/front/src/modules/settings/data-model/types/ObjectFieldDataType.ts b/front/src/modules/settings/data-model/types/ObjectFieldDataType.ts index 177bd60bfd6..0c47e05858f 100644 --- a/front/src/modules/settings/data-model/types/ObjectFieldDataType.ts +++ b/front/src/modules/settings/data-model/types/ObjectFieldDataType.ts @@ -1,5 +1,6 @@ export type MetadataFieldDataType = | 'BOOLEAN' + | 'DATE' | 'MONEY' | 'NUMBER' | 'RELATION' diff --git a/front/src/modules/ui/object/field/meta-types/display/content-display/components/URLDisplayV2.tsx b/front/src/modules/ui/object/field/meta-types/display/content-display/components/URLDisplayV2.tsx index 47866c57eed..3820638ba7f 100644 --- a/front/src/modules/ui/object/field/meta-types/display/content-display/components/URLDisplayV2.tsx +++ b/front/src/modules/ui/object/field/meta-types/display/content-display/components/URLDisplayV2.tsx @@ -50,7 +50,7 @@ export const URLV2Display = ({ value }: URLV2DisplayProps) => { : 'https://' + value.link : ''; - const displayedValue = value?.text ?? ''; + const displayedValue = value?.text || value?.link || ''; const type = checkUrlType(absoluteUrl); diff --git a/front/src/modules/ui/object/field/meta-types/hooks/useURLField.ts b/front/src/modules/ui/object/field/meta-types/hooks/useURLField.ts index 1c738e63966..f82981e8fac 100644 --- a/front/src/modules/ui/object/field/meta-types/hooks/useURLField.ts +++ b/front/src/modules/ui/object/field/meta-types/hooks/useURLField.ts @@ -9,6 +9,7 @@ import { usePersistField } from '../../hooks/usePersistField'; import { entityFieldsFamilySelector } from '../../states/selectors/entityFieldsFamilySelector'; import { assertFieldMetadata } from '../../types/guards/assertFieldMetadata'; import { isFieldURL } from '../../types/guards/isFieldURL'; +import { isFieldURLValue } from '../../types/guards/isFieldURLValue'; export const useURLField = () => { const { entityId, fieldDefinition, hotkeyScope } = useContext(FieldContext); @@ -23,12 +24,13 @@ export const useURLField = () => { fieldName: fieldName, }), ); + const fieldUrlValue = isFieldURLValue(fieldValue) ? fieldValue : ''; const fieldInitialValue = useFieldInitialValue(); const initialValue = fieldInitialValue?.isEmpty ? '' - : fieldInitialValue?.value ?? fieldValue; + : fieldInitialValue?.value ?? fieldUrlValue; const persistField = usePersistField(); @@ -42,7 +44,7 @@ export const useURLField = () => { return { fieldDefinition, - fieldValue, + fieldValue: fieldUrlValue, initialValue, setFieldValue, hotkeyScope, diff --git a/front/src/modules/ui/object/field/meta-types/hooks/useURLV2Field.ts b/front/src/modules/ui/object/field/meta-types/hooks/useURLV2Field.ts index 47072d18d68..6ed7354b6fa 100644 --- a/front/src/modules/ui/object/field/meta-types/hooks/useURLV2Field.ts +++ b/front/src/modules/ui/object/field/meta-types/hooks/useURLV2Field.ts @@ -28,7 +28,9 @@ export const useURLV2Field = () => { const initialValue: FieldURLV2Value = fieldInitialValue?.isEmpty ? { link: '', text: '' } - : { link: fieldInitialValue?.value ?? '', text: '' } ?? fieldValue; + : fieldInitialValue?.value + ? { link: fieldInitialValue.value, text: '' } + : fieldValue; const persistField = usePersistField(); diff --git a/front/src/modules/ui/object/field/states/selectors/isEntityFieldEmptyFamilySelector.ts b/front/src/modules/ui/object/field/states/selectors/isEntityFieldEmptyFamilySelector.ts index bf672dd9a74..df376d025df 100644 --- a/front/src/modules/ui/object/field/states/selectors/isEntityFieldEmptyFamilySelector.ts +++ b/front/src/modules/ui/object/field/states/selectors/isEntityFieldEmptyFamilySelector.ts @@ -19,6 +19,8 @@ import { isFieldRelation } from '../../types/guards/isFieldRelation'; import { isFieldRelationValue } from '../../types/guards/isFieldRelationValue'; import { isFieldText } from '../../types/guards/isFieldText'; import { isFieldURL } from '../../types/guards/isFieldURL'; +import { isFieldURLV2 } from '../../types/guards/isFieldURLV2'; +import { isFieldURLV2Value } from '../../types/guards/isFieldURLV2Value'; import { entityFieldsFamilyState } from '../entityFieldsFamilyState'; const isValueEmpty = (value: unknown) => !assertNotNull(value) || value === ''; @@ -104,6 +106,13 @@ export const isEntityFieldEmptyFamilySelector = selectorFamily({ ); } + if (isFieldURLV2(fieldDefinition)) { + const fieldName = fieldDefinition.metadata.fieldName; + const fieldValue = get(entityFieldsFamilyState(entityId))?.[fieldName]; + + return !isFieldURLV2Value(fieldValue) || isValueEmpty(fieldValue?.link); + } + throw new Error( `Entity field type not supported in isEntityFieldEmptyFamilySelector : ${fieldDefinition.type}}`, ); diff --git a/front/src/pages/settings/SettingsExperience.tsx b/front/src/pages/settings/SettingsExperience.tsx index ec8f7ec8abf..f52ed32c4b3 100644 --- a/front/src/pages/settings/SettingsExperience.tsx +++ b/front/src/pages/settings/SettingsExperience.tsx @@ -18,7 +18,7 @@ export const SettingsExperience = () => { return ( - +