Page layout tab v2 (#16319)
# Introduction Migrating `pageLayoutTab` to the v2 engine - Types and constants - Builder and validate - Runner Introduced a new `StrictSyncableEntity` that enforces that `universalIdentifier` and `applicationId` are defined As these entities are brand new we could enforce this rule already This still requires a migration command to associate the existing entities to custom workspace application instance and define universalIdentifier Handled retro-comp of the migration through a migration as upgrade command fallback --------- Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
This commit is contained in:
+6
-1
@@ -14,6 +14,8 @@ import {
|
||||
UpdateDateColumn,
|
||||
} from 'typeorm';
|
||||
|
||||
import { StrictSyncableEntity } from 'src/engine/workspace-manager/workspace-sync/interfaces/strict-syncable-entity.interface';
|
||||
|
||||
import { PageLayoutWidgetEntity } from 'src/engine/core-modules/page-layout/entities/page-layout-widget.entity';
|
||||
import { PageLayoutEntity } from 'src/engine/core-modules/page-layout/entities/page-layout.entity';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
@@ -25,7 +27,10 @@ import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.ent
|
||||
['workspaceId', 'pageLayoutId'],
|
||||
{ where: '"deletedAt" IS NULL' },
|
||||
)
|
||||
export class PageLayoutTabEntity implements Required<PageLayoutTabEntity> {
|
||||
export class PageLayoutTabEntity
|
||||
extends StrictSyncableEntity
|
||||
implements Required<PageLayoutTabEntity>
|
||||
{
|
||||
@PrimaryGeneratedColumn('uuid')
|
||||
id: string;
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import { PageLayoutTabService } from 'src/engine/core-modules/page-layout/servic
|
||||
import { PageLayoutUpdateService } from 'src/engine/core-modules/page-layout/services/page-layout-update.service';
|
||||
import { PageLayoutWidgetService } from 'src/engine/core-modules/page-layout/services/page-layout-widget.service';
|
||||
import { PageLayoutService } from 'src/engine/core-modules/page-layout/services/page-layout.service';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
|
||||
|
||||
@@ -24,6 +25,7 @@ import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
|
||||
PageLayoutEntity,
|
||||
PageLayoutTabEntity,
|
||||
PageLayoutWidgetEntity,
|
||||
WorkspaceEntity,
|
||||
]),
|
||||
TwentyORMModule,
|
||||
PermissionsModule,
|
||||
|
||||
+15
@@ -3,6 +3,7 @@ import { getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { type Repository } from 'typeorm';
|
||||
|
||||
import { type ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { PageLayoutTabEntity } from 'src/engine/core-modules/page-layout/entities/page-layout-tab.entity';
|
||||
import { type PageLayoutWidgetEntity } from 'src/engine/core-modules/page-layout/entities/page-layout-widget.entity';
|
||||
import { WidgetType } from 'src/engine/core-modules/page-layout/enums/widget-type.enum';
|
||||
@@ -18,6 +19,7 @@ import {
|
||||
} from 'src/engine/core-modules/page-layout/exceptions/page-layout.exception';
|
||||
import { PageLayoutTabService } from 'src/engine/core-modules/page-layout/services/page-layout-tab.service';
|
||||
import { PageLayoutService } from 'src/engine/core-modules/page-layout/services/page-layout.service';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
describe('PageLayoutTabService', () => {
|
||||
let pageLayoutTabService: PageLayoutTabService;
|
||||
@@ -36,6 +38,9 @@ describe('PageLayoutTabService', () => {
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
deletedAt: null,
|
||||
application: {} as ApplicationEntity,
|
||||
applicationId: 'application-id',
|
||||
universalIdentifier: 'universal-identifier',
|
||||
} as PageLayoutTabEntity;
|
||||
|
||||
const mockWidget = {
|
||||
@@ -71,6 +76,14 @@ describe('PageLayoutTabService', () => {
|
||||
insert: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(WorkspaceEntity),
|
||||
useValue: {
|
||||
findOneOrFail: jest.fn().mockResolvedValue({
|
||||
workspaceCustomApplicationId: 'application-id',
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: PageLayoutService,
|
||||
useValue: {
|
||||
@@ -261,6 +274,8 @@ describe('PageLayoutTabService', () => {
|
||||
expect(pageLayoutTabRepository.insert).toHaveBeenCalledWith({
|
||||
...pageLayoutTabData,
|
||||
workspaceId,
|
||||
applicationId: 'application-id',
|
||||
universalIdentifier: expect.any(String),
|
||||
});
|
||||
expect(result).toEqual(mockPageLayoutTab);
|
||||
});
|
||||
|
||||
+4
@@ -2,6 +2,7 @@ import { Test, type TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { DataSource, type EntityManager } from 'typeorm';
|
||||
|
||||
import { type ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { type UpdatePageLayoutTabWithWidgetsInput } from 'src/engine/core-modules/page-layout/dtos/inputs/update-page-layout-tab-with-widgets.input';
|
||||
import { type UpdatePageLayoutWidgetWithIdInput } from 'src/engine/core-modules/page-layout/dtos/inputs/update-page-layout-widget-with-id.input';
|
||||
import { type PageLayoutTabEntity } from 'src/engine/core-modules/page-layout/entities/page-layout-tab.entity';
|
||||
@@ -49,6 +50,9 @@ describe('PageLayoutUpdateService', () => {
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
deletedAt: null,
|
||||
application: {} as ApplicationEntity,
|
||||
applicationId: 'application-id',
|
||||
universalIdentifier: 'universal-identifier',
|
||||
} as PageLayoutTabEntity;
|
||||
|
||||
const mockWidget = {
|
||||
|
||||
+11
@@ -4,6 +4,7 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { EntityManager, IsNull, Repository } from 'typeorm';
|
||||
import { QueryDeepPartialEntity } from 'typeorm/query-builder/QueryPartialEntity';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { CreatePageLayoutTabInput } from 'src/engine/core-modules/page-layout/dtos/inputs/create-page-layout-tab.input';
|
||||
import { PageLayoutTabEntity } from 'src/engine/core-modules/page-layout/entities/page-layout-tab.entity';
|
||||
@@ -18,12 +19,15 @@ import {
|
||||
PageLayoutExceptionCode,
|
||||
} from 'src/engine/core-modules/page-layout/exceptions/page-layout.exception';
|
||||
import { PageLayoutService } from 'src/engine/core-modules/page-layout/services/page-layout.service';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
|
||||
@Injectable()
|
||||
export class PageLayoutTabService {
|
||||
constructor(
|
||||
@InjectRepository(PageLayoutTabEntity)
|
||||
private readonly pageLayoutTabRepository: Repository<PageLayoutTabEntity>,
|
||||
@InjectRepository(WorkspaceEntity)
|
||||
private readonly workspaceRepository: Repository<WorkspaceEntity>,
|
||||
private readonly pageLayoutService: PageLayoutService,
|
||||
) {}
|
||||
|
||||
@@ -113,11 +117,18 @@ export class PageLayoutTabService {
|
||||
transactionManager,
|
||||
);
|
||||
|
||||
const workspace = await this.workspaceRepository.findOneOrFail({
|
||||
where: { id: workspaceId },
|
||||
select: ['workspaceCustomApplicationId'],
|
||||
});
|
||||
|
||||
const repository = this.getPageLayoutTabRepository(transactionManager);
|
||||
|
||||
const insertResult = await repository.insert({
|
||||
...pageLayoutTabData,
|
||||
workspaceId,
|
||||
universalIdentifier: v4(),
|
||||
applicationId: workspace.workspaceCustomApplicationId,
|
||||
});
|
||||
|
||||
return this.findByIdOrThrow(
|
||||
|
||||
Reference in New Issue
Block a user