diff --git a/front/src/modules/metadata/hooks/useFindManyObjects.ts b/front/src/modules/metadata/hooks/useFindManyObjects.ts index baf415983..4f508bc6a 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 b8c5e0619..48983aef6 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 1e25259a8..4f23c1756 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 177bd60bf..0c47e0585 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 47866c57e..3820638ba 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 1c738e639..f82981e8f 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 47072d18d..6ed7354b6 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 bf672dd9a..df376d025 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 ec8f7ec8a..f52ed32c4 100644 --- a/front/src/pages/settings/SettingsExperience.tsx +++ b/front/src/pages/settings/SettingsExperience.tsx @@ -18,7 +18,7 @@ export const SettingsExperience = () => { return ( - +