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 4869b40fa..c3904b80e 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,4 +1,5 @@
import { getFilterTypeFromFieldType } from '@/object-metadata/utils/formatFieldMetadataItemsAsFilterDefinitions';
+import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
import { useDefaultFieldMetadataItemForFilter } from '@/object-record/advanced-filter/hooks/useDefaultFieldMetadataItemForFilter';
import { getAdvancedFilterAddFilterRuleSelectDropdownId } from '@/object-record/advanced-filter/utils/getAdvancedFilterAddFilterRuleSelectDropdownId';
import { useUpsertRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useUpsertRecordFilterGroup';
@@ -16,12 +17,10 @@ import { v4 } from 'uuid';
type AdvancedFilterAddFilterRuleSelectProps = {
recordFilterGroup: RecordFilterGroup;
- lastChildPosition?: number;
};
export const AdvancedFilterAddFilterRuleSelect = ({
recordFilterGroup,
- lastChildPosition = 0,
}: AdvancedFilterAddFilterRuleSelectProps) => {
const dropdownId = getAdvancedFilterAddFilterRuleSelectDropdownId(
recordFilterGroup.id,
@@ -33,6 +32,10 @@ export const AdvancedFilterAddFilterRuleSelect = ({
const { upsertRecordFilter } = useUpsertRecordFilter();
+ const { lastChildPosition } = useChildRecordFiltersAndRecordFilterGroups({
+ recordFilterGroupId: recordFilterGroup.id,
+ });
+
const newPositionInRecordFilterGroup = lastChildPosition + 1;
const { closeDropdown } = useDropdown(dropdownId);
diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroup.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroup.tsx
index b2d8244b1..bc90f61c2 100644
--- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroup.tsx
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRecordFilterGroup.tsx
@@ -34,13 +34,10 @@ type AdvancedFilterRecordFilterGroupProps = {
export const AdvancedFilterRecordFilterGroup = ({
recordFilterGroupId,
}: AdvancedFilterRecordFilterGroupProps) => {
- const {
- currentRecordFilterGroup,
- childRecordFiltersAndRecordFilterGroups,
- lastChildPosition,
- } = useChildRecordFiltersAndRecordFilterGroups({
- recordFilterGroupId,
- });
+ const { currentRecordFilterGroup, childRecordFiltersAndRecordFilterGroups } =
+ useChildRecordFiltersAndRecordFilterGroups({
+ recordFilterGroupId,
+ });
if (!currentRecordFilterGroup) {
return null;
@@ -66,7 +63,6 @@ export const AdvancedFilterRecordFilterGroup = ({
))}
);
diff --git a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRootLevelViewFilterGroup.tsx b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRootLevelViewFilterGroup.tsx
index d0d292266..a7f6fe0c9 100644
--- a/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRootLevelViewFilterGroup.tsx
+++ b/packages/twenty-front/src/modules/object-record/advanced-filter/components/AdvancedFilterRootLevelViewFilterGroup.tsx
@@ -6,6 +6,8 @@ import { AdvancedFilterRecordFilterGroup } from '@/object-record/advanced-filter
import { AdvancedFilterViewFilter } from '@/object-record/advanced-filter/components/AdvancedFilterViewFilter';
import { useChildRecordFiltersAndRecordFilterGroups } from '@/object-record/advanced-filter/hooks/useChildRecordFiltersAndRecordFilterGroups';
import { isRecordFilterGroupChildARecordFilterGroup } from '@/object-record/advanced-filter/utils/isRecordFilterGroupChildARecordFilterGroup';
+import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
import styled from '@emotion/styled';
import { isDefined } from 'twenty-shared';
@@ -29,19 +31,20 @@ const StyledContainer = styled.div<{ isGrayBackground?: boolean }>`
overflow: hidden;
`;
-type AdvancedFilterRootLevelViewFilterGroupProps = {
- rootLevelRecordFilterGroupId: string;
-};
+export const AdvancedFilterRootLevelViewFilterGroup = () => {
+ const currentRecordFilterGroups = useRecoilComponentValueV2(
+ currentRecordFilterGroupsComponentState,
+ );
+
+ const rootRecordFilterGroupId = currentRecordFilterGroups.find(
+ (recordFilterGroup) => !recordFilterGroup.parentRecordFilterGroupId,
+ )?.id;
-export const AdvancedFilterRootLevelViewFilterGroup = ({
- rootLevelRecordFilterGroupId,
-}: AdvancedFilterRootLevelViewFilterGroupProps) => {
const {
currentRecordFilterGroup: rootLevelRecordFilterGroup,
childRecordFiltersAndRecordFilterGroups,
- lastChildPosition,
} = useChildRecordFiltersAndRecordFilterGroups({
- recordFilterGroupId: rootLevelRecordFilterGroupId,
+ recordFilterGroupId: rootRecordFilterGroupId,
});
if (!isDefined(rootLevelRecordFilterGroup)) {
@@ -50,34 +53,38 @@ export const AdvancedFilterRootLevelViewFilterGroup = ({
return (
- {childRecordFiltersAndRecordFilterGroups.map((child, i) =>
- isRecordFilterGroupChildARecordFilterGroup(child) ? (
-
-
-
-
-
- ) : (
-
-
-
-
-
- ),
+ {childRecordFiltersAndRecordFilterGroups.map(
+ (recordFilterGroupChild, recordFilterGroupChildIndex) =>
+ isRecordFilterGroupChildARecordFilterGroup(recordFilterGroupChild) ? (
+
+
+
+
+
+ ) : (
+
+
+
+
+
+ ),
)}
);
diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AdvancedFilterButton.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AdvancedFilterButton.tsx
index f6e1c5af5..0bd4dd0e3 100644
--- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AdvancedFilterButton.tsx
+++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/AdvancedFilterButton.tsx
@@ -91,14 +91,14 @@ export const AdvancedFilterButton = () => {
const alreadyHasAdvancedFilterGroup = currentRecordFilterGroups.length > 0;
if (!alreadyHasAdvancedFilterGroup) {
- const newViewFilterGroup = {
+ const newRecordFilterGroup = {
id: v4(),
viewId: currentView.id,
logicalOperator: ViewFilterGroupLogicalOperator.AND,
};
upsertRecordFilterGroup({
- id: newViewFilterGroup.id,
+ id: newRecordFilterGroup.id,
logicalOperator: RecordFilterGroupLogicalOperator.AND,
});
@@ -127,9 +127,10 @@ export const AdvancedFilterButton = () => {
operand: firstOperand,
value: '',
displayValue: '',
- recordFilterGroupId: newViewFilterGroup.id,
+ recordFilterGroupId: newRecordFilterGroup.id,
type: getFilterTypeFromFieldType(defaultFieldMetadataItem.type),
label: defaultFieldMetadataItem.label,
+ positionInRecordFilterGroup: 1,
});
}
diff --git a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextSearchInput.tsx b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextSearchInput.tsx
index 3d7af159a..c08d55278 100644
--- a/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextSearchInput.tsx
+++ b/packages/twenty-front/src/modules/object-record/object-filter-dropdown/components/ObjectFilterDropdownTextSearchInput.tsx
@@ -69,6 +69,8 @@ export const ObjectFilterDropdownTextSearchInput = () => {
fieldMetadataItemUsedInDropdown.type,
),
label: fieldMetadataItemUsedInDropdown.label,
+ positionInRecordFilterGroup:
+ selectedFilter?.positionInRecordFilterGroup,
});
}}
/>
diff --git a/packages/twenty-front/src/modules/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters.ts b/packages/twenty-front/src/modules/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters.ts
index 3a8a178aa..17f529935 100644
--- a/packages/twenty-front/src/modules/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters.ts
+++ b/packages/twenty-front/src/modules/object-record/record-filter/utils/findDuplicateRecordFilterInNonAdvancedRecordFilters.ts
@@ -1,4 +1,5 @@
import { RecordFilter } from '@/object-record/record-filter/types/RecordFilter';
+import { isDefined } from 'twenty-shared';
import { compareStrictlyExceptForNullAndUndefined } from '~/utils/compareStrictlyExceptForNullAndUndefined';
export const findDuplicateRecordFilterInNonAdvancedRecordFilters = ({
@@ -10,17 +11,19 @@ export const findDuplicateRecordFilterInNonAdvancedRecordFilters = ({
fieldMetadataItemId: string;
subFieldName?: string | null | undefined;
}): RecordFilter | undefined => {
- const duplicateFilterInCurrentRecordFilters = recordFilters.find(
- (recordFilter) =>
- compareStrictlyExceptForNullAndUndefined(
- recordFilter.fieldMetadataId,
- fieldMetadataItemId,
- ) &&
- compareStrictlyExceptForNullAndUndefined(
- recordFilter.subFieldName,
- subFieldName,
- ),
- );
+ const duplicateFilterInCurrentRecordFilters = recordFilters
+ .filter((recordFilter) => !isDefined(recordFilter.recordFilterGroupId))
+ .find(
+ (recordFilter) =>
+ compareStrictlyExceptForNullAndUndefined(
+ recordFilter.fieldMetadataId,
+ fieldMetadataItemId,
+ ) &&
+ compareStrictlyExceptForNullAndUndefined(
+ recordFilter.subFieldName,
+ subFieldName,
+ ),
+ );
return duplicateFilterInCurrentRecordFilters;
};
diff --git a/packages/twenty-front/src/modules/views/components/AdvancedFilterChip.tsx b/packages/twenty-front/src/modules/views/components/AdvancedFilterChip.tsx
index 733084aca..915ac7c99 100644
--- a/packages/twenty-front/src/modules/views/components/AdvancedFilterChip.tsx
+++ b/packages/twenty-front/src/modules/views/components/AdvancedFilterChip.tsx
@@ -1,27 +1,62 @@
import { IconFilterCog } from 'twenty-ui';
+import { useRemoveRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useRemoveRecordFilterGroup';
+import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
+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';
import { SortOrFilterChip } from '@/views/components/SortOrFilterChip';
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
import { plural } from 'pluralize';
+import { isDefined } from 'twenty-shared';
+import { isNonEmptyArray } from '~/utils/isNonEmptyArray';
-type AdvancedFilterChipProps = {
- onRemove: () => void;
- advancedFilterCount?: number;
-};
+export const AdvancedFilterChip = () => {
+ const currentRecordFilterGroups = useRecoilComponentValueV2(
+ currentRecordFilterGroupsComponentState,
+ );
+
+ const currentRecordFilters = useRecoilComponentValueV2(
+ currentRecordFiltersComponentState,
+ );
+
+ const advancedRecordFilterIds = currentRecordFilters
+ .filter((recordFilter) => isDefined(recordFilter.recordFilterGroupId))
+ .map((recordFilter) => recordFilter.id);
+
+ const { removeRecordFilter } = useRemoveRecordFilter();
+ const { removeRecordFilterGroup } = useRemoveRecordFilterGroup();
+
+ const handleRemoveClick = () => {
+ if (!isNonEmptyArray(advancedRecordFilterIds)) {
+ throw new Error('No advanced view filters to remove');
+ }
+
+ const viewFilterGroupIds = currentRecordFilterGroups.map(
+ (recordFilterGroup) => recordFilterGroup.id,
+ );
+
+ for (const viewFilterGroupId of viewFilterGroupIds) {
+ removeRecordFilterGroup(viewFilterGroupId);
+ }
+
+ for (const recordFilterId of advancedRecordFilterIds) {
+ removeRecordFilter({ recordFilterId });
+ }
+ };
+
+ const advancedFilterCount = advancedRecordFilterIds.length;
-export const AdvancedFilterChip = ({
- onRemove,
- advancedFilterCount,
-}: AdvancedFilterChipProps) => {
const labelText = 'advanced rule';
- const chipLabel = `${advancedFilterCount ?? 0} ${advancedFilterCount === 1 ? labelText : plural(labelText)}`;
+ const chipLabel = `${advancedFilterCount} ${advancedFilterCount === 1 ? labelText : plural(labelText)}`;
+
return (
);
};
diff --git a/packages/twenty-front/src/modules/views/components/AdvancedFilterDropdownButton.tsx b/packages/twenty-front/src/modules/views/components/AdvancedFilterDropdownButton.tsx
index 2173d7cd0..59729a31a 100644
--- a/packages/twenty-front/src/modules/views/components/AdvancedFilterDropdownButton.tsx
+++ b/packages/twenty-front/src/modules/views/components/AdvancedFilterDropdownButton.tsx
@@ -1,58 +1,16 @@
-import { useCallback } from 'react';
-
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { AdvancedFilterRootLevelViewFilterGroup } from '@/object-record/advanced-filter/components/AdvancedFilterRootLevelViewFilterGroup';
-import { useRemoveRecordFilterGroup } from '@/object-record/record-filter-group/hooks/useRemoveRecordFilterGroup';
import { currentRecordFilterGroupsComponentState } from '@/object-record/record-filter-group/states/currentRecordFilterGroupsComponentState';
-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';
import { AdvancedFilterChip } from '@/views/components/AdvancedFilterChip';
import { ADVANCED_FILTER_DROPDOWN_ID } from '@/views/constants/AdvancedFilterDropdownId';
-import { isDefined } from 'twenty-shared';
export const AdvancedFilterDropdownButton = () => {
- const { removeRecordFilterGroup } = useRemoveRecordFilterGroup();
-
const currentRecordFilterGroups = useRecoilComponentValueV2(
currentRecordFilterGroupsComponentState,
);
- const currentRecordFilters = useRecoilComponentValueV2(
- currentRecordFiltersComponentState,
- );
-
- const advancedRecordFilterIds = currentRecordFilters
- .filter((recordFilter) => isDefined(recordFilter.recordFilterGroupId))
- .map((recordFilter) => recordFilter.id);
-
- const { removeRecordFilter } = useRemoveRecordFilter();
-
- const removeAdvancedFilter = useCallback(async () => {
- if (!advancedRecordFilterIds) {
- throw new Error('No advanced view filters to remove');
- }
-
- const viewFilterGroupIds =
- currentRecordFilterGroups?.map(
- (recordFilterGroup) => recordFilterGroup.id,
- ) ?? [];
-
- for (const viewFilterGroupId of viewFilterGroupIds) {
- removeRecordFilterGroup(viewFilterGroupId);
- }
-
- for (const recordFilterId of advancedRecordFilterIds) {
- removeRecordFilter({ recordFilterId });
- }
- }, [
- advancedRecordFilterIds,
- removeRecordFilterGroup,
- removeRecordFilter,
- currentRecordFilterGroups,
- ]);
-
const outermostRecordFilterGroupId = currentRecordFilterGroups.find(
(recordFilterGroup) => !recordFilterGroup.parentRecordFilterGroupId,
)?.id;
@@ -64,17 +22,8 @@ export const AdvancedFilterDropdownButton = () => {
return (
- }
- dropdownComponents={
-
- }
+ clickableComponent={}
+ dropdownComponents={}
dropdownHotkeyScope={{ scope: ADVANCED_FILTER_DROPDOWN_ID }}
dropdownOffset={{ y: 8, x: 0 }}
dropdownPlacement="bottom-start"
diff --git a/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts b/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts
index e42b1636d..8bc32011c 100644
--- a/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts
+++ b/packages/twenty-front/src/modules/views/hooks/useCreateViewFromCurrentView.ts
@@ -19,7 +19,9 @@ import { isPersistingViewFieldsState } from '@/views/states/isPersistingViewFiel
import { GraphQLView } from '@/views/types/GraphQLView';
import { View } from '@/views/types/View';
import { ViewGroup } from '@/views/types/ViewGroup';
+import { ViewSort } from '@/views/types/ViewSort';
import { ViewType } from '@/views/types/ViewType';
+import { duplicateViewFiltersAndViewFilterGroups } from '@/views/utils/duplicateViewFiltersAndViewFilterGroups';
import { mapRecordFilterGroupToViewFilterGroup } from '@/views/utils/mapRecordFilterGroupToViewFilterGroup';
import { mapRecordFilterToViewFilter } from '@/views/utils/mapRecordFilterToViewFilter';
import { mapRecordSortToViewSort } from '@/views/utils/mapRecordSortToViewSort';
@@ -167,7 +169,7 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
}
if (shouldCopyFiltersAndSortsAndAggregate === true) {
- const viewFilterGroupsToCreate = currentRecordFilterGroups.map(
+ const viewFilterGroupsToCopy = currentRecordFilterGroups.map(
(recordFilterGroup) =>
mapRecordFilterGroupToViewFilterGroup({
recordFilterGroup,
@@ -175,16 +177,31 @@ export const useCreateViewFromCurrentView = (viewBarComponentId?: string) => {
}),
);
- const viewSortsToCreate = currentRecordSorts.map(
- mapRecordSortToViewSort,
- );
- const viewFiltersToCreate = currentRecordFilters.map(
+ const viewFiltersToCopy = currentRecordFilters.map(
mapRecordFilterToViewFilter,
);
- await createViewSortRecords(viewSortsToCreate, newView);
- await createViewFilterRecords(viewFiltersToCreate, newView);
+ const {
+ duplicatedViewFilterGroups: viewFilterGroupsToCreate,
+ duplicatedViewFilters: viewFiltersToCreate,
+ } = duplicateViewFiltersAndViewFilterGroups({
+ viewFilterGroupsToDuplicate: viewFilterGroupsToCopy,
+ viewFiltersToDuplicate: viewFiltersToCopy,
+ });
+
+ const viewSortsToCreate = currentRecordSorts
+ .map(mapRecordSortToViewSort)
+ .map(
+ (viewSort) =>
+ ({
+ ...viewSort,
+ id: v4(),
+ }) satisfies ViewSort,
+ );
+
await createViewFilterGroupRecords(viewFilterGroupsToCreate, newView);
+ await createViewFilterRecords(viewFiltersToCreate, newView);
+ await createViewSortRecords(viewSortsToCreate, newView);
}
await findManyRecords();
diff --git a/packages/twenty-front/src/modules/views/utils/duplicateViewFiltersAndViewFilterGroups.ts b/packages/twenty-front/src/modules/views/utils/duplicateViewFiltersAndViewFilterGroups.ts
new file mode 100644
index 000000000..84ad0cbcf
--- /dev/null
+++ b/packages/twenty-front/src/modules/views/utils/duplicateViewFiltersAndViewFilterGroups.ts
@@ -0,0 +1,82 @@
+import { ViewFilter } from '@/views/types/ViewFilter';
+import { ViewFilterGroup } from '@/views/types/ViewFilterGroup';
+import { isDefined } from 'twenty-shared';
+import { v4 } from 'uuid';
+
+export const duplicateViewFiltersAndViewFilterGroups = ({
+ viewFilterGroupsToDuplicate,
+ viewFiltersToDuplicate,
+}: {
+ viewFiltersToDuplicate: ViewFilter[];
+ viewFilterGroupsToDuplicate: ViewFilterGroup[];
+}) => {
+ const oldViewFilterGroupIdToNewViewFilterGroupIdMap = new Map<
+ string,
+ string
+ >();
+
+ for (const viewFilterGroupToCopy of viewFilterGroupsToDuplicate) {
+ oldViewFilterGroupIdToNewViewFilterGroupIdMap.set(
+ viewFilterGroupToCopy.id,
+ v4(),
+ );
+ }
+
+ const duplicatedViewFilterGroups = viewFilterGroupsToDuplicate.map(
+ (viewFilterGroupToCopy) => {
+ const newViewFilterGroupId =
+ oldViewFilterGroupIdToNewViewFilterGroupIdMap.get(
+ viewFilterGroupToCopy.id,
+ );
+
+ if (
+ !isDefined(viewFilterGroupToCopy.id) ||
+ !isDefined(newViewFilterGroupId)
+ ) {
+ throw new Error(
+ `Failed to find view filter group to copy for id ${viewFilterGroupToCopy.id} this shouldn't happen`,
+ );
+ }
+
+ const parentViewFilterGroupIdToCopy =
+ viewFilterGroupToCopy.parentViewFilterGroupId;
+
+ const newParentViewFilterGroupId = isDefined(
+ parentViewFilterGroupIdToCopy,
+ )
+ ? oldViewFilterGroupIdToNewViewFilterGroupIdMap.get(
+ parentViewFilterGroupIdToCopy,
+ )
+ : undefined;
+
+ const newViewFilterGroup = {
+ ...viewFilterGroupToCopy,
+ id: newViewFilterGroupId,
+ parentViewFilterGroupId: newParentViewFilterGroupId,
+ } satisfies ViewFilterGroup;
+
+ return newViewFilterGroup;
+ },
+ );
+
+ const duplicatedViewFilters = viewFiltersToDuplicate.map((viewFilter) => {
+ const parentViewFilterGroupIdToCopy = viewFilter.viewFilterGroupId;
+
+ const newParentViewFilterGroupId = isDefined(parentViewFilterGroupIdToCopy)
+ ? oldViewFilterGroupIdToNewViewFilterGroupIdMap.get(
+ parentViewFilterGroupIdToCopy,
+ )
+ : undefined;
+
+ return {
+ ...viewFilter,
+ id: v4(),
+ viewFilterGroupId: newParentViewFilterGroupId,
+ } satisfies ViewFilter;
+ });
+
+ return {
+ duplicatedViewFilterGroups,
+ duplicatedViewFilters,
+ };
+};
diff --git a/packages/twenty-server/src/modules/view/standard-objects/view-filter-group.workspace-entity.ts b/packages/twenty-server/src/modules/view/standard-objects/view-filter-group.workspace-entity.ts
index 2580ed258..f807eca53 100644
--- a/packages/twenty-server/src/modules/view/standard-objects/view-filter-group.workspace-entity.ts
+++ b/packages/twenty-server/src/modules/view/standard-objects/view-filter-group.workspace-entity.ts
@@ -85,7 +85,7 @@ export class ViewFilterGroupWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: VIEW_FILTER_GROUP_STANDARD_FIELD_IDS.positionInViewFilterGroup,
- type: FieldMetadataType.POSITION,
+ type: FieldMetadataType.NUMBER,
label: msg`Position in view filter group`,
description: msg`Position in the parent view filter group`,
icon: 'IconHierarchy2',
diff --git a/packages/twenty-server/src/modules/view/standard-objects/view-filter.workspace-entity.ts b/packages/twenty-server/src/modules/view/standard-objects/view-filter.workspace-entity.ts
index f4949511c..88387de62 100644
--- a/packages/twenty-server/src/modules/view/standard-objects/view-filter.workspace-entity.ts
+++ b/packages/twenty-server/src/modules/view/standard-objects/view-filter.workspace-entity.ts
@@ -87,7 +87,7 @@ export class ViewFilterWorkspaceEntity extends BaseWorkspaceEntity {
@WorkspaceField({
standardId: VIEW_FILTER_STANDARD_FIELD_IDS.positionInViewFilterGroup,
- type: FieldMetadataType.POSITION,
+ type: FieldMetadataType.NUMBER,
label: msg`Position in view filter group`,
description: msg`Position in the view filter group`,
icon: 'IconHierarchy2',