From aba20dae11394025d07dcfb87bae73937eb2ee03 Mon Sep 17 00:00:00 2001 From: Lucas Bordeau Date: Tue, 4 Mar 2025 13:16:02 +0100 Subject: [PATCH] Implemented CRUD for view filter group and removed old states (#10590) This PR implements CRUD for view filter groups with the new logic as already done for view filters and view sorts. It also completely removes the old combined view filter group states and usage. This PR is quite big but the impact is limited since it only changes advanced filters module, which is under feature flag at the moment, and it is already in a broken state so unusable, even if someone activates the feature flag. --- .../AdvancedFilterAddFilterRuleSelect.tsx | 42 ++---- .../AdvancedFilterLogicalOperatorCell.tsx | 11 +- .../AdvancedFilterLogicalOperatorDropdown.tsx | 32 ++--- ...AdvancedFilterRootLevelViewFilterGroup.tsx | 8 +- .../AdvancedFilterRuleOptionsDropdown.tsx | 10 +- .../AdvancedFilterViewFilterFieldSelect.tsx | 2 +- .../AdvancedFilterViewFilterGroup.tsx | 8 +- .../AdvancedFilterLogicalOperatorOptions.ts | 6 +- .../hooks/useCurrentViewViewFilterGroup.ts | 41 +++--- .../hooks/useDeleteCombinedViewFilterGroup.ts | 110 --------------- .../hooks/useUpsertCombinedViewFilterGroup.ts | 54 -------- .../components/AdvancedFilterButton.tsx | 28 ++-- .../ObjectFilterDropdownBooleanSelect.tsx | 2 +- .../ObjectFilterDropdownDateInput.tsx | 4 +- .../ObjectFilterDropdownFilterSelect.tsx | 8 +- ...pdownFilterSelectCompositeFieldSubMenu.tsx | 2 +- .../ObjectFilterDropdownNumberInput.tsx | 2 +- .../ObjectFilterDropdownOptionSelect.tsx | 2 +- .../ObjectFilterDropdownRatingInput.tsx | 2 +- .../ObjectFilterDropdownRecordSelect.tsx | 2 +- .../ObjectFilterDropdownSourceSelect.tsx | 2 +- .../ObjectFilterDropdownTextSearchInput.tsx | 2 +- .../hooks/useSelectFilterUsedInDropdown.ts | 2 +- .../ObjectOptionsDropdownMenuContent.tsx | 5 +- ...jectOptionsDropdownRecordGroupsContent.tsx | 5 +- .../record-board/components/RecordBoard.tsx | 17 ++- .../record-filter/types/RecordFilter.ts | 4 +- .../computeViewRecordGqlOperationFilter.ts | 4 +- ...RecordTableBodyDragDropContextProvider.tsx | 16 +-- .../AdvancedFilterDropdownButton.tsx | 29 ++-- .../components/QueryParamsFiltersEffect.tsx | 4 - .../components/UpdateViewButtonGroup.tsx | 6 +- .../src/modules/views/components/ViewBar.tsx | 2 +- .../views/components/ViewBarDetails.tsx | 29 ++-- .../views/components/ViewBarPageTitle.tsx | 11 +- ...ViewFiltersToCurrentRecordFilters.test.tsx | 4 +- ...ViewFiltersToCurrentRecordFilters.test.tsx | 4 +- .../src/modules/views/hooks/useChangeView.ts | 7 +- .../hooks/useCreateViewFromCurrentView.ts | 25 ++-- .../hooks/useGetCombinedViewFilterGroups.ts | 68 ---------- .../modules/views/hooks/useGetCurrentView.ts | 27 ---- .../views/hooks/useResetUnsavedViewStates.ts | 34 ----- .../useSaveCurrentViewFiltersAndSorts.ts | 128 ++---------------- ...aveRecordFilterGroupsToViewFilterGroups.ts | 85 ++++++++++++ ...eViewFilterGroupIdsComponentFamilyState.ts | 9 -- ...ertViewFilterGroupsComponentFamilyState.ts | 10 -- .../utils/__tests__/viewMapFunctions.test.ts | 5 +- .../utils/mapRecordFilterToViewFilter.ts | 10 +- .../views/utils/mapViewFiltersToFilters.ts | 6 +- .../views/utils/shouldReplaceFilter.ts | 19 ++- .../components/ViewPickerDropdown.tsx | 12 +- .../components/ViewPickerListContent.tsx | 12 +- .../hooks/useDeleteViewFromCurrentState.ts | 2 +- .../hooks/useUpdateViewFromCurrentState.ts | 4 +- 54 files changed, 304 insertions(+), 681 deletions(-) delete mode 100644 packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useDeleteCombinedViewFilterGroup.ts delete mode 100644 packages/twenty-front/src/modules/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/useGetCombinedViewFilterGroups.ts delete mode 100644 packages/twenty-front/src/modules/views/hooks/useResetUnsavedViewStates.ts create mode 100644 packages/twenty-front/src/modules/views/hooks/useSaveRecordFilterGroupsToViewFilterGroups.ts delete mode 100644 packages/twenty-front/src/modules/views/states/unsavedToDeleteViewFilterGroupIdsComponentFamilyState.ts delete mode 100644 packages/twenty-front/src/modules/views/states/unsavedToUpsertViewFilterGroupsComponentFamilyState.ts diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx index a81a0d873..ab5cad4a9 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterAddFilterRuleSelect.tsx @@ -1,7 +1,6 @@ import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMetadataItemById'; import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForFilterFamilySelector'; import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions'; -import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup'; import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup'; import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; @@ -12,8 +11,7 @@ import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/Drop import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId'; import { useGetCurrentView } from '@/views/hooks/useGetCurrentView'; -import { ViewFilterGroup } from '@/views/types/ViewFilterGroup'; -import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; +import { useGetCurrentViewOnly } from '@/views/hooks/useGetCurrentViewOnly'; import { useCallback } from 'react'; import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared'; @@ -21,31 +19,29 @@ import { IconLibraryPlus, IconPlus, LightButton, MenuItem } from 'twenty-ui'; import { v4 } from 'uuid'; type AdvancedFilterAddFilterRuleSelectProps = { - viewFilterGroup: ViewFilterGroup; + recordFilterGroup: RecordFilterGroup; lastChildPosition?: number; }; export const AdvancedFilterAddFilterRuleSelect = ({ - viewFilterGroup, + recordFilterGroup, lastChildPosition = 0, }: AdvancedFilterAddFilterRuleSelectProps) => { - const dropdownId = `advanced-filter-add-filter-rule-${viewFilterGroup.id}`; + const dropdownId = `advanced-filter-add-filter-rule-${recordFilterGroup.id}`; const { currentViewId } = useGetCurrentView(); - const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup(); const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup(); const { upsertRecordFilter } = useUpsertRecordFilter(); - const newPositionInViewFilterGroup = lastChildPosition + 1; + const newPositionInRecordFilterGroup = lastChildPosition + 1; const { closeDropdown } = useDropdown(dropdownId); - const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView(); + const { currentView } = useGetCurrentViewOnly(); - const objectMetadataId = - currentViewWithCombinedFiltersAndSorts?.objectMetadataId; + const objectMetadataId = currentView?.objectMetadataId; if (!isDefined(objectMetadataId)) { throw new Error('Object metadata id is missing from current view'); @@ -100,8 +96,8 @@ export const AdvancedFilterAddFilterRuleSelect = ({ })[0], value: '', displayValue: '', - viewFilterGroupId: viewFilterGroup.id, - positionInViewFilterGroup: newPositionInViewFilterGroup, + recordFilterGroupId: recordFilterGroup.id, + positionInRecordFilterGroup: newPositionInRecordFilterGroup, label: defaultFieldMetadataItem.label, }); }; @@ -115,23 +111,13 @@ export const AdvancedFilterAddFilterRuleSelect = ({ const newRecordFilterGroupId = v4(); - const newViewFilterGroup: ViewFilterGroup = { - __typename: 'ViewFilterGroup', - id: newRecordFilterGroupId, - viewId: currentViewId, - logicalOperator: ViewFilterGroupLogicalOperator.AND, - parentViewFilterGroupId: viewFilterGroup.id, - positionInViewFilterGroup: newPositionInViewFilterGroup, - }; - const newRecordFilterGroup: RecordFilterGroup = { id: newRecordFilterGroupId, logicalOperator: RecordFilterGroupLogicalOperator.AND, - parentRecordFilterGroupId: viewFilterGroup.id, - positionInRecordFilterGroup: newPositionInViewFilterGroup, + parentRecordFilterGroupId: recordFilterGroup.id, + positionInRecordFilterGroup: newPositionInRecordFilterGroup, }; - upsertCombinedViewFilterGroup(newViewFilterGroup); upsertRecordFilterGroup(newRecordFilterGroup); const defaultFieldMetadataItem = getDefaultFieldMetadataItem(); @@ -149,14 +135,14 @@ export const AdvancedFilterAddFilterRuleSelect = ({ })[0], value: '', displayValue: '', - viewFilterGroupId: newViewFilterGroup.id, - positionInViewFilterGroup: newPositionInViewFilterGroup, + recordFilterGroupId: newRecordFilterGroupId, + positionInRecordFilterGroup: newPositionInRecordFilterGroup, label: defaultFieldMetadataItem.label, }); }; const isFilterRuleGroupOptionVisible = !isDefined( - viewFilterGroup.parentViewFilterGroupId, + recordFilterGroup.parentRecordFilterGroupId, ); if (!isFilterRuleGroupOptionVisible) { diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell.tsx index 7a7c5e9a3..fbca8948d 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorCell.tsx @@ -1,5 +1,6 @@ import { AdvancedFilterLogicalOperatorDropdown } from '@/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown'; -import { ViewFilterGroup } from '@/views/types/ViewFilterGroup'; +import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; + import styled from '@emotion/styled'; import { capitalize } from 'twenty-shared'; @@ -18,23 +19,23 @@ const StyledContainer = styled.div` type AdvancedFilterLogicalOperatorCellProps = { index: number; - viewFilterGroup: ViewFilterGroup; + recordFilterGroup: RecordFilterGroup; }; export const AdvancedFilterLogicalOperatorCell = ({ index, - viewFilterGroup, + recordFilterGroup, }: AdvancedFilterLogicalOperatorCellProps) => ( {index === 0 ? ( Where ) : index === 1 ? ( ) : ( - {capitalize(viewFilterGroup.logicalOperator.toLowerCase())} + {capitalize(recordFilterGroup.logicalOperator.toLowerCase())} )} diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown.tsx index c6ffcfd58..e566b4446 100644 --- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown.tsx +++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterLogicalOperatorDropdown.tsx @@ -1,43 +1,33 @@ import { ADVANCED_FILTER_LOGICAL_OPERATOR_OPTIONS } from '@/object-record/advanced-filter/constants/AdvancedFilterLogicalOperatorOptions'; -import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup'; import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup'; +import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; import { Select } from '@/ui/input/components/Select'; -import { ViewFilterGroup } from '@/views/types/ViewFilterGroup'; -import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; type AdvancedFilterLogicalOperatorDropdownProps = { - viewFilterGroup: ViewFilterGroup; + recordFilterGroup: RecordFilterGroup; }; export const AdvancedFilterLogicalOperatorDropdown = ({ - viewFilterGroup, + recordFilterGroup, }: AdvancedFilterLogicalOperatorDropdownProps) => { - const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup(); const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup(); - const handleChange = (value: ViewFilterGroupLogicalOperator) => { - upsertCombinedViewFilterGroup({ - ...viewFilterGroup, - logicalOperator: value, - }); - + const handleChange = (value: RecordFilterGroupLogicalOperator) => { upsertRecordFilterGroup({ - id: viewFilterGroup.id, - parentRecordFilterGroupId: viewFilterGroup.parentViewFilterGroupId, - positionInRecordFilterGroup: viewFilterGroup.positionInViewFilterGroup, - logicalOperator: - value === ViewFilterGroupLogicalOperator.AND - ? RecordFilterGroupLogicalOperator.AND - : RecordFilterGroupLogicalOperator.OR, + id: recordFilterGroup.id, + parentRecordFilterGroupId: recordFilterGroup.parentRecordFilterGroupId, + positionInRecordFilterGroup: + recordFilterGroup.positionInRecordFilterGroup, + logicalOperator: value, }); }; return (