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:
@ -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();
|
||||
|
||||
|
||||
@ -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 (
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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) =>
|
||||
|
||||
@ -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,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -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,
|
||||
);
|
||||
});
|
||||
});
|
||||
@ -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,
|
||||
};
|
||||
};
|
||||
@ -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,
|
||||
};
|
||||
};
|
||||
@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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,
|
||||
|
||||
Reference in New Issue
Block a user