From b28ff9c97e92753da4667ba042f8e612d9393355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tha=C3=AFs?= Date: Thu, 9 Nov 2023 18:51:21 +0100 Subject: [PATCH] feat: add Url field preview in settings (#2402) * feat: add Url field preview in settings Closes #2326 * feat: add Date field type in settings (#2414) Closes #2331 --- .../metadata/hooks/useFindManyObjects.ts | 3 +- .../SettingsObjectFieldTypeSelectSection.tsx | 4 ++- .../SettingsObjectFieldPreview.stories.tsx | 24 ++++++++++++++ .../data-model/constants/dataTypes.ts | 31 +++++++++++++------ .../data-model/types/ObjectFieldDataType.ts | 1 + .../components/URLDisplayV2.tsx | 2 +- .../field/meta-types/hooks/useURLField.ts | 6 ++-- .../field/meta-types/hooks/useURLV2Field.ts | 4 ++- .../isEntityFieldEmptyFamilySelector.ts | 9 ++++++ .../src/pages/settings/SettingsExperience.tsx | 2 +- 10 files changed, 70 insertions(+), 16 deletions(-) diff --git a/front/src/modules/metadata/hooks/useFindManyObjects.ts b/front/src/modules/metadata/hooks/useFindManyObjects.ts index baf415983c..4f508bc6a3 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 b8c5e0619f..48983aef6e 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 1e25259a8f..4f23c1756b 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 177bd60bfd..0c47e05858 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 47866c57ee..3820638ba7 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 1c738e6396..f82981e8fa 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 47072d18d6..6ed7354b6f 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 bf672dd9a7..df376d025d 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 ec8f7ec8ab..f52ed32c4b 100644 --- a/front/src/pages/settings/SettingsExperience.tsx +++ b/front/src/pages/settings/SettingsExperience.tsx @@ -18,7 +18,7 @@ export const SettingsExperience = () => { return ( - +