[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
@@ -1443,6 +1443,9 @@ export const STANDARD_OBJECTS = {
universalIdentifier:
VIEW_STANDARD_FIELD_IDS.kanbanAggregateOperationFieldMetadataId,
},
mainGroupByFieldMetadataId: {
universalIdentifier: VIEW_STANDARD_FIELD_IDS.mainGroupByFieldMetadataId,
},
position: { universalIdentifier: VIEW_STANDARD_FIELD_IDS.position },
isCompact: { universalIdentifier: VIEW_STANDARD_FIELD_IDS.isCompact },
openRecordIn: {
@@ -1,7 +1,7 @@
import {
FieldMetadataType,
FieldMetadataSettings,
FieldMetadataOptions,
FieldMetadataSettings,
FieldMetadataType,
} from 'twenty-shared/types';
import {
Check,
@@ -212,4 +212,7 @@ export class FieldMetadataEntity<
@OneToMany(() => ViewEntity, (view) => view.calendarFieldMetadata)
calendarViews: Relation<ViewEntity[]>;
@OneToMany(() => ViewEntity, (view) => view.mainGroupByFieldMetadata)
mainGroupByFieldMetadataViews: Relation<ViewEntity[]>;
}
@@ -41,6 +41,10 @@ export const ALL_METADATA_RELATED_METADATA_BY_FOREIGN_KEY = {
metadataName: 'fieldMetadata',
flatEntityForeignKeyAggregator: 'calendarViewIds',
},
mainGroupByFieldMetadataId: {
metadataName: 'fieldMetadata',
flatEntityForeignKeyAggregator: 'mainGroupByFieldMetadataViewIds',
},
objectMetadataId: {
metadataName: 'objectMetadata',
flatEntityForeignKeyAggregator: 'viewIds',
@@ -25,6 +25,7 @@ export const getFlatFieldMetadataMock = <T extends FieldMetadataType>(
kanbanAggregateOperationViewIds: [],
viewFieldIds: [],
createdAt,
mainGroupByFieldMetadataViewIds: [],
updatedAt: createdAt,
defaultValue: null,
options: null,
@@ -33,6 +33,7 @@ export const getRelationTargetFlatFieldMetadataMock = ({
return {
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
viewFilterIds: [],
viewGroupIds: [],
viewFieldIds: [],
@@ -120,6 +120,7 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
"isUnique": null,
"kanbanAggregateOperationViewIds": [],
"label": "newFieldLabel",
"mainGroupByFieldMetadataViewIds": [],
"morphId": Any<String>,
"name": "newFieldPets",
"objectMetadataId": Any<String>,
@@ -156,6 +157,7 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
"isUnique": null,
"kanbanAggregateOperationViewIds": [],
"label": "Pet",
"mainGroupByFieldMetadataViewIds": [],
"morphId": null,
"name": "pet",
"objectMetadataId": Any<String>,
@@ -194,6 +196,7 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
"isUnique": null,
"kanbanAggregateOperationViewIds": [],
"label": "newFieldLabel",
"mainGroupByFieldMetadataViewIds": [],
"morphId": Any<String>,
"name": "newFieldCompanies",
"objectMetadataId": Any<String>,
@@ -230,6 +233,7 @@ exports[`fromCreateFieldInputToFlatFieldMetadatasToCreate MORPH_RELATION test su
"isUnique": null,
"kanbanAggregateOperationViewIds": [],
"label": "Company",
"mainGroupByFieldMetadataViewIds": [],
"morphId": null,
"name": "company",
"objectMetadataId": Any<String>,
@@ -68,6 +68,7 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceCachePro
'id',
'kanbanAggregateOperationFieldMetadataId',
'calendarFieldMetadataId',
'mainGroupByFieldMetadataId',
],
withDeleted: true,
}),
@@ -79,6 +80,7 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceCachePro
viewGroupsByFieldId,
calendarViewsByFieldId,
kanbanViewsByFieldId,
mainGroupByFieldMetadataViewsByFieldId,
] = (
[
{
@@ -101,6 +103,10 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceCachePro
entities: views,
foreignKey: 'kanbanAggregateOperationFieldMetadataId',
},
{
entities: views,
foreignKey: 'mainGroupByFieldMetadataId',
},
] as const
).map(regroupEntitiesByRelatedEntityId);
@@ -115,6 +121,9 @@ export class WorkspaceFlatFieldMetadataMapCacheService extends WorkspaceCachePro
kanbanAggregateOperationViews:
kanbanViewsByFieldId.get(fieldMetadataEntity.id) || [],
calendarViews: calendarViewsByFieldId.get(fieldMetadataEntity.id) || [],
mainGroupByFieldMetadataViews:
mainGroupByFieldMetadataViewsByFieldId.get(fieldMetadataEntity.id) ||
[],
} as FieldMetadataEntity);
addFlatEntityToFlatEntityMapsThroughMutationOrThrow({
@@ -11,9 +11,10 @@ export const FIELD_METADATA_RELATION_PROPERTIES = [
'viewFields',
'application',
'viewFilters',
'viewGroups',
'kanbanAggregateOperationViews',
'calendarViews',
'mainGroupByFieldMetadataViews',
'viewGroups',
] as const satisfies (keyof FieldMetadataEntity)[];
export type FieldMetadataEntityRelationProperties =
@@ -24,7 +25,8 @@ export type FlatFieldMetadata<T extends FieldMetadataType = FieldMetadataType> =
universalIdentifier: string;
viewFieldIds: string[];
viewFilterIds: string[];
viewGroupIds: string[];
kanbanAggregateOperationViewIds: string[];
calendarViewIds: string[];
mainGroupByFieldMetadataViewIds: string[];
viewGroupIds: string[];
};
@@ -23,6 +23,9 @@ export const fromFieldMetadataEntityToFlatFieldMetadata = <
kanbanAggregateOperationViewIds:
fieldMetadataEntity.kanbanAggregateOperationViews.map(({ id }) => id),
calendarViewIds: fieldMetadataEntity.calendarViews.map(({ id }) => id),
mainGroupByFieldMetadataViewIds:
fieldMetadataEntity.mainGroupByFieldMetadataViews?.map(({ id }) => id) ??
[],
viewGroupIds: fieldMetadataEntity.viewGroups.map(({ id }) => id),
viewFieldIds: fieldMetadataEntity.viewFields.map(({ id }) => id),
viewFilterIds: fieldMetadataEntity.viewFilters.map(({ id }) => id),
@@ -26,6 +26,7 @@ export const getDefaultFlatFieldMetadata = ({
return {
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
viewFieldIds: [],
description: createFieldInput.description ?? null,
id: fieldMetadataId,
@@ -1,5 +1,5 @@
import { isDefined } from 'class-validator';
import { type EnumFieldMetadataType } from 'twenty-shared/types';
import { isDefined } from 'twenty-shared/utils';
import { v4 } from 'uuid';
import {
@@ -63,7 +63,8 @@ export const recomputeViewGroupsOnFlatFieldMetadataOptionsUpdate = ({
const flatViewGroupsToUpdate = updatedFieldMetadataOptions.flatMap(
({ from: fromOption, to: toOption }) =>
flatViewGroups.flatMap((flatViewGroup) =>
flatViewGroup.fieldValue === fromOption.value
flatViewGroup.fieldValue === fromOption.value &&
flatViewGroup.fieldMetadataId === fromFlatFieldMetadata.id
? { ...flatViewGroup, fieldValue: toOption.value }
: [],
),
@@ -13,4 +13,5 @@ export const FLAT_VIEW_EDITABLE_PROPERTIES = [
'calendarLayout',
'calendarFieldMetadataId',
'visibility',
'mainGroupByFieldMetadataId',
] as const satisfies (keyof FlatView)[];
@@ -44,6 +44,8 @@ export const fromCreateViewInputToFlatViewToCreate = ({
kanbanAggregateOperation: createViewInput.kanbanAggregateOperation ?? null,
kanbanAggregateOperationFieldMetadataId:
createViewInput.kanbanAggregateOperationFieldMetadataId ?? null,
mainGroupByFieldMetadataId:
createViewInput.mainGroupByFieldMetadataId ?? null,
key: createViewInput.key ?? null,
openRecordIn: createViewInput.openRecordIn ?? ViewOpenRecordIn.SIDE_PANEL,
position: createViewInput.position ?? 0,
@@ -31,6 +31,7 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
isLabelSyncedWithName: false,
isUnique: true,
objectMetadataId,
@@ -68,6 +69,7 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
isLabelSyncedWithName: false,
isUnique: false,
objectMetadataId,
@@ -105,6 +107,7 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
isLabelSyncedWithName: false,
isUnique: false,
objectMetadataId,
@@ -142,6 +145,7 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
isLabelSyncedWithName: false,
isUnique: false,
objectMetadataId,
@@ -179,6 +183,7 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
isLabelSyncedWithName: false,
isUnique: false,
objectMetadataId,
@@ -216,6 +221,7 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
isLabelSyncedWithName: false,
isUnique: false,
objectMetadataId,
@@ -252,6 +258,7 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
isLabelSyncedWithName: false,
isUnique: false,
objectMetadataId,
@@ -284,6 +291,7 @@ export const buildDefaultFlatFieldMetadatasForCustomObject = ({
const searchVectorFieldId = v4();
const searchVectorField: FlatFieldMetadata<FieldMetadataType.TS_VECTOR> = {
type: FieldMetadataType.TS_VECTOR,
mainGroupByFieldMetadataViewIds: [],
viewFieldIds: [],
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
@@ -61,6 +61,7 @@ const generateSourceFlatFieldMetadata = ({
return {
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
kanbanAggregateOperationViewIds: [],
viewFilterIds: [],
viewFieldIds: [],
@@ -128,6 +129,7 @@ const generateTargetFlatFieldMetadata = ({
return {
morphId: null,
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
viewFieldIds: [],
kanbanAggregateOperationViewIds: [],
viewFilterIds: [],
@@ -69,7 +69,7 @@ export class ViewFilterService {
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
});
const validateAndBuildResult =
const buildAndRunResult =
await this.workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
{
fromToAllFlatEntityMaps: {
@@ -92,13 +92,18 @@ export class ViewFilterService {
},
);
if (isDefined(validateAndBuildResult)) {
if (isDefined(buildAndRunResult)) {
throw new WorkspaceMigrationBuilderExceptionV2(
validateAndBuildResult,
buildAndRunResult,
'Multiple validation errors occurred while creating view filter',
);
}
this.flatEntityMapsCacheService.invalidateFlatEntityMaps({
workspaceId,
flatMapsKeys: ['flatViewFilterMaps'],
});
const { flatViewFilterMaps: recomputedExistingFlatViewFilterMaps } =
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
{
@@ -92,6 +92,11 @@ export class CreateViewInput {
@Field(() => UUIDScalarType, { nullable: true })
calendarFieldMetadataId?: string;
@IsOptional()
@IsUUID()
@Field(() => UUIDScalarType, { nullable: true })
mainGroupByFieldMetadataId?: string;
@IsOptional()
@IsEnum(ViewVisibility)
@Field(() => ViewVisibility, {
@@ -87,4 +87,9 @@ export class UpdateViewInput {
@IsEnum(ViewVisibility)
@Field(() => ViewVisibility, { nullable: true })
visibility?: ViewVisibility;
@IsOptional()
@IsUUID()
@Field(() => UUIDScalarType, { nullable: true })
mainGroupByFieldMetadataId?: string;
}
@@ -62,6 +62,9 @@ export class ViewDTO {
@Field(() => UUIDScalarType, { nullable: true })
kanbanAggregateOperationFieldMetadataId?: string | null;
@Field(() => UUIDScalarType, { nullable: true })
mainGroupByFieldMetadataId?: string | null;
@Field(() => UUIDScalarType, { nullable: true })
calendarFieldMetadataId?: string | null;
@@ -138,6 +138,20 @@ export class ViewEntity extends SyncableEntity implements Required<ViewEntity> {
@JoinColumn({ name: 'calendarFieldMetadataId' })
calendarFieldMetadata: Relation<FieldMetadataEntity>;
@Column({ nullable: true, type: 'uuid' })
mainGroupByFieldMetadataId: string | null;
@ManyToOne(
() => FieldMetadataEntity,
(fieldMetadata) => fieldMetadata.mainGroupByFieldMetadataViews,
{
onDelete: 'CASCADE',
nullable: true,
},
)
@JoinColumn({ name: 'mainGroupByFieldMetadataId' })
mainGroupByFieldMetadata: Relation<FieldMetadataEntity>;
@Column({ nullable: false, type: 'uuid' })
workspaceId: string;
@@ -151,6 +151,7 @@ describe('WorkspaceEntityManager', () => {
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
relationTargetFieldMetadataId: null,
relationTargetObjectMetadataId: null,
morphId: null,
@@ -94,6 +94,7 @@ describe('WorkspaceRepository', () => {
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
viewFieldIds: [],
mainGroupByFieldMetadataViewIds: [],
};
mockInternalContext = {
@@ -63,6 +63,7 @@ describe('getFieldMetadataIdToColumnNamesMap', () => {
viewGroupIds: [],
kanbanAggregateOperationViewIds: [],
calendarViewIds: [],
mainGroupByFieldMetadataViewIds: [],
applicationId: null,
}) as unknown as FlatFieldMetadata;
@@ -171,6 +171,7 @@ export const createCoreViews = async (
icon,
isCustom,
openRecordIn,
mainGroupByFieldMetadataId,
kanbanAggregateOperation,
kanbanAggregateOperationFieldMetadataId,
applicationId,
@@ -191,6 +192,7 @@ export const createCoreViews = async (
: ViewOpenRecordIn.SIDE_PANEL,
kanbanAggregateOperation,
kanbanAggregateOperationFieldMetadataId,
mainGroupByFieldMetadataId,
workspaceId,
anyFieldFilterValue: null,
visibility: ViewVisibility.WORKSPACE,
@@ -16,9 +16,9 @@ export interface ViewDefinition {
icon?: string;
isCustom?: boolean;
openRecordIn?: ViewOpenRecordInType;
kanbanFieldMetadataId?: string;
kanbanAggregateOperation?: AggregateOperations;
kanbanAggregateOperationFieldMetadataId?: string;
mainGroupByFieldMetadataId?: string;
calendarFieldMetadataId?: string;
calendarLayout?: string;
fields?: {
@@ -42,7 +42,6 @@ export const calendarEventsAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconCalendar',
kanbanFieldMetadataId: '',
calendarFieldMetadataId:
calendarEventObjectMetadata.fields.find(
(field) =>
@@ -43,7 +43,6 @@ export const companiesAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconList',
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -42,7 +42,6 @@ export const dashboardsAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconLayoutDashboard',
kanbanFieldMetadataId: '',
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
filters: [],
fields: [
@@ -42,7 +42,6 @@ export const messageThreadsAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconList',
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -42,7 +42,6 @@ export const messagesAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconList',
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -41,7 +41,6 @@ export const notesAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconNotes',
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -39,7 +39,6 @@ export const opportunitiesAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconList',
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -29,6 +29,11 @@ export const opportunitiesByStageView = ({
const viewUniversalIdentifier =
STANDARD_OBJECTS.opportunity.views.byStage.universalIdentifier;
const stageFieldMetadataId =
opportunityObjectMetadata.fields.find(
(field) => field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.stage,
)?.id ?? '';
return {
id: v4(),
universalIdentifier: viewUniversalIdentifier,
@@ -39,16 +44,13 @@ export const opportunitiesByStageView = ({
key: null,
position: 2,
icon: 'IconLayoutKanban',
kanbanFieldMetadataId:
opportunityObjectMetadata.fields.find(
(field) => field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.stage,
)?.id ?? '',
kanbanAggregateOperation: AggregateOperations.MIN,
kanbanAggregateOperationFieldMetadataId:
opportunityObjectMetadata.fields.find(
(field) => field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.amount,
)?.id ?? '',
filters: [],
mainGroupByFieldMetadataId: stageFieldMetadataId,
fields: [
{
fieldMetadataId:
@@ -42,7 +42,6 @@ export const peopleAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconList',
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -41,7 +41,6 @@ export const tasksAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconList',
kanbanFieldMetadataId: '',
filters: [] /* [
{
fieldMetadataId:
@@ -42,7 +42,10 @@ export const tasksAssignedToMeView = ({
key: null,
position: 2,
icon: 'IconUserCircle',
kanbanFieldMetadataId: '',
mainGroupByFieldMetadataId:
taskObjectMetadata.fields.find(
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
)?.id ?? '',
filters: [
{
fieldMetadataId:
@@ -41,7 +41,7 @@ export const tasksByStatusView = ({
key: null,
position: 1,
icon: 'IconLayoutKanban',
kanbanFieldMetadataId:
mainGroupByFieldMetadataId:
taskObjectMetadata.fields.find(
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
)?.id ?? '',
@@ -44,7 +44,6 @@ export const timelineActivitiesAllView = ({
position: 0,
icon: 'IconList',
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -40,7 +40,6 @@ export const workflowRunsAllView = ({
position: 0,
icon: 'IconHistoryToggle',
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -46,7 +46,6 @@ export const workflowVersionsAllView = ({
position: 0,
icon: 'IconVersions',
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -43,7 +43,6 @@ export const workflowsAllView = ({
position: 0,
icon: 'IconSettingsAutomation',
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -45,7 +45,6 @@ export const workspaceMembersAllView = ({
key: 'INDEX',
position: 0,
icon: 'IconList',
kanbanFieldMetadataId: '',
filters: [],
fields: [
{
@@ -21,6 +21,7 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a crea
"isUnique": false,
"kanbanAggregateOperationViewIds": [],
"label": "flat field metadata label",
"mainGroupByFieldMetadataViewIds": [],
"morphId": null,
"name": "flatFieldMetadataName",
"objectMetadataId": "object-metadata-id-1",
@@ -85,6 +86,7 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect a dele
"isUnique": false,
"kanbanAggregateOperationViewIds": [],
"label": "flat field metadata label",
"mainGroupByFieldMetadataViewIds": [],
"morphId": null,
"name": "flatFieldMetadataName",
"objectMetadataId": "object-metadata-id-1",
@@ -167,6 +169,7 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create
"isUnique": false,
"kanbanAggregateOperationViewIds": [],
"label": "flat field metadata label",
"mainGroupByFieldMetadataViewIds": [],
"morphId": null,
"name": "flatFieldMetadataName",
"objectMetadataId": "object-metadata-id-1",
@@ -213,6 +216,7 @@ exports[`flatEntityDeletedCreatedUpdatedMatrixDispatcher It should detect create
"isUnique": false,
"kanbanAggregateOperationViewIds": [],
"label": "flat field metadata label",
"mainGroupByFieldMetadataViewIds": [],
"morphId": null,
"name": "flatFieldMetadataName",
"objectMetadataId": "object-metadata-id-1",
@@ -416,6 +416,7 @@ export const VIEW_STANDARD_FIELD_IDS = {
kanbanAggregateOperation: '20202020-8da2-45de-a731-61bed84b17a8',
kanbanAggregateOperationFieldMetadataId:
'20202020-b1b3-4bf3-85e4-dc7d58aa9b02',
mainGroupByFieldMetadataId: '20202020-f782-4f89-96eb-083a02cca887',
position: '20202020-e9db-4303-b271-e8250c450172',
isCompact: '20202020-674e-4314-994d-05754ea7b22b',
openRecordIn: '20202020-086d-4eef-9f03-56c6392eacb8',