diff --git a/packages/twenty-front/src/modules/views/components/ViewBar.tsx b/packages/twenty-front/src/modules/views/components/ViewBar.tsx index 1a6fcfcad..232d70607 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBar.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBar.tsx @@ -18,6 +18,7 @@ import { FiltersHotkeyScope } from '@/object-record/object-filter-dropdown/types import { VIEW_SORT_DROPDOWN_ID } from '@/object-record/object-sort-dropdown/constants/ViewSortDropdownId'; import { ObjectSortDropdownComponentInstanceContext } from '@/object-record/object-sort-dropdown/states/context/ObjectSortDropdownComponentInstanceContext'; import { ViewBarRecordFilterEffect } from '@/views/components/ViewBarRecordFilterEffect'; +import { ViewBarRecordFilterGroupEffect } from '@/views/components/ViewBarRecordFilterGroupEffect'; import { ViewBarRecordSortEffect } from '@/views/components/ViewBarRecordSortEffect'; import { UpdateViewButtonGroup } from './UpdateViewButtonGroup'; import { ViewBarDetails } from './ViewBarDetails'; @@ -47,6 +48,7 @@ export const ViewBar = ({ + diff --git a/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterEffect.tsx b/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterEffect.tsx index 55b607acc..537a77f2a 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterEffect.tsx @@ -41,10 +41,6 @@ export const ViewBarRecordFilterEffect = () => { currentRecordFiltersComponentState, ); - const currentRecordFilters = useRecoilComponentValueV2( - currentRecordFiltersComponentState, - ); - const { filterableFieldMetadataItems } = useFilterableFieldMetadataItems( contextStoreCurrentObjectMetadataItem?.id, ); @@ -65,6 +61,7 @@ export const ViewBarRecordFilterEffect = () => { filterableFieldMetadataItems, ), ); + setHasInitializedCurrentRecordFilters(true); } } @@ -72,7 +69,6 @@ export const ViewBarRecordFilterEffect = () => { currentViewId, setCurrentRecordFilters, filterableFieldMetadataItems, - currentRecordFilters, hasInitializedCurrentRecordFilters, setHasInitializedCurrentRecordFilters, contextStoreCurrentObjectMetadataItem?.id, diff --git a/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterGroupEffect.tsx b/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterGroupEffect.tsx new file mode 100644 index 000000000..f5df1f9da --- /dev/null +++ b/packages/twenty-front/src/modules/views/components/ViewBarRecordFilterGroupEffect.tsx @@ -0,0 +1,72 @@ +import { contextStoreCurrentObjectMetadataItemComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemComponentState'; +import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; +import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState'; +import { prefetchViewFromViewIdFamilySelector } from '@/prefetch/states/selector/prefetchViewFromViewIdFamilySelector'; +import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2'; +import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2'; +import { useSetRecoilComponentStateV2 } from '@/ui/utilities/state/component-state/hooks/useSetRecoilComponentStateV2'; +import { hasInitializedCurrentRecordFilterGroupsComponentFamilyState } from '@/views/states/hasInitializedCurrentRecordFilterGroupsComponentFamilyState'; +import { mapViewFilterGroupsToRecordFilterGroups } from '@/views/utils/mapViewFilterGroupsToRecordFilterGroups'; +import { useEffect } from 'react'; +import { useRecoilValue } from 'recoil'; +import { isDefined } from 'twenty-shared'; + +export const ViewBarRecordFilterGroupEffect = () => { + const currentViewId = useRecoilComponentValueV2( + contextStoreCurrentViewIdComponentState, + ); + + const contextStoreCurrentObjectMetadataItem = useRecoilComponentValueV2( + contextStoreCurrentObjectMetadataItemComponentState, + ); + + const currentView = useRecoilValue( + prefetchViewFromViewIdFamilySelector({ + viewId: currentViewId ?? '', + }), + ); + + const [ + hasInitializedCurrentRecordFilterGroups, + setHasInitializedCurrentRecordFilterGroups, + ] = useRecoilComponentFamilyStateV2( + hasInitializedCurrentRecordFilterGroupsComponentFamilyState, + { + viewId: currentViewId ?? undefined, + }, + ); + + const setCurrentRecordFilterGroups = useSetRecoilComponentStateV2( + currentRecordFilterGroupsComponentState, + ); + + useEffect(() => { + if (isDefined(currentView) && !hasInitializedCurrentRecordFilterGroups) { + if ( + currentView.objectMetadataId !== + contextStoreCurrentObjectMetadataItem?.id + ) { + return; + } + + if (isDefined(currentView)) { + setCurrentRecordFilterGroups( + mapViewFilterGroupsToRecordFilterGroups( + currentView.viewFilterGroups ?? [], + ), + ); + + setHasInitializedCurrentRecordFilterGroups(true); + } + } + }, [ + currentViewId, + setCurrentRecordFilterGroups, + hasInitializedCurrentRecordFilterGroups, + setHasInitializedCurrentRecordFilterGroups, + contextStoreCurrentObjectMetadataItem?.id, + currentView, + ]); + + return null; +}; diff --git a/packages/twenty-front/src/modules/views/components/ViewBarRecordSortEffect.tsx b/packages/twenty-front/src/modules/views/components/ViewBarRecordSortEffect.tsx index 9d73e1408..cbf6e58e8 100644 --- a/packages/twenty-front/src/modules/views/components/ViewBarRecordSortEffect.tsx +++ b/packages/twenty-front/src/modules/views/components/ViewBarRecordSortEffect.tsx @@ -1,6 +1,5 @@ import { contextStoreCurrentObjectMetadataItemComponentState } from '@/context-store/states/contextStoreCurrentObjectMetadataItemComponentState'; import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState'; -import { availableFieldMetadataItemsForSortFamilySelector } from '@/object-metadata/states/availableFieldMetadataItemsForSortFamilySelector'; import { currentRecordSortsComponentState } from '@/object-record/record-sort/states/currentRecordSortsComponentState'; import { prefetchViewFromViewIdFamilySelector } from '@/prefetch/states/selector/prefetchViewFromViewIdFamilySelector'; import { useRecoilComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentFamilyStateV2'; @@ -43,12 +42,6 @@ export const ViewBarRecordSortEffect = () => { currentRecordSortsComponentState, ); - const sortableFieldMetadataItems = useRecoilValue( - availableFieldMetadataItemsForSortFamilySelector({ - objectMetadataItemId: contextStoreCurrentObjectMetadataItem?.id, - }), - ); - useEffect(() => { if (isDefined(currentView) && !hasInitializedCurrentRecordSorts) { if ( @@ -66,7 +59,6 @@ export const ViewBarRecordSortEffect = () => { }, [ hasInitializedCurrentRecordSorts, currentView, - sortableFieldMetadataItems, setCurrentRecordSorts, contextStoreCurrentObjectMetadataItem, setHasInitializedCurrentRecordSorts, diff --git a/packages/twenty-front/src/modules/views/states/hasInitializedCurrentRecordFilterGroupsComponentFamilyState.ts b/packages/twenty-front/src/modules/views/states/hasInitializedCurrentRecordFilterGroupsComponentFamilyState.ts new file mode 100644 index 000000000..9496bd246 --- /dev/null +++ b/packages/twenty-front/src/modules/views/states/hasInitializedCurrentRecordFilterGroupsComponentFamilyState.ts @@ -0,0 +1,9 @@ +import { RecordFilterGroupsComponentInstanceContext } from '@/object-record/record-filter-group/states/context/RecordFilterGroupsComponentInstanceContext'; +import { createComponentFamilyStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentFamilyStateV2'; + +export const hasInitializedCurrentRecordFilterGroupsComponentFamilyState = + createComponentFamilyStateV2({ + key: 'hasInitializedCurrentRecordFilterGroupsComponentFamilyState', + defaultValue: false, + componentInstanceContext: RecordFilterGroupsComponentInstanceContext, + }); diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/getViewSortsToCreate.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/getViewSortsToCreate.test.ts index ebc8f5790..337505e3d 100644 --- a/packages/twenty-front/src/modules/views/utils/__tests__/getViewSortsToCreate.test.ts +++ b/packages/twenty-front/src/modules/views/utils/__tests__/getViewSortsToCreate.test.ts @@ -54,25 +54,6 @@ describe('getViewSortsToCreate', () => { expect(result).toEqual([newSortWithDifferentFieldMetadataId]); }); - it('should handle sorts with different fieldMetadataIds', () => { - const existingSort = { ...baseSort }; - const sortWithDifferentFieldMetadataId = { - ...baseSort, - fieldMetadataId: 'group-2', - } satisfies ViewSort; - - const currentViewSorts: ViewSort[] = [existingSort]; - - const newViewSorts: ViewSort[] = [ - existingSort, - sortWithDifferentFieldMetadataId, - ]; - - const result = getViewSortsToCreate(currentViewSorts, newViewSorts); - - expect(result).toEqual([sortWithDifferentFieldMetadataId]); - }); - it('should handle empty arrays for both inputs', () => { const currentViewSorts: ViewSort[] = []; const newViewSorts: ViewSort[] = []; diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.test.ts new file mode 100644 index 000000000..d4c3a171f --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.test.ts @@ -0,0 +1,21 @@ +import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; +import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; +import { mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator } from '@/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator'; + +describe('mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator', () => { + it('should map correctly for AND', () => { + expect( + mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator({ + recordFilterGroupLogicalOperator: RecordFilterGroupLogicalOperator.AND, + }), + ).toEqual(ViewFilterGroupLogicalOperator.AND); + }); + + it('should map correctly for OR', () => { + expect( + mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator({ + recordFilterGroupLogicalOperator: RecordFilterGroupLogicalOperator.OR, + }), + ).toEqual(ViewFilterGroupLogicalOperator.OR); + }); +}); diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupToViewFilterGroup.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupToViewFilterGroup.test.ts new file mode 100644 index 000000000..182f2d406 --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/__tests__/mapRecordFilterGroupToViewFilterGroup.test.ts @@ -0,0 +1,138 @@ +import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; +import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; +import { AGGREGATE_OPERATIONS } from '@/object-record/record-table/constants/AggregateOperations'; +import { View } from '@/views/types/View'; +import { ViewFilterGroup } from '@/views/types/ViewFilterGroup'; +import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; +import { ViewOpenRecordInType } from '@/views/types/ViewOpenRecordInType'; +import { ViewType } from '@/views/types/ViewType'; +import { mapRecordFilterGroupToViewFilterGroup } from '@/views/utils/mapRecordFilterGroupToViewFilterGroup'; +import { isDefined } from 'twenty-shared'; +import { generatedMockObjectMetadataItems } from '~/testing/mock-data/generatedMockObjectMetadataItems'; + +const mockObjectMetadataItemNameSingular = 'company'; + +describe('mapRecordFilterGroupToViewFilterGroup', () => { + const mockObjectMetadataItem = generatedMockObjectMetadataItems.find( + (item) => item.nameSingular === mockObjectMetadataItemNameSingular, + ); + + if (!isDefined(mockObjectMetadataItem)) { + throw new Error( + 'Missing mock object metadata item with name singular "company"', + ); + } + + const mockView: View = { + id: 'view-1', + name: 'Test View', + objectMetadataId: mockObjectMetadataItem.id, + viewFilters: [], + viewFilterGroups: [], + type: ViewType.Table, + key: null, + isCompact: false, + openRecordIn: ViewOpenRecordInType.SIDE_PANEL, + viewFields: [], + viewGroups: [], + viewSorts: [], + kanbanFieldMetadataId: '', + kanbanAggregateOperation: AGGREGATE_OPERATIONS.count, + icon: '', + kanbanAggregateOperationFieldMetadataId: '', + position: 0, + __typename: 'View', + }; + + it('should correctly map single record filter group', () => { + const recordFilterGroups: RecordFilterGroup[] = [ + { + id: 'filter-group-1', + parentRecordFilterGroupId: null, + logicalOperator: RecordFilterGroupLogicalOperator.AND, + positionInRecordFilterGroup: 0, + }, + ]; + + const expectedViewFilterGroups: ViewFilterGroup[] = [ + { + id: 'filter-group-1', + parentViewFilterGroupId: null, + logicalOperator: ViewFilterGroupLogicalOperator.AND, + positionInViewFilterGroup: 0, + viewId: 'view-1', + __typename: 'ViewFilterGroup', + }, + ]; + + const mappedRecordFilterGroups = recordFilterGroups.map( + (recordFilterGroup) => + mapRecordFilterGroupToViewFilterGroup({ + recordFilterGroup, + view: mockView, + }), + ); + + expect(mappedRecordFilterGroups).toEqual(expectedViewFilterGroups); + }); + + it('should correctly map multiple record filter groups with a parent', () => { + const recordFilterGroups: RecordFilterGroup[] = [ + { + id: 'filter-group-parent-1', + parentRecordFilterGroupId: null, + logicalOperator: RecordFilterGroupLogicalOperator.OR, + positionInRecordFilterGroup: 0, + }, + { + id: 'filter-group-child-1', + parentRecordFilterGroupId: 'filter-group-parent-1', + logicalOperator: RecordFilterGroupLogicalOperator.AND, + positionInRecordFilterGroup: 1, + }, + { + id: 'filter-group-child-2', + parentRecordFilterGroupId: 'filter-group-parent-1', + logicalOperator: RecordFilterGroupLogicalOperator.AND, + positionInRecordFilterGroup: 2, + }, + ]; + + const expectedViewFilterGroups: ViewFilterGroup[] = [ + { + id: 'filter-group-parent-1', + parentViewFilterGroupId: null, + logicalOperator: ViewFilterGroupLogicalOperator.OR, + positionInViewFilterGroup: 0, + viewId: 'view-1', + __typename: 'ViewFilterGroup', + }, + { + id: 'filter-group-child-1', + parentViewFilterGroupId: 'filter-group-parent-1', + logicalOperator: ViewFilterGroupLogicalOperator.AND, + positionInViewFilterGroup: 1, + viewId: 'view-1', + __typename: 'ViewFilterGroup', + }, + { + id: 'filter-group-child-2', + parentViewFilterGroupId: 'filter-group-parent-1', + logicalOperator: ViewFilterGroupLogicalOperator.AND, + positionInViewFilterGroup: 2, + viewId: 'view-1', + __typename: 'ViewFilterGroup', + }, + ]; + + const mappedRecordFilterGroups = recordFilterGroups.map( + (recordFilterGroup) => + mapRecordFilterGroupToViewFilterGroup({ + recordFilterGroup, + view: mockView, + }), + ); + + expect(mappedRecordFilterGroups).toEqual(expectedViewFilterGroups); + }); +}); diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.test.ts new file mode 100644 index 000000000..f965d1516 --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.test.ts @@ -0,0 +1,21 @@ +import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; +import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; +import { mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator } from '@/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator'; + +describe('mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator', () => { + it('should map correctly for AND', () => { + expect( + mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator({ + viewFilterGroupLogicalOperator: ViewFilterGroupLogicalOperator.AND, + }), + ).toEqual(RecordFilterGroupLogicalOperator.AND); + }); + + it('should map correctly for OR', () => { + expect( + mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator({ + viewFilterGroupLogicalOperator: ViewFilterGroupLogicalOperator.OR, + }), + ).toEqual(RecordFilterGroupLogicalOperator.OR); + }); +}); diff --git a/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupsToRecordFilterGroups.test.ts b/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupsToRecordFilterGroups.test.ts new file mode 100644 index 000000000..cb7cce235 --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/__tests__/mapViewFilterGroupsToRecordFilterGroups.test.ts @@ -0,0 +1,91 @@ +import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; +import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; +import { ViewFilterGroup } from '@/views/types/ViewFilterGroup'; +import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; +import { mapViewFilterGroupsToRecordFilterGroups } from '@/views/utils/mapViewFilterGroupsToRecordFilterGroups'; + +describe('mapViewFilterGroupsToRecordFilterGroups', () => { + it('should map empty array to empty array', () => { + expect(mapViewFilterGroupsToRecordFilterGroups([])).toEqual([]); + }); + + it('should map correctly for single group', () => { + const viewFilterGroups: ViewFilterGroup[] = [ + { + id: 'filter-group-1', + parentViewFilterGroupId: null, + logicalOperator: ViewFilterGroupLogicalOperator.AND, + positionInViewFilterGroup: 0, + viewId: 'view-1', + __typename: 'ViewFilterGroup', + }, + ]; + + const expectedRecordFilterGroups: RecordFilterGroup[] = [ + { + id: 'filter-group-1', + parentRecordFilterGroupId: null, + logicalOperator: RecordFilterGroupLogicalOperator.AND, + positionInRecordFilterGroup: 0, + }, + ]; + + expect(mapViewFilterGroupsToRecordFilterGroups(viewFilterGroups)).toEqual( + expectedRecordFilterGroups, + ); + }); + + it('should map correctly for view filter groups with a parent', () => { + const viewFilterGroups: ViewFilterGroup[] = [ + { + id: 'filter-group-parent-1', + parentViewFilterGroupId: null, + logicalOperator: ViewFilterGroupLogicalOperator.OR, + positionInViewFilterGroup: 0, + viewId: 'view-1', + __typename: 'ViewFilterGroup', + }, + { + id: 'filter-group-child-1', + parentViewFilterGroupId: 'filter-group-parent-1', + logicalOperator: ViewFilterGroupLogicalOperator.AND, + positionInViewFilterGroup: 1, + viewId: 'view-1', + __typename: 'ViewFilterGroup', + }, + { + id: 'filter-group-child-2', + parentViewFilterGroupId: 'filter-group-parent-1', + logicalOperator: ViewFilterGroupLogicalOperator.AND, + positionInViewFilterGroup: 2, + viewId: 'view-1', + __typename: 'ViewFilterGroup', + }, + ]; + + const expectedRecordFilterGroups: RecordFilterGroup[] = [ + { + id: 'filter-group-parent-1', + parentRecordFilterGroupId: null, + logicalOperator: RecordFilterGroupLogicalOperator.OR, + positionInRecordFilterGroup: 0, + }, + { + id: 'filter-group-child-1', + parentRecordFilterGroupId: 'filter-group-parent-1', + logicalOperator: RecordFilterGroupLogicalOperator.AND, + positionInRecordFilterGroup: 1, + }, + { + id: 'filter-group-child-2', + parentRecordFilterGroupId: 'filter-group-parent-1', + logicalOperator: RecordFilterGroupLogicalOperator.AND, + positionInRecordFilterGroup: 2, + }, + ]; + + expect(mapViewFilterGroupsToRecordFilterGroups(viewFilterGroups)).toEqual( + expectedRecordFilterGroups, + ); + }); +}); diff --git a/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.ts b/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.ts new file mode 100644 index 000000000..976a63bc9 --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator.ts @@ -0,0 +1,14 @@ +import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; +import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; + +export const mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator = + ({ + recordFilterGroupLogicalOperator, + }: { + recordFilterGroupLogicalOperator: RecordFilterGroupLogicalOperator; + }) => { + return recordFilterGroupLogicalOperator === + RecordFilterGroupLogicalOperator.AND + ? ViewFilterGroupLogicalOperator.AND + : ViewFilterGroupLogicalOperator.OR; + }; diff --git a/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupToViewFilterGroup.ts b/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupToViewFilterGroup.ts new file mode 100644 index 000000000..02cf7f7ec --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/mapRecordFilterGroupToViewFilterGroup.ts @@ -0,0 +1,24 @@ +import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; +import { View } from '@/views/types/View'; +import { ViewFilterGroup } from '@/views/types/ViewFilterGroup'; +import { mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator } from '@/views/utils/mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator'; + +export const mapRecordFilterGroupToViewFilterGroup = ({ + recordFilterGroup, + view, +}: { + recordFilterGroup: RecordFilterGroup; + view: Pick; +}): ViewFilterGroup => { + return { + __typename: 'ViewFilterGroup', + id: recordFilterGroup.id, + logicalOperator: + mapRecordFilterGroupLogicalOperatorToViewFilterGroupLogicalOperator({ + recordFilterGroupLogicalOperator: recordFilterGroup.logicalOperator, + }), + viewId: view.id, + parentViewFilterGroupId: recordFilterGroup.parentRecordFilterGroupId, + positionInViewFilterGroup: recordFilterGroup.positionInRecordFilterGroup, + }; +}; diff --git a/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.ts b/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.ts new file mode 100644 index 000000000..316b6d085 --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator.ts @@ -0,0 +1,13 @@ +import { RecordFilterGroupLogicalOperator } from '@/object-record/record-filter-group/types/RecordFilterGroupLogicalOperator'; +import { ViewFilterGroupLogicalOperator } from '@/views/types/ViewFilterGroupLogicalOperator'; + +export const mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator = + ({ + viewFilterGroupLogicalOperator, + }: { + viewFilterGroupLogicalOperator: ViewFilterGroupLogicalOperator; + }) => { + return viewFilterGroupLogicalOperator === ViewFilterGroupLogicalOperator.AND + ? RecordFilterGroupLogicalOperator.AND + : RecordFilterGroupLogicalOperator.OR; + }; diff --git a/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupsToRecordFilterGroups.ts b/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupsToRecordFilterGroups.ts new file mode 100644 index 000000000..f11a0b0da --- /dev/null +++ b/packages/twenty-front/src/modules/views/utils/mapViewFilterGroupsToRecordFilterGroups.ts @@ -0,0 +1,21 @@ +import { RecordFilterGroup } from '@/object-record/record-filter-group/types/RecordFilterGroup'; +import { ViewFilterGroup } from '@/views/types/ViewFilterGroup'; +import { mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator } from '@/views/utils/mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator'; + +export const mapViewFilterGroupsToRecordFilterGroups = ( + viewFilterGroups: ViewFilterGroup[], +): RecordFilterGroup[] => { + return viewFilterGroups.map((viewFilterGroup) => { + const recordFilterGroupLogicalOperator = + mapViewFilterGroupLogicalOperatorToRecordFilterGroupLogicalOperator({ + viewFilterGroupLogicalOperator: viewFilterGroup.logicalOperator, + }); + + return { + id: viewFilterGroup.id, + parentRecordFilterGroupId: viewFilterGroup.parentViewFilterGroupId, + logicalOperator: recordFilterGroupLogicalOperator, + positionInRecordFilterGroup: viewFilterGroup.positionInViewFilterGroup, + }; + }); +};