Fix page layout seeding for record page layouts (#17871)
## Context Fix broken record page layout seeding. This was not detected by the CI because it doesn't have the env variable yet. Following the same mechanism as labelIdentifier in object for circular dependency resolution
This commit is contained in:
+43
-2
@@ -3,6 +3,7 @@ import { assertUnreachable, isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type UniversalCreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
|
||||
import { type UniversalCreateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
|
||||
import { type UniversalCreatePageLayoutAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/types/workspace-migration-page-layout-action.type';
|
||||
import { type WorkspaceMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration';
|
||||
|
||||
export type IdByUniversalIdentifierByMetadataName = {
|
||||
@@ -40,6 +41,25 @@ const buildFieldIdByUniversalIdentifier = ({
|
||||
return fieldIdByUniversalIdentifier;
|
||||
};
|
||||
|
||||
const buildTabIdByUniversalIdentifier = ({
|
||||
action,
|
||||
pageLayoutTabIdByUniversalIdentifier,
|
||||
}: {
|
||||
action: UniversalCreatePageLayoutAction;
|
||||
pageLayoutTabIdByUniversalIdentifier: Record<string, string>;
|
||||
}): Record<string, string> | undefined => {
|
||||
const tabIdByUniversalIdentifier = {
|
||||
...action.tabIdByUniversalIdentifier,
|
||||
...pageLayoutTabIdByUniversalIdentifier,
|
||||
};
|
||||
|
||||
if (Object.keys(tabIdByUniversalIdentifier).length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return tabIdByUniversalIdentifier;
|
||||
};
|
||||
|
||||
export const enrichCreateWorkspaceMigrationActionsWithIds = ({
|
||||
workspaceMigration,
|
||||
idByUniversalIdentifierByMetadataName,
|
||||
@@ -49,6 +69,8 @@ export const enrichCreateWorkspaceMigrationActionsWithIds = ({
|
||||
}): WorkspaceMigration => {
|
||||
const fieldMetadataIdByUniversalIdentifier =
|
||||
idByUniversalIdentifierByMetadataName.fieldMetadata;
|
||||
const pageLayoutTabIdByUniversalIdentifier =
|
||||
idByUniversalIdentifierByMetadataName.pageLayoutTab;
|
||||
|
||||
const enrichedActions = workspaceMigration.actions.map((action) => {
|
||||
if (action.type !== 'create') {
|
||||
@@ -60,7 +82,8 @@ export const enrichCreateWorkspaceMigrationActionsWithIds = ({
|
||||
|
||||
if (
|
||||
!isDefined(idByUniversalIdentifier) &&
|
||||
!isDefined(fieldMetadataIdByUniversalIdentifier)
|
||||
!isDefined(fieldMetadataIdByUniversalIdentifier) &&
|
||||
!isDefined(pageLayoutTabIdByUniversalIdentifier)
|
||||
) {
|
||||
return action;
|
||||
}
|
||||
@@ -98,6 +121,25 @@ export const enrichCreateWorkspaceMigrationActionsWithIds = ({
|
||||
}),
|
||||
};
|
||||
}
|
||||
case 'pageLayout': {
|
||||
const id = isDefined(idByUniversalIdentifier)
|
||||
? idByUniversalIdentifier[action.flatEntity.universalIdentifier]
|
||||
: undefined;
|
||||
const tabIdByUniversalIdentifier = isDefined(
|
||||
pageLayoutTabIdByUniversalIdentifier,
|
||||
)
|
||||
? buildTabIdByUniversalIdentifier({
|
||||
action,
|
||||
pageLayoutTabIdByUniversalIdentifier,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
...action,
|
||||
id,
|
||||
tabIdByUniversalIdentifier,
|
||||
};
|
||||
}
|
||||
case 'view':
|
||||
case 'viewField':
|
||||
case 'viewGroup':
|
||||
@@ -111,7 +153,6 @@ export const enrichCreateWorkspaceMigrationActionsWithIds = ({
|
||||
case 'roleTarget':
|
||||
case 'agent':
|
||||
case 'skill':
|
||||
case 'pageLayout':
|
||||
case 'pageLayoutWidget':
|
||||
case 'pageLayoutTab':
|
||||
case 'commandMenuItem':
|
||||
|
||||
+3
-1
@@ -9,7 +9,9 @@ export type FlatCreatePageLayoutAction =
|
||||
BaseFlatCreateWorkspaceMigrationAction<'pageLayout'>;
|
||||
|
||||
export type UniversalCreatePageLayoutAction =
|
||||
BaseUniversalCreateWorkspaceMigrationAction<'pageLayout'>;
|
||||
BaseUniversalCreateWorkspaceMigrationAction<'pageLayout'> & {
|
||||
tabIdByUniversalIdentifier?: Record<string, string>;
|
||||
};
|
||||
|
||||
export type FlatUpdatePageLayoutAction =
|
||||
BaseFlatUpdateWorkspaceMigrationAction<'pageLayout'>;
|
||||
|
||||
+40
-6
@@ -1,15 +1,21 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { resolveUniversalRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-relation-identifiers-to-ids.util';
|
||||
import {
|
||||
FlatCreatePageLayoutAction,
|
||||
UniversalCreatePageLayoutAction,
|
||||
} from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/types/workspace-migration-page-layout-action.type';
|
||||
import { findPageLayoutTabIdInCreatePageLayoutContext } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/action-handlers/page-layout/services/utils/find-page-layout-tab-id-in-create-page-layout-context.util';
|
||||
import {
|
||||
WorkspaceMigrationActionRunnerArgs,
|
||||
WorkspaceMigrationActionRunnerContext,
|
||||
@@ -30,12 +36,40 @@ export class CreatePageLayoutActionHandlerService extends WorkspaceMigrationRunn
|
||||
flatApplication,
|
||||
workspaceId,
|
||||
}: WorkspaceMigrationActionRunnerArgs<UniversalCreatePageLayoutAction>): Promise<FlatCreatePageLayoutAction> {
|
||||
const { objectMetadataId, defaultTabToFocusOnMobileAndSidePanelId } =
|
||||
resolveUniversalRelationIdentifiersToIds({
|
||||
flatEntityMaps: allFlatEntityMaps,
|
||||
metadataName: action.metadataName,
|
||||
universalForeignKeyValues: action.flatEntity,
|
||||
});
|
||||
const { objectMetadataId } = resolveUniversalRelationIdentifiersToIds<
|
||||
'pageLayout',
|
||||
'objectMetadataUniversalIdentifier'
|
||||
>({
|
||||
flatEntityMaps: allFlatEntityMaps,
|
||||
metadataName: 'pageLayout',
|
||||
universalForeignKeyValues: {
|
||||
objectMetadataUniversalIdentifier:
|
||||
action.flatEntity.objectMetadataUniversalIdentifier,
|
||||
},
|
||||
});
|
||||
|
||||
let defaultTabToFocusOnMobileAndSidePanelId: string | null = null;
|
||||
|
||||
const defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier =
|
||||
action.flatEntity
|
||||
.defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier;
|
||||
|
||||
if (isDefined(defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier)) {
|
||||
defaultTabToFocusOnMobileAndSidePanelId =
|
||||
findPageLayoutTabIdInCreatePageLayoutContext({
|
||||
universalIdentifier:
|
||||
defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier,
|
||||
tabIdByUniversalIdentifier: action.tabIdByUniversalIdentifier,
|
||||
flatPageLayoutTabMaps: allFlatEntityMaps.flatPageLayoutTabMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(defaultTabToFocusOnMobileAndSidePanelId)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`Could not resolve defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier to defaultTabToFocusOnMobileAndSidePanelId: no pageLayoutTab found for universal identifier ${defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...action,
|
||||
|
||||
+38
-6
@@ -1,8 +1,16 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { WorkspaceMigrationRunnerActionHandler } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/interfaces/workspace-migration-runner-action-handler-service.interface';
|
||||
|
||||
import {
|
||||
FlatEntityMapsException,
|
||||
FlatEntityMapsExceptionCode,
|
||||
} from 'src/engine/metadata-modules/flat-entity/exceptions/flat-entity-maps.exception';
|
||||
import { type FlatEntityUpdate } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-update.type';
|
||||
import { findFlatEntityByUniversalIdentifierOrThrow } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier-or-throw.util';
|
||||
import { findFlatEntityByUniversalIdentifier } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-universal-identifier.util';
|
||||
import { PageLayoutEntity } from 'src/engine/metadata-modules/page-layout/entities/page-layout.entity';
|
||||
import { resolveUniversalUpdateRelationIdentifiersToIds } from 'src/engine/workspace-manager/workspace-migration/universal-flat-entity/utils/resolve-universal-update-relation-identifiers-to-ids.util';
|
||||
import {
|
||||
@@ -29,17 +37,41 @@ export class UpdatePageLayoutActionHandlerService extends WorkspaceMigrationRunn
|
||||
universalIdentifier: action.universalIdentifier,
|
||||
});
|
||||
|
||||
const update = resolveUniversalUpdateRelationIdentifiersToIds({
|
||||
metadataName: 'pageLayout',
|
||||
universalUpdate: action.update,
|
||||
allFlatEntityMaps,
|
||||
});
|
||||
const {
|
||||
defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier,
|
||||
...restUpdate
|
||||
} = action.update;
|
||||
|
||||
const transpiledUpdate: FlatEntityUpdate<'pageLayout'> =
|
||||
resolveUniversalUpdateRelationIdentifiersToIds({
|
||||
metadataName: 'pageLayout',
|
||||
universalUpdate: restUpdate,
|
||||
allFlatEntityMaps,
|
||||
});
|
||||
|
||||
if (isDefined(defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier)) {
|
||||
const flatPageLayoutTab = findFlatEntityByUniversalIdentifier({
|
||||
flatEntityMaps: allFlatEntityMaps.flatPageLayoutTabMaps,
|
||||
universalIdentifier:
|
||||
defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier,
|
||||
});
|
||||
|
||||
if (!isDefined(flatPageLayoutTab)) {
|
||||
throw new FlatEntityMapsException(
|
||||
`Could not resolve defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier to defaultTabToFocusOnMobileAndSidePanelId: no pageLayoutTab found for universal identifier ${defaultTabToFocusOnMobileAndSidePanelUniversalIdentifier}`,
|
||||
FlatEntityMapsExceptionCode.ENTITY_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
transpiledUpdate.defaultTabToFocusOnMobileAndSidePanelId =
|
||||
flatPageLayoutTab.id;
|
||||
}
|
||||
|
||||
return {
|
||||
type: 'update',
|
||||
metadataName: 'pageLayout',
|
||||
entityId: flatPageLayout.id,
|
||||
update,
|
||||
update: transpiledUpdate,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
|
||||
|
||||
export const findPageLayoutTabIdInCreatePageLayoutContext = ({
|
||||
universalIdentifier,
|
||||
tabIdByUniversalIdentifier,
|
||||
flatPageLayoutTabMaps,
|
||||
}: {
|
||||
universalIdentifier: string;
|
||||
tabIdByUniversalIdentifier: Record<string, string> | undefined;
|
||||
flatPageLayoutTabMaps: AllFlatEntityMaps['flatPageLayoutTabMaps'];
|
||||
}): string | null => {
|
||||
const providedId = tabIdByUniversalIdentifier?.[universalIdentifier];
|
||||
|
||||
if (isDefined(providedId)) {
|
||||
return providedId;
|
||||
}
|
||||
|
||||
const existingTab =
|
||||
flatPageLayoutTabMaps.byUniversalIdentifier[universalIdentifier];
|
||||
|
||||
return existingTab?.id ?? null;
|
||||
};
|
||||
Reference in New Issue
Block a user