diff --git a/packages/twenty-front/src/modules/apollo/optimistic-effect/utils/triggerDestroyRecordsOptimisticEffect.ts b/packages/twenty-front/src/modules/apollo/optimistic-effect/utils/triggerDestroyRecordsOptimisticEffect.ts index 5f62ff3bdb..8ed05ecd02 100644 --- a/packages/twenty-front/src/modules/apollo/optimistic-effect/utils/triggerDestroyRecordsOptimisticEffect.ts +++ b/packages/twenty-front/src/modules/apollo/optimistic-effect/utils/triggerDestroyRecordsOptimisticEffect.ts @@ -36,8 +36,7 @@ export const triggerDestroyRecordsOptimisticEffect = ({ const rootQueryCachedObjectRecordConnection = rootQueryCachedResponse; - const recordIdsToDelete = recordsToDestroy.map(({ id }) => id); - + const recordIdsToDestroy = recordsToDestroy.map(({ id }) => id); const cachedEdges = readField( 'edges', rootQueryCachedObjectRecordConnection, @@ -52,7 +51,7 @@ export const triggerDestroyRecordsOptimisticEffect = ({ cachedEdges?.filter((cachedEdge) => { const nodeId = readField('id', cachedEdge.node); - return nodeId && !recordIdsToDelete.includes(nodeId); + return nodeId && !recordIdsToDestroy.includes(nodeId); }) || []; if (nextCachedEdges.length === cachedEdges?.length) @@ -62,7 +61,7 @@ export const triggerDestroyRecordsOptimisticEffect = ({ ...rootQueryCachedObjectRecordConnection, edges: nextCachedEdges, totalCount: isDefined(totalCount) - ? totalCount - recordIdsToDelete.length + ? totalCount - recordIdsToDestroy.length : undefined, }; }, diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu.tsx index 84442b51a8..6fd8b778dc 100644 --- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu.tsx +++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelectCompositeFieldSubMenu.tsx @@ -1,7 +1,7 @@ -import { StyledInput } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownFilterSelect'; import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown'; import { objectFilterDropdownFilterIsSelectedComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFilterIsSelectedComponentState'; import { objectFilterDropdownFirstLevelFilterDefinitionComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownFirstLevelFilterDefinitionComponentState'; +import { objectFilterDropdownIsSelectingCompositeFieldComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownIsSelectingCompositeFieldComponentState'; import { objectFilterDropdownSubMenuFieldTypeComponentState } from '@/object-record/object-filter-dropdown/states/objectFilterDropdownSubMenuFieldTypeComponentState'; import { FilterDefinition } from '@/object-record/object-filter-dropdown/types/FilterDefinition'; import { getCompositeSubFieldLabel } from '@/object-record/object-filter-dropdown/utils/getCompositeSubFieldLabel'; @@ -16,7 +16,7 @@ import { useState } from 'react'; import { IconApps, IconChevronLeft, isDefined, useIcons } from 'twenty-ui'; export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => { - const [searchText, setSearchText] = useState(''); + const [searchText] = useState(''); const { getIcon } = useIcons(); @@ -31,6 +31,11 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => { objectFilterDropdownFilterIsSelectedComponentState, ); + const [, setObjectFilterDropdownIsSelectingCompositeField] = + useRecoilComponentStateV2( + objectFilterDropdownIsSelectingCompositeFieldComponentState, + ); + const [ objectFilterDropdownSubMenuFieldType, setObjectFilterDropdownSubMenuFieldType, @@ -62,6 +67,8 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => { setFilterDefinitionUsedInDropdown(null); setObjectFilterDropdownSubMenuFieldType(null); setObjectFilterDropdownFirstLevelFilterDefinition(null); + setObjectFilterDropdownIsSelectingCompositeField(false); + setObjectFilterDropdownFilterIsSelected(false); }; if ( @@ -87,14 +94,14 @@ export const ObjectFilterDropdownFilterSelectCompositeFieldSubMenu = () => { > {getFilterableFieldTypeLabel(objectFilterDropdownSubMenuFieldType)} - ) => setSearchText(event.target.value) } - /> + /> */} { LeftIcon={IconApps} text={`Any ${getFilterableFieldTypeLabel(objectFilterDropdownSubMenuFieldType)} field`} /> - {options.map((subFieldName, index) => ( - { - if (isDefined(objectFilterDropdownFirstLevelFilterDefinition)) { - handleSelectFilter({ - ...objectFilterDropdownFirstLevelFilterDefinition, - label: getCompositeSubFieldLabel( - objectFilterDropdownSubMenuFieldType, - subFieldName, - ), - compositeFieldName: subFieldName, - }); - } - }} - text={getCompositeSubFieldLabel( - objectFilterDropdownSubMenuFieldType, - subFieldName, - )} - LeftIcon={getIcon( - objectFilterDropdownFirstLevelFilterDefinition?.iconName, - )} - /> - ))} + {/* TODO: fix this with a backend field on ViewFilter for composite field filter */} + {objectFilterDropdownFirstLevelFilterDefinition.type === 'ACTOR' && + options.map((subFieldName, index) => ( + { + if (isDefined(objectFilterDropdownFirstLevelFilterDefinition)) { + handleSelectFilter({ + ...objectFilterDropdownFirstLevelFilterDefinition, + label: getCompositeSubFieldLabel( + objectFilterDropdownSubMenuFieldType, + subFieldName, + ), + compositeFieldName: subFieldName, + }); + } + }} + text={getCompositeSubFieldLabel( + objectFilterDropdownSubMenuFieldType, + subFieldName, + )} + LeftIcon={getIcon( + objectFilterDropdownFirstLevelFilterDefinition?.iconName, + )} + /> + ))} ); 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 476818a566..ff01993449 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 @@ -24,7 +24,6 @@ import { convertRatingToRatingValue, } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownRatingInput'; import { Filter } from '@/object-record/object-filter-dropdown/types/Filter'; -import { isActorSourceCompositeFilter } from '@/object-record/object-filter-dropdown/utils/isActorSourceCompositeFilter'; import { applyEmptyFilters } from '@/object-record/record-filter/utils/applyEmptyFilters'; import { resolveFilterValue } from '@/views/utils/view-filter-value/resolveFilterValue'; import { endOfDay, roundToNearestMinutes, startOfDay } from 'date-fns'; @@ -677,81 +676,83 @@ export const turnObjectDropdownFilterIntoQueryFilter = ( } break; } - case 'ACTOR': - if (isActorSourceCompositeFilter(rawUIFilter.definition)) { - const parsedRecordIds = JSON.parse(rawUIFilter.value) as string[]; + // TODO: fix this with a new composite field in ViewFilter entity + case 'ACTOR': { + switch (rawUIFilter.operand) { + case ViewFilterOperand.Is: { + const parsedRecordIds = JSON.parse(rawUIFilter.value) as string[]; - switch (rawUIFilter.operand) { - case ViewFilterOperand.Is: + objectRecordFilters.push({ + [correspondingField.name]: { + source: { + in: parsedRecordIds, + } as RelationFilter, + }, + }); + + break; + } + case ViewFilterOperand.IsNot: { + const parsedRecordIds = JSON.parse(rawUIFilter.value) as string[]; + + if (parsedRecordIds.length > 0) { objectRecordFilters.push({ - [correspondingField.name]: { - source: { - in: parsedRecordIds, - } as RelationFilter, + not: { + [correspondingField.name]: { + source: { + in: parsedRecordIds, + } as RelationFilter, + }, }, }); - - break; - case ViewFilterOperand.IsNot: - if (parsedRecordIds.length > 0) { - objectRecordFilters.push({ - not: { - [correspondingField.name]: { - source: { - in: parsedRecordIds, - } as RelationFilter, - }, - }, - }); - } - break; + } + break; } - } else { - switch (rawUIFilter.operand) { - case ViewFilterOperand.Contains: - objectRecordFilters.push({ - or: [ - { + case ViewFilterOperand.Contains: + objectRecordFilters.push({ + or: [ + { + [correspondingField.name]: { + name: { + ilike: `%${rawUIFilter.value}%`, + }, + } as ActorFilter, + }, + ], + }); + break; + case ViewFilterOperand.DoesNotContain: + objectRecordFilters.push({ + and: [ + { + not: { [correspondingField.name]: { name: { ilike: `%${rawUIFilter.value}%`, }, } as ActorFilter, }, - ], - }); - break; - case ViewFilterOperand.DoesNotContain: - objectRecordFilters.push({ - and: [ - { - not: { - [correspondingField.name]: { - name: { - ilike: `%${rawUIFilter.value}%`, - }, - } as ActorFilter, - }, - }, - ], - }); - break; - case ViewFilterOperand.IsEmpty: - case ViewFilterOperand.IsNotEmpty: - applyEmptyFilters( - rawUIFilter.operand, - correspondingField, - objectRecordFilters, - rawUIFilter.definition, - ); - break; - default: - throw new Error( - `Unknown operand ${rawUIFilter.operand} for ${rawUIFilter.definition.label} filter`, - ); - } + }, + ], + }); + break; + case ViewFilterOperand.IsEmpty: + case ViewFilterOperand.IsNotEmpty: + applyEmptyFilters( + rawUIFilter.operand, + correspondingField, + objectRecordFilters, + rawUIFilter.definition, + ); + break; + + default: + throw new Error( + `Unknown operand ${rawUIFilter.operand} for ${rawUIFilter.definition.label} filter`, + ); } break; + } case 'EMAILS': switch (rawUIFilter.operand) { case ViewFilterOperand.Contains: diff --git a/packages/twenty-front/src/modules/views/components/SortOrFilterChip.tsx b/packages/twenty-front/src/modules/views/components/SortOrFilterChip.tsx index 8b66bfc32b..1b55e6a327 100644 --- a/packages/twenty-front/src/modules/views/components/SortOrFilterChip.tsx +++ b/packages/twenty-front/src/modules/views/components/SortOrFilterChip.tsx @@ -39,9 +39,11 @@ const StyledChip = styled.div<{ variant: SortOrFitlerChipVariant }>` flex-shrink: 0; font-size: ${({ theme }) => theme.font.size.sm}; font-weight: ${({ theme }) => theme.font.weight.medium}; - padding: ${({ theme }) => theme.spacing(1) + ' ' + theme.spacing(2)}; + padding: ${({ theme }) => theme.spacing(0.5) + ' ' + theme.spacing(2)}; user-select: none; white-space: nowrap; + + max-height: ${({ theme }) => theme.spacing(4.5)}; `; const StyledIcon = styled.div` diff --git a/packages/twenty-front/src/modules/views/components/ViewBarDetails.tsx b/packages/twenty-front/src/modules/views/components/ViewBarDetails.tsx index 87b16a65fd..18ef21581f 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBarDetails.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarDetails.tsx @@ -50,7 +50,6 @@ const StyledChipcontainer = styled.div` overflow: scroll; gap: ${({ theme }) => theme.spacing(1)}; padding-top: ${({ theme }) => theme.spacing(1)}; - padding-bottom: ${({ theme }) => theme.spacing(0.5)}; z-index: 1; `;