From f4017119abedabc6f633ee2a4fedaad5a0489739 Mon Sep 17 00:00:00 2001 From: Charles Bochet Date: Fri, 5 Apr 2024 17:32:14 +0200 Subject: [PATCH] Various cosmetic fixes for 0.4.0 (#4844) In this PR: - fix empty list placeholder positionning - prevent user from erasing custom address field as composite types removal is not supported yet @ijreilly FYI - fix show page relation error - Implement address filter --- .../hooks/useLazyFindOneRecord.ts | 4 +- .../MultipleFiltersDropdownContent.tsx | 13 +++- .../getOperandsForFilterType.test.tsx | 1 + .../utils/getOperandsForFilterType.ts | 1 + ...turnObjectDropdownFilterIntoQueryFilter.ts | 69 +++++++++++++++++++ .../components/RecordTableWithWrappers.tsx | 1 + ...tingsObjectFieldDisabledActionDropdown.tsx | 10 ++- .../data-model/SettingsObjectDetail.tsx | 6 +- 8 files changed, 93 insertions(+), 12 deletions(-) diff --git a/packages/twenty-front/src/modules/object-record/hooks/useLazyFindOneRecord.ts b/packages/twenty-front/src/modules/object-record/hooks/useLazyFindOneRecord.ts index 8ef752088..e905b58a2 100644 --- a/packages/twenty-front/src/modules/object-record/hooks/useLazyFindOneRecord.ts +++ b/packages/twenty-front/src/modules/object-record/hooks/useLazyFindOneRecord.ts @@ -2,6 +2,7 @@ import { useLazyQuery } from '@apollo/client'; import { useObjectMetadataItemOnly } from '@/object-metadata/hooks/useObjectMetadataItemOnly'; import { ObjectMetadataItemIdentifier } from '@/object-metadata/types/ObjectMetadataItemIdentifier'; +import { getRecordFromRecordNode } from '@/object-record/cache/utils/getRecordFromRecordNode'; import { useGenerateFindOneRecordQuery } from '@/object-record/hooks/useGenerateFindOneRecordQuery'; import { ObjectRecord } from '@/object-record/types/ObjectRecord'; @@ -31,7 +32,8 @@ export const useLazyFindOneRecord = ({ findOneRecord: ({ objectRecordId, onCompleted }: FindOneRecordParams) => findOneRecord({ variables: { objectRecordId }, - onCompleted: (data) => onCompleted?.(data[objectNameSingular]), + onCompleted: (data) => + onCompleted?.(getRecordFromRecordNode(data[objectNameSingular])), }), called, error, diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx index 152fb1f82..1ab04fd68 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/MultipleFiltersDropdownContent.tsx @@ -48,9 +48,16 @@ export const MultipleFiltersDropdownContent = ({ <> - {['TEXT', 'EMAIL', 'PHONE', 'FULL_NAME', 'LINK'].includes( - filterDefinitionUsedInDropdown.type, - ) && } + {[ + 'TEXT', + 'EMAIL', + 'PHONE', + 'FULL_NAME', + 'LINK', + 'ADDRESS', + ].includes(filterDefinitionUsedInDropdown.type) && ( + + )} {['NUMBER', 'CURRENCY'].includes( filterDefinitionUsedInDropdown.type, ) && } diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.tsx index 1486146d8..7c6f09e6e 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/__tests__/getOperandsForFilterType.test.tsx @@ -11,6 +11,7 @@ describe('getOperandsForFilterType', () => { 'FULL_NAME', [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain], ], + ['ADDRESS', [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain]], ['LINK', [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain]], ['CURRENCY', [ViewFilterOperand.GreaterThan, ViewFilterOperand.LessThan]], ['NUMBER', [ViewFilterOperand.GreaterThan, ViewFilterOperand.LessThan]], diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getOperandsForFilterType.ts b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getOperandsForFilterType.ts index 94c6f92d5..874acf3a5 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getOperandsForFilterType.ts +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/utils/getOperandsForFilterType.ts @@ -9,6 +9,7 @@ export const getOperandsForFilterType = ( case 'TEXT': case 'EMAIL': case 'FULL_NAME': + case 'ADDRESS': case 'LINK': return [ViewFilterOperand.Contains, ViewFilterOperand.DoesNotContain]; case 'CURRENCY': diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts index 728c681d5..c6974c435 100644 --- a/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts +++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/turnObjectDropdownFilterIntoQueryFilter.ts @@ -1,6 +1,7 @@ import { isNonEmptyString } from '@sniptt/guards'; import { + AddressFilter, CurrencyFilter, DateFilter, FloatFilter, @@ -254,6 +255,74 @@ export const turnObjectDropdownFilterIntoQueryFilter = ( ); } break; + case 'ADDRESS': + switch (rawUIFilter.operand) { + case ViewFilterOperand.Contains: + objectRecordFilters.push({ + or: [ + { + [correspondingField.name]: { + addressStreet1: { + ilike: `%${rawUIFilter.value}%`, + }, + } as AddressFilter, + }, + { + [correspondingField.name]: { + addressStreet2: { + ilike: `%${rawUIFilter.value}%`, + }, + } as AddressFilter, + }, + { + [correspondingField.name]: { + addressCity: { + ilike: `%${rawUIFilter.value}%`, + }, + } as AddressFilter, + }, + ], + }); + break; + case ViewFilterOperand.DoesNotContain: + objectRecordFilters.push({ + and: [ + { + not: { + [correspondingField.name]: { + addressStreet1: { + ilike: `%${rawUIFilter.value}%`, + }, + } as AddressFilter, + }, + }, + { + not: { + [correspondingField.name]: { + addressStreet2: { + ilike: `%${rawUIFilter.value}%`, + }, + } as AddressFilter, + }, + }, + { + not: { + [correspondingField.name]: { + addressCity: { + ilike: `%${rawUIFilter.value}%`, + }, + } as AddressFilter, + }, + }, + ], + }); + break; + default: + throw new Error( + `Unknown operand ${rawUIFilter.operand} for ${rawUIFilter.definition.type} filter`, + ); + } + break; case 'SELECT': { const stringifiedSelectValues = rawUIFilter.value; let parsedOptionValues: string[] = []; diff --git a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx index 12e2f06d4..225df8bf5 100644 --- a/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx +++ b/packages/twenty-front/src/modules/object-record/record-table/components/RecordTableWithWrappers.tsx @@ -33,6 +33,7 @@ const StyledTableWithHeader = styled.div` flex: 1; flex-direction: column; width: 100%; + height: 100%; `; const StyledTableContainer = styled.div` diff --git a/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown.tsx b/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown.tsx index 432567b13..846f27fd5 100644 --- a/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown.tsx +++ b/packages/twenty-front/src/modules/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown.tsx @@ -6,10 +6,11 @@ import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu'; import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer'; import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem'; +import { FieldMetadataType } from '~/generated-metadata/graphql'; type SettingsObjectFieldInactiveActionDropdownProps = { isCustomField?: boolean; - isRelationType?: boolean; + fieldType?: FieldMetadataType; onActivate: () => void; onErase: () => void; scopeKey: string; @@ -20,7 +21,7 @@ export const SettingsObjectFieldInactiveActionDropdown = ({ scopeKey, onErase, isCustomField, - isRelationType, + fieldType, }: SettingsObjectFieldInactiveActionDropdownProps) => { const dropdownId = `${scopeKey}-settings-field-disabled-action-dropdown`; @@ -36,7 +37,10 @@ export const SettingsObjectFieldInactiveActionDropdown = ({ closeDropdown(); }; - const isErasable = isCustomField && !isRelationType; + const isErasable = + isCustomField && + fieldType !== FieldMetadataType.Relation && + fieldType !== FieldMetadataType.Address; return ( { ActionIcon={ activateMetadataField(disabledMetadataField)