[Requires "warm" cache flush (no immediate downtime before flush)] Migrate viewGroup.fieldMetadataId -> view.mainGroupByFieldMetadataId (1/3) (#16206)

In this PR (1/3)
- introduce view.mainGroupByFieldMetadataId as the new reference
determining which fieldMetadataId is used in a grouped view, in order to
deprecate viewGroup.fieldMetadataId which creates inconsistencies.
view.mainGroupByFieldMetadataId is now filled at every view creation,
though not in use yet.
- Introduce a command to backfill view.mainGroupByFieldMetadataId for
existing views + delete all viewGroup.fieldMetadataId with a
fieldMetadataId that is not view.mainGroupByFieldMetadataId. (It should
concern 37 active workspaces)
- Temporarily disable the option to change a grouped view's
fieldMetadataId as for now it creates inconsistencies. This feature can
be reintroduced when we have done the full migration.

In a next PR
- (2/3) use view.mainGroupByFieldMetadataId instead of
viewGroup.fieldMetadataId. In FE we may keep viewGroup.fieldMetadataId
as a state (TBD). View groups will now be created / deleted as a side
effect of view's mainGroupByFieldMetadataId update.
- (3/3) remove viewGroup.fieldMetadataId

---------

Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
Marie
2025-12-02 16:31:07 +01:00
committed by GitHub
parent aa729a2a0a
commit 77409b6eb2
71 changed files with 484 additions and 99 deletions
@@ -37,7 +37,7 @@ describe('mapRecordFilterGroupToViewFilterGroup', () => {
viewFields: [],
viewGroups: [],
viewSorts: [],
kanbanFieldMetadataId: '',
mainGroupByFieldMetadataId: '',
kanbanAggregateOperation: AggregateOperations.COUNT,
icon: '',
kanbanAggregateOperationFieldMetadataId: '',
@@ -38,7 +38,7 @@ export const convertCoreViewToView = (
convertCoreViewFilterGroupToViewFilterGroup,
),
viewSorts: coreView.viewSorts,
kanbanFieldMetadataId: '',
mainGroupByFieldMetadataId: coreView.mainGroupByFieldMetadataId ?? null,
kanbanAggregateOperation: coreView.kanbanAggregateOperation ?? null,
kanbanAggregateOperationFieldMetadataId:
coreView.kanbanAggregateOperationFieldMetadataId ?? null,
@@ -16,7 +16,7 @@ export const getObjectMetadataItemViews = (
key: view.key,
position: view.position,
objectMetadataId: view.objectMetadataId,
kanbanFieldMetadataId: view.kanbanFieldMetadataId,
mainGroupByFieldMetadataId: view.mainGroupByFieldMetadataId,
kanbanAggregateOperation: view.kanbanAggregateOperation,
kanbanAggregateOperationFieldMetadataId:
view.kanbanAggregateOperationFieldMetadataId,
@@ -4,8 +4,8 @@ import {
RecordGroupDefinitionType,
} from '@/object-record/record-group/types/RecordGroupDefinition';
import { type ViewGroup } from '@/views/types/ViewGroup';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { isDefined } from 'twenty-shared/utils';
import { FieldMetadataType } from '~/generated-metadata/graphql';
export const mapViewGroupsToRecordGroupDefinitions = ({
objectMetadataItem,
@@ -36,6 +36,10 @@ export const mapViewGroupsToRecordGroupDefinitions = ({
const recordGroupDefinitionsFromViewGroups = viewGroups
.map((viewGroup) => {
if (viewGroup.fieldMetadataId !== selectFieldMetadataItem.id) {
return null;
}
const selectedOption = selectFieldMetadataItem.options?.find(
(option) => option.value === viewGroup.fieldValue,
);