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',