Implements record filter group upsert and remove (#10514)

This PR implements a parallel code path to upsert and remove record
filter groups.

Those record filter groups aren't keeping track of the view id but since
they are in a view context, it's implicit that the advanced filter
feature can keep track of view for record filter groups.

We'll need record filter group for an upcoming feature without views, so
we need to abstract record filter group from view.

We have viewFilterGroup.id === recordFilterGroup.id, so it's easy to map
each other.
This commit is contained in:
Lucas Bordeau
2025-02-26 16:24:11 +01:00
committed by GitHub
parent dd12bc31ca
commit 694553608b
11 changed files with 391 additions and 27 deletions

View File

@ -2,6 +2,9 @@ import { useObjectMetadataItemById } from '@/object-metadata/hooks/useObjectMeta
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';
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
@ -31,6 +34,8 @@ export const AdvancedFilterAddFilterRuleSelect = ({
const { currentViewId } = useGetCurrentView();
const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup();
const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup();
const { upsertRecordFilter } = useUpsertRecordFilter();
const newPositionInViewFilterGroup = lastChildPosition + 1;
@ -108,15 +113,26 @@ export const AdvancedFilterAddFilterRuleSelect = ({
throw new Error('Missing view id');
}
const newViewFilterGroup = {
id: v4(),
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,
};
upsertCombinedViewFilterGroup(newViewFilterGroup);
upsertRecordFilterGroup(newRecordFilterGroup);
const defaultFieldMetadataItem = getDefaultFieldMetadataItem();

View File

@ -1,5 +1,7 @@
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 { 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';
@ -12,12 +14,23 @@ export const AdvancedFilterLogicalOperatorDropdown = ({
viewFilterGroup,
}: AdvancedFilterLogicalOperatorDropdownProps) => {
const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup();
const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup();
const handleChange = (value: ViewFilterGroupLogicalOperator) => {
upsertCombinedViewFilterGroup({
...viewFilterGroup,
logicalOperator: value,
});
upsertRecordFilterGroup({
id: viewFilterGroup.id,
parentRecordFilterGroupId: viewFilterGroup.parentViewFilterGroupId,
positionInRecordFilterGroup: viewFilterGroup.positionInViewFilterGroup,
logicalOperator:
value === ViewFilterGroupLogicalOperator.AND
? RecordFilterGroupLogicalOperator.AND
: RecordFilterGroupLogicalOperator.OR,
});
};
return (

View File

@ -2,6 +2,7 @@ import { AdvancedFilterRuleOptionsDropdownButton } from '@/object-record/advance
import { useCurrentViewViewFilterGroup } from '@/object-record/advanced-filter/hooks/useCurrentViewViewFilterGroup';
import { useDeleteCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useDeleteCombinedViewFilterGroup';
import { useRemoveRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useRemoveRecordFilterGroup';
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
@ -30,6 +31,7 @@ export const AdvancedFilterRuleOptionsDropdown = ({
const { removeRecordFilter } = useRemoveRecordFilter();
const { deleteCombinedViewFilterGroup } = useDeleteCombinedViewFilterGroup();
const { removeRecordFilterGroup } = useRemoveRecordFilterGroup();
const { currentViewFilterGroup, childViewFiltersAndViewFilterGroups } =
useCurrentViewViewFilterGroup({
@ -56,9 +58,11 @@ export const AdvancedFilterRuleOptionsDropdown = ({
isDefined(currentRecordFilter?.viewFilterGroupId)
) {
deleteCombinedViewFilterGroup(currentRecordFilter.viewFilterGroupId);
removeRecordFilterGroup(currentRecordFilter.viewFilterGroupId);
}
} else if (isDefined(currentViewFilterGroup)) {
deleteCombinedViewFilterGroup(currentViewFilterGroup.id);
removeRecordFilterGroup(currentViewFilterGroup.id);
// TODO: This is a temporary fix view filter group will be removed soon.
const childViewFilters = childViewFiltersAndViewFilterGroups.filter(

View File

@ -3,6 +3,8 @@ import { availableFieldMetadataItemsForFilterFamilySelector } from '@/object-met
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
import { useUpsertCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useUpsertCombinedViewFilterGroup';
import { OBJECT_FILTER_DROPDOWN_ID } from '@/object-record/object-filter-dropdown/constants/ObjectFilterDropdownId';
import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup';
import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator';
import { useUpsertRecordFilter } from '@/object-record/record-filter/hooks/useUpsertRecordFilter';
import { getRecordFilterOperands } from '@/object-record/record-filter/utils/getRecordFilterOperands';
@ -58,6 +60,7 @@ export const AdvancedFilterButton = () => {
useGetCurrentView();
const { upsertCombinedViewFilterGroup } = useUpsertCombinedViewFilterGroup();
const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup();
const { upsertRecordFilter } = useUpsertRecordFilter();
@ -96,6 +99,11 @@ export const AdvancedFilterButton = () => {
upsertCombinedViewFilterGroup(newViewFilterGroup);
upsertRecordFilterGroup({
id: newViewFilterGroup.id,
logicalOperator: RecordFilterGroupLogicalOperator.AND,
});
const defaultFieldMetadataItem =
availableFieldMetadataItemsForFilter.find(
(fieldMetadataItem) =>

View File

@ -0,0 +1,104 @@
import { renderHook } from '@testing-library/react';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { act } from 'react';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { useRemoveRecordFilterGroup } from '../useRemoveRecordFilterGroup';
import { useUpsertRecordFilterGroup } from '../useUpsertRecordFilterGroup';
const Wrapper = getJestMetadataAndApolloMocksWrapper({
apolloMocks: [],
});
describe('useRemoveRecordFilterGroup', () => {
it('should remove an existing record filter group', () => {
const { result } = renderHook(
() => {
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup();
const { removeRecordFilterGroup } = useRemoveRecordFilterGroup();
return {
upsertRecordFilterGroup,
removeRecordFilterGroup,
currentRecordFilterGroups,
};
},
{
wrapper: Wrapper,
},
);
const mockRecordFilterGroup: RecordFilterGroup = {
id: 'record-filter-group-1',
logicalOperator: RecordFilterGroupLogicalOperator.AND,
parentRecordFilterGroupId: null,
};
act(() => {
result.current.upsertRecordFilterGroup(mockRecordFilterGroup);
});
expect(result.current.currentRecordFilterGroups).toHaveLength(1);
expect(result.current.currentRecordFilterGroups[0]).toEqual(
mockRecordFilterGroup,
);
act(() => {
result.current.removeRecordFilterGroup(mockRecordFilterGroup.id);
});
expect(result.current.currentRecordFilterGroups).toHaveLength(0);
});
it('should not modify record filter groups when trying to remove a non-existent record filter group', () => {
const { result } = renderHook(
() => {
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup();
const { removeRecordFilterGroup } = useRemoveRecordFilterGroup();
return {
upsertRecordFilterGroup,
removeRecordFilterGroup,
currentRecordFilterGroups,
};
},
{
wrapper: Wrapper,
},
);
const mockRecordFilterGroup: RecordFilterGroup = {
id: 'record-filter-group-1',
logicalOperator: RecordFilterGroupLogicalOperator.AND,
parentRecordFilterGroupId: null,
};
act(() => {
result.current.upsertRecordFilterGroup(mockRecordFilterGroup);
});
expect(result.current.currentRecordFilterGroups).toHaveLength(1);
act(() => {
result.current.removeRecordFilterGroup(
'non-existent-record-filter-group-id',
);
});
expect(result.current.currentRecordFilterGroups).toHaveLength(1);
expect(result.current.currentRecordFilterGroups[0]).toEqual(
mockRecordFilterGroup,
);
});
});

View File

@ -0,0 +1,94 @@
import { renderHook } from '@testing-library/react';
import { act } from 'react';
import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
const Wrapper = getJestMetadataAndApolloMocksWrapper({
apolloMocks: [],
});
describe('useUpsertRecordFilterGroup', () => {
it('should add a new record filter group', () => {
const { result } = renderHook(
() => {
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup();
return { upsertRecordFilterGroup, currentRecordFilterGroups };
},
{
wrapper: Wrapper,
},
);
const mockRecordFilterGroup: RecordFilterGroup = {
id: 'record-filter-group-1',
logicalOperator: RecordFilterGroupLogicalOperator.AND,
parentRecordFilterGroupId: null,
};
act(() => {
result.current.upsertRecordFilterGroup(mockRecordFilterGroup);
});
expect(result.current.currentRecordFilterGroups).toHaveLength(1);
expect(result.current.currentRecordFilterGroups[0]).toEqual(
mockRecordFilterGroup,
);
});
it('should update an existing record filter group', () => {
const { result } = renderHook(
() => {
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
const { upsertRecordFilterGroup } = useUpsertRecordFilterGroup();
return { upsertRecordFilterGroup, currentRecordFilterGroups };
},
{
wrapper: Wrapper,
},
);
const mockInitialRecordFilterGroup: RecordFilterGroup = {
id: 'record-filter-group-1',
logicalOperator: RecordFilterGroupLogicalOperator.AND,
parentRecordFilterGroupId: null,
};
const mockUpdatedRecordFilterGroup: RecordFilterGroup = {
id: 'record-filter-group-1',
logicalOperator: RecordFilterGroupLogicalOperator.OR,
parentRecordFilterGroupId: null,
};
act(() => {
result.current.upsertRecordFilterGroup(mockInitialRecordFilterGroup);
});
expect(result.current.currentRecordFilterGroups).toHaveLength(1);
expect(result.current.currentRecordFilterGroups[0]).toEqual(
mockInitialRecordFilterGroup,
);
act(() => {
result.current.upsertRecordFilterGroup(mockUpdatedRecordFilterGroup);
});
expect(result.current.currentRecordFilterGroups).toHaveLength(1);
expect(result.current.currentRecordFilterGroups[0]).toEqual(
mockUpdatedRecordFilterGroup,
);
});
});

View File

@ -0,0 +1,59 @@
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilCallback } from 'recoil';
export const useRemoveRecordFilterGroup = () => {
const currentRecordFilterGroupsCallbackState =
useRecoilComponentCallbackStateV2(currentRecordFilterGroupsComponentState);
const removeRecordFilterGroup = useRecoilCallback(
({ set, snapshot }) =>
(recordFilterGroupIdToRemove: string) => {
const currentRecordFilterGroups = getSnapshotValue(
snapshot,
currentRecordFilterGroupsCallbackState,
);
const hasFoundRecordFilterGroupInCurrentRecordFilterGroups =
currentRecordFilterGroups.some(
(existingRecordFilterGroup) =>
existingRecordFilterGroup.id === recordFilterGroupIdToRemove,
);
if (hasFoundRecordFilterGroupInCurrentRecordFilterGroups) {
set(
currentRecordFilterGroupsCallbackState,
(currentRecordFilterGroups) => {
const newCurrentRecordFilterGroups = [
...currentRecordFilterGroups,
];
const indexOfRecordFilterGroupToRemove =
newCurrentRecordFilterGroups.findIndex(
(existingRecordFilterGroup) =>
existingRecordFilterGroup.id ===
recordFilterGroupIdToRemove,
);
if (indexOfRecordFilterGroupToRemove === -1) {
return newCurrentRecordFilterGroups;
}
newCurrentRecordFilterGroups.splice(
indexOfRecordFilterGroupToRemove,
1,
);
return newCurrentRecordFilterGroups;
},
);
}
},
[currentRecordFilterGroupsCallbackState],
);
return {
removeRecordFilterGroup,
};
};

View File

@ -0,0 +1,63 @@
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup';
import { useRecoilComponentCallbackStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentCallbackStateV2';
import { getSnapshotValue } from '@/ui/utilities/state/utils/getSnapshotValue';
import { useRecoilCallback } from 'recoil';
export const useUpsertRecordFilterGroup = () => {
const currentRecordFilterGroupsCallbackState =
useRecoilComponentCallbackStateV2(currentRecordFilterGroupsComponentState);
const upsertRecordFilterGroup = useRecoilCallback(
({ set, snapshot }) =>
(recordFilterGroupToSet: RecordFilterGroup) => {
const currentRecordFilterGroups = getSnapshotValue(
snapshot,
currentRecordFilterGroupsCallbackState,
);
const hasFoundRecordFilterGroupInCurrentRecordFilterGroups =
currentRecordFilterGroups.some(
(existingRecordFilterGroup) =>
existingRecordFilterGroup.id === recordFilterGroupToSet.id,
);
if (!hasFoundRecordFilterGroupInCurrentRecordFilterGroups) {
set(currentRecordFilterGroupsCallbackState, [
...currentRecordFilterGroups,
recordFilterGroupToSet,
]);
} else {
set(
currentRecordFilterGroupsCallbackState,
(currentRecordFilterGroups) => {
const newCurrentRecordFilterGroups = [
...currentRecordFilterGroups,
];
const indexOfRecordFilterGroupToUpdate =
newCurrentRecordFilterGroups.findIndex(
(existingRecordFilterGroup) =>
existingRecordFilterGroup.id === recordFilterGroupToSet.id,
);
if (indexOfRecordFilterGroupToUpdate === -1) {
return newCurrentRecordFilterGroups;
}
newCurrentRecordFilterGroups[indexOfRecordFilterGroupToUpdate] = {
...recordFilterGroupToSet,
};
return newCurrentRecordFilterGroups;
},
);
}
},
[currentRecordFilterGroupsCallbackState],
);
return {
upsertRecordFilterGroup,
};
};

View File

@ -1,10 +1,10 @@
import { renderHook } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
import { act } from 'react';
import { FieldMetadataType } from '~/generated/graphql';
import { getJestMetadataAndApolloMocksWrapper } from '~/testing/jest/getJestMetadataAndApolloMocksWrapper';
import { useRemoveRecordFilter } from '../useRemoveRecordFilter';
@ -15,7 +15,7 @@ const Wrapper = getJestMetadataAndApolloMocksWrapper({
});
describe('useRemoveRecordFilter', () => {
it('should remove an existing filter', () => {
it('should remove an existing record filter', () => {
const { result } = renderHook(
() => {
const currentRecordFilters = useRecoilComponentValueV2(
@ -36,7 +36,7 @@ describe('useRemoveRecordFilter', () => {
},
);
const filter: RecordFilter = {
const mockRecordFilter: RecordFilter = {
id: 'filter-1',
fieldMetadataId: 'field-1',
value: 'test-value',
@ -46,17 +46,15 @@ describe('useRemoveRecordFilter', () => {
type: FieldMetadataType.TEXT,
};
// First add a filter
act(() => {
result.current.upsertRecordFilter(filter);
result.current.upsertRecordFilter(mockRecordFilter);
});
expect(result.current.currentRecordFilters).toHaveLength(1);
expect(result.current.currentRecordFilters[0]).toEqual(filter);
expect(result.current.currentRecordFilters[0]).toEqual(mockRecordFilter);
// Then remove it
act(() => {
result.current.removeRecordFilter(filter.fieldMetadataId);
result.current.removeRecordFilter(mockRecordFilter.fieldMetadataId);
});
expect(result.current.currentRecordFilters).toHaveLength(0);
@ -81,7 +79,7 @@ describe('useRemoveRecordFilter', () => {
},
);
const filter: RecordFilter = {
const mockRecordFilter: RecordFilter = {
id: 'filter-1',
fieldMetadataId: 'field-1',
value: 'test-value',
@ -91,20 +89,17 @@ describe('useRemoveRecordFilter', () => {
type: FieldMetadataType.TEXT,
};
// Add a filter
act(() => {
result.current.upsertRecordFilter(filter);
result.current.upsertRecordFilter(mockRecordFilter);
});
expect(result.current.currentRecordFilters).toHaveLength(1);
// Try to remove a non-existent filter
act(() => {
result.current.removeRecordFilter('non-existent-field');
result.current.removeRecordFilter('non-existent-field-metadata-id');
});
// Filter list should remain unchanged
expect(result.current.currentRecordFilters).toHaveLength(1);
expect(result.current.currentRecordFilters[0]).toEqual(filter);
expect(result.current.currentRecordFilters[0]).toEqual(mockRecordFilter);
});
});

View File

@ -1,5 +1,5 @@
import { renderHook } from '@testing-library/react';
import { act } from 'react-dom/test-utils';
import { act } from 'react';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
@ -30,7 +30,7 @@ describe('useUpsertRecordFilter', () => {
},
);
const newFilter: RecordFilter = {
const mockNewRecordFilter: RecordFilter = {
id: 'filter-1',
fieldMetadataId: 'field-1',
value: 'test-value',
@ -41,11 +41,11 @@ describe('useUpsertRecordFilter', () => {
};
act(() => {
result.current.upsertRecordFilter(newFilter);
result.current.upsertRecordFilter(mockNewRecordFilter);
});
expect(result.current.currentRecordFilters).toHaveLength(1);
expect(result.current.currentRecordFilters[0]).toEqual(newFilter);
expect(result.current.currentRecordFilters[0]).toEqual(mockNewRecordFilter);
});
it('should update an existing filter when fieldMetadataId exists', () => {
@ -64,7 +64,7 @@ describe('useUpsertRecordFilter', () => {
},
);
const initialFilter: RecordFilter = {
const mockInitialRecordFilter: RecordFilter = {
id: 'filter-1',
fieldMetadataId: 'field-1',
value: 'initial-value',
@ -74,7 +74,7 @@ describe('useUpsertRecordFilter', () => {
type: FieldMetadataType.TEXT,
};
const updatedFilter: RecordFilter = {
const mockUpdatedRecordFilter: RecordFilter = {
id: 'filter-1',
fieldMetadataId: 'field-1',
value: 'updated-value',
@ -85,17 +85,21 @@ describe('useUpsertRecordFilter', () => {
};
act(() => {
result.current.upsertRecordFilter(initialFilter);
result.current.upsertRecordFilter(mockInitialRecordFilter);
});
expect(result.current.currentRecordFilters).toHaveLength(1);
expect(result.current.currentRecordFilters[0]).toEqual(initialFilter);
expect(result.current.currentRecordFilters[0]).toEqual(
mockInitialRecordFilter,
);
act(() => {
result.current.upsertRecordFilter(updatedFilter);
result.current.upsertRecordFilter(mockUpdatedRecordFilter);
});
expect(result.current.currentRecordFilters).toHaveLength(1);
expect(result.current.currentRecordFilters[0]).toEqual(updatedFilter);
expect(result.current.currentRecordFilters[0]).toEqual(
mockUpdatedRecordFilter,
);
});
});

View File

@ -4,6 +4,7 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { AdvancedFilterRootLevelViewFilterGroup } from '@/object-record/advanced-filter/components/AdvancedFilterRootLevelViewFilterGroup';
import { useDeleteCombinedViewFilterGroup } from '@/object-record/advanced-filter/hooks/useDeleteCombinedViewFilterGroup';
import { useRemoveRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useRemoveRecordFilterGroup';
import { useRemoveRecordFilter } from '@/object-record/record-filter/hooks/useRemoveRecordFilter';
import { currentRecordFiltersComponentState } from '@/object-record/record-filter/states/currentRecordFiltersComponentState';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
@ -14,6 +15,7 @@ import { isDefined } from 'twenty-shared';
export const AdvancedFilterDropdownButton = () => {
const { deleteCombinedViewFilterGroup } = useDeleteCombinedViewFilterGroup();
const { removeRecordFilterGroup } = useRemoveRecordFilterGroup();
const { currentViewWithCombinedFiltersAndSorts } = useGetCurrentView();
@ -43,6 +45,7 @@ export const AdvancedFilterDropdownButton = () => {
for (const viewFilterGroupId of viewFilterGroupIds) {
await deleteCombinedViewFilterGroup(viewFilterGroupId);
removeRecordFilterGroup(viewFilterGroupId);
}
for (const recordFilterId of advancedRecordFilterIds) {
@ -50,6 +53,7 @@ export const AdvancedFilterDropdownButton = () => {
}
}, [
advancedRecordFilterIds,
removeRecordFilterGroup,
removeRecordFilter,
deleteCombinedViewFilterGroup,
currentViewWithCombinedFiltersAndSorts?.viewFilterGroups,