Create PageLayoutEntity (#14099)

Closes https://github.com/twentyhq/core-team-issues/issues/1389
This commit is contained in:
Raphaël Bosi
2025-08-27 12:34:02 +02:00
committed by GitHub
parent 850a0fdea2
commit 28de78bfc0
5 changed files with 120 additions and 1 deletions
@@ -0,0 +1,37 @@
import { type MigrationInterface, type QueryRunner } from 'typeorm';
export class CreatePageLayoutEntity1756289507594 implements MigrationInterface {
name = 'CreatePageLayoutEntity1756289507594';
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`CREATE TYPE "core"."pageLayout_type_enum" AS ENUM('RECORD_INDEX', 'RECORD_PAGE', 'DASHBOARD')`,
);
await queryRunner.query(
`CREATE TABLE "core"."pageLayout" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "name" character varying NOT NULL, "workspaceId" uuid NOT NULL, "type" "core"."pageLayout_type_enum" NOT NULL DEFAULT 'RECORD_PAGE', "objectMetadataId" uuid, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, CONSTRAINT "PK_5028ccb46ffa0c945d2f9246dfa" PRIMARY KEY ("id"))`,
);
await queryRunner.query(
`CREATE INDEX "IDX_PAGE_LAYOUT_WORKSPACE_ID_OBJECT_METADATA_ID" ON "core"."pageLayout" ("workspaceId", "objectMetadataId") `,
);
await queryRunner.query(
`ALTER TABLE "core"."pageLayout" ADD CONSTRAINT "FK_760ec8b78721991220b76accd55" FOREIGN KEY ("workspaceId") REFERENCES "core"."workspace"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
await queryRunner.query(
`ALTER TABLE "core"."pageLayout" ADD CONSTRAINT "FK_dd63ca42614bacf58971aabdcbb" FOREIGN KEY ("objectMetadataId") REFERENCES "core"."objectMetadata"("id") ON DELETE CASCADE ON UPDATE NO ACTION`,
);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
`ALTER TABLE "core"."pageLayout" DROP CONSTRAINT "FK_dd63ca42614bacf58971aabdcbb"`,
);
await queryRunner.query(
`ALTER TABLE "core"."pageLayout" DROP CONSTRAINT "FK_760ec8b78721991220b76accd55"`,
);
await queryRunner.query(
`DROP INDEX "core"."IDX_PAGE_LAYOUT_WORKSPACE_ID_OBJECT_METADATA_ID"`,
);
await queryRunner.query(`DROP TABLE "core"."pageLayout"`);
await queryRunner.query(`DROP TYPE "core"."pageLayout_type_enum"`);
}
}
@@ -22,6 +22,7 @@ import { exceptionHandlerModuleFactory } from 'src/engine/core-modules/exception
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
import { FileStorageModule } from 'src/engine/core-modules/file-storage/file-storage.module';
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
import { GeoMapModule } from 'src/engine/core-modules/geo-map/geo-map-module';
import { HealthModule } from 'src/engine/core-modules/health/health.module';
import { ImapSmtpCaldavModule } from 'src/engine/core-modules/imap-smtp-caldav-connection/imap-smtp-caldav-connection.module';
import { LabModule } from 'src/engine/core-modules/lab/lab.module';
@@ -31,6 +32,7 @@ import { MessageQueueModule } from 'src/engine/core-modules/message-queue/messag
import { messageQueueModuleFactory } from 'src/engine/core-modules/message-queue/message-queue.module-factory';
import { TimelineMessagingModule } from 'src/engine/core-modules/messaging/timeline-messaging.module';
import { OpenApiModule } from 'src/engine/core-modules/open-api/open-api.module';
import { PageLayoutModule } from 'src/engine/core-modules/page-layout/page-layout.module';
import { PostgresCredentialsModule } from 'src/engine/core-modules/postgres-credentials/postgres-credentials.module';
import { RedisClientModule } from 'src/engine/core-modules/redis-client/redis-client.module';
import { RedisClientService } from 'src/engine/core-modules/redis-client/redis-client.service';
@@ -50,7 +52,6 @@ import { WorkspaceModule } from 'src/engine/core-modules/workspace/workspace.mod
import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
import { SubscriptionsModule } from 'src/engine/subscriptions/subscriptions.module';
import { WorkspaceEventEmitterModule } from 'src/engine/workspace-event-emitter/workspace-event-emitter.module';
import { GeoMapModule } from 'src/engine/core-modules/geo-map/geo-map-module';
import { AuditModule } from './audit/audit.module';
import { ClientConfigModule } from './client-config/client-config.module';
@@ -120,6 +121,7 @@ import { FileModule } from './file/file.module';
ApiKeyModule,
WebhookModule,
CoreViewModule,
PageLayoutModule,
],
exports: [
AuditModule,
@@ -0,0 +1,65 @@
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
Relation,
UpdateDateColumn,
} from 'typeorm';
import { PageLayoutType } from 'src/engine/core-modules/page-layout/enums/page-layout-type.enum';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
@Entity({ name: 'pageLayout', schema: 'core' })
@Index('IDX_PAGE_LAYOUT_WORKSPACE_ID_OBJECT_METADATA_ID', [
'workspaceId',
'objectMetadataId',
])
export class PageLayoutEntity implements Required<PageLayoutEntity> {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false })
name: string;
@Column({ nullable: false, type: 'uuid' })
workspaceId: string;
@ManyToOne(() => Workspace, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'workspaceId' })
workspace: Relation<Workspace>;
@Column({
type: 'enum',
enum: Object.values(PageLayoutType),
nullable: false,
default: PageLayoutType.RECORD_PAGE,
})
type: PageLayoutType;
@Column({ nullable: true, type: 'uuid' })
objectMetadataId: string | null;
@ManyToOne(() => ObjectMetadataEntity, {
onDelete: 'CASCADE',
nullable: true,
})
@JoinColumn({ name: 'objectMetadataId' })
objectMetadata: Relation<ObjectMetadataEntity> | null;
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@DeleteDateColumn({ type: 'timestamptz' })
deletedAt: Date | null;
}
@@ -0,0 +1,5 @@
export enum PageLayoutType {
RECORD_INDEX = 'RECORD_INDEX',
RECORD_PAGE = 'RECORD_PAGE',
DASHBOARD = 'DASHBOARD',
}
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { PageLayoutEntity } from 'src/engine/core-modules/page-layout/entities/page-layout.entity';
@Module({
imports: [TypeOrmModule.forFeature([PageLayoutEntity], 'core')],
exports: [],
})
export class PageLayoutModule {}