diff --git a/server/migrations/1691004576333-CreatePageTable.ts b/server/migrations/1691004576333-CreatePageTable.ts new file mode 100644 index 0000000000..73a42c0c9e --- /dev/null +++ b/server/migrations/1691004576333-CreatePageTable.ts @@ -0,0 +1,54 @@ +import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm'; + +export class CreatePageTable1691004576333 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: 'pages', + columns: [ + { + name: 'id', + type: 'uuid', + isPrimary: true, + default: 'gen_random_uuid()', + }, + { + name: 'name', + type: 'varchar', + isNullable: false, + }, + { + name: 'app_version_id', + type: 'uuid', + isNullable: false, + }, + { + name: 'update_id', + type: 'varchar', + isNullable: false, + }, + { + name: 'last_hashed_diff', + type: 'varchar', + isNullable: false, + }, + ], + }) + ); + + // Add foreign key to relate Page with AppVersion + await queryRunner.createForeignKey( + 'pages', + new TableForeignKey({ + columnNames: ['app_version_id'], + referencedColumnNames: ['id'], + referencedTableName: 'app_versions', + onDelete: 'CASCADE', + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable('pages'); + } +} diff --git a/server/migrations/1691004706564-CreateEventHandlerTable.ts b/server/migrations/1691004706564-CreateEventHandlerTable.ts new file mode 100644 index 0000000000..78343cd7e2 --- /dev/null +++ b/server/migrations/1691004706564-CreateEventHandlerTable.ts @@ -0,0 +1,56 @@ +import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm'; + +export class CreateEventHandlerTable1691004706564 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: 'event_handlers', + columns: [ + { + name: 'id', + type: 'uuid', + isPrimary: true, + default: 'gen_random_uuid()', + }, + { + name: 'name', + type: 'varchar', + isNullable: false, + }, + { + name: 'app_version_id', + type: 'uuid', + isNullable: false, + }, + { + name: 'source_id', + type: 'varchar', + isNullable: false, + }, + { + name: 'target', + type: 'enum', + enum: ['page', 'component', 'data_query'], + default: "'page'", + isNullable: false, + }, + ], + }) + ); + + // Add foreign key to relate EventHandler with AppVersion + await queryRunner.createForeignKey( + 'event_handlers', + new TableForeignKey({ + columnNames: ['app_version_id'], + referencedColumnNames: ['id'], + referencedTableName: 'app_versions', + onDelete: 'CASCADE', + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable('event_handlers'); + } +} diff --git a/server/migrations/1691006886775-UpdateAppVersionEntity.ts b/server/migrations/1691006886775-UpdateAppVersionEntity.ts new file mode 100644 index 0000000000..91dc1162f0 --- /dev/null +++ b/server/migrations/1691006886775-UpdateAppVersionEntity.ts @@ -0,0 +1,41 @@ +import { MigrationInterface, QueryRunner, TableColumn } from 'typeorm'; + +export class UpdateAppVersionEntity1691006886775 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + // Add the new columns to the app_versions table + await queryRunner.addColumn( + 'app_versions', + new TableColumn({ + name: 'global_settings', + type: 'json', + isNullable: true, + }) + ); + + await queryRunner.addColumn( + 'app_versions', + new TableColumn({ + name: 'show_viewer_navigation', + type: 'boolean', + default: false, + isNullable: false, + }) + ); + + await queryRunner.addColumn( + 'app_versions', + new TableColumn({ + name: 'home_page_id', + type: 'uuid', + isNullable: true, + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + // Remove the new columns from the app_versions table (if necessary) + await queryRunner.dropColumn('app_versions', 'global_settings'); + await queryRunner.dropColumn('app_versions', 'show_viewer_navigation'); + await queryRunner.dropColumn('app_versions', 'home_page_id'); + } +} diff --git a/server/migrations/1691006952074-CreateComponentTable.ts b/server/migrations/1691006952074-CreateComponentTable.ts new file mode 100644 index 0000000000..3aab390d2a --- /dev/null +++ b/server/migrations/1691006952074-CreateComponentTable.ts @@ -0,0 +1,59 @@ +import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm'; + +export class CreateComponentTable1691006952074 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: 'components', + columns: [ + { + name: 'id', + type: 'uuid', + isPrimary: true, + default: 'gen_random_uuid()', + }, + { + name: 'name', + type: 'varchar', + isNullable: false, + }, + { + name: 'page_id', + type: 'uuid', + isNullable: false, + }, + { + name: 'properties', + type: 'json', + isNullable: true, + }, + { + name: 'styles', + type: 'json', + isNullable: true, + }, + { + name: 'validations', + type: 'json', + isNullable: true, + }, + ], + }) + ); + + // Add foreign key to relate Component with Page + await queryRunner.createForeignKey( + 'components', + new TableForeignKey({ + columnNames: ['page_id'], + referencedColumnNames: ['id'], + referencedTableName: 'pages', + onDelete: 'CASCADE', + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable('components'); + } +} diff --git a/server/migrations/1691007037021-CreateLayoutTable.ts b/server/migrations/1691007037021-CreateLayoutTable.ts new file mode 100644 index 0000000000..aedd4e84d6 --- /dev/null +++ b/server/migrations/1691007037021-CreateLayoutTable.ts @@ -0,0 +1,59 @@ +import { MigrationInterface, QueryRunner, Table, TableForeignKey } from 'typeorm'; + +export class CreateLayoutTable1691007037021 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: 'layouts', + columns: [ + { + name: 'id', + type: 'uuid', + isPrimary: true, + default: 'gen_random_uuid()', + }, + { + name: 'name', + type: 'varchar', + isNullable: false, + }, + { + name: 'type', + type: 'varchar', + isNullable: false, + }, + { + name: 'top', + type: 'integer', + isNullable: false, + }, + { + name: 'left', + type: 'integer', + isNullable: false, + }, + { + name: 'component_id', + type: 'uuid', + isNullable: false, + }, + ], + }) + ); + + // Add foreign key to relate Layout with Component + await queryRunner.createForeignKey( + 'layouts', + new TableForeignKey({ + columnNames: ['component_id'], + referencedColumnNames: ['id'], + referencedTableName: 'components', + onDelete: 'CASCADE', + }) + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable('layouts'); + } +} diff --git a/server/src/entities/app_version.entity.ts b/server/src/entities/app_version.entity.ts index 17027de2f5..683d7f7c5d 100644 --- a/server/src/entities/app_version.entity.ts +++ b/server/src/entities/app_version.entity.ts @@ -13,6 +13,8 @@ import { import { App } from './app.entity'; import { DataQuery } from './data_query.entity'; import { DataSource } from './data_source.entity'; +import { Page } from './page.entity'; +import { EventHandler } from './event_handler.entity'; @Entity({ name: 'app_versions' }) @Unique(['name', 'appId']) @@ -26,6 +28,15 @@ export class AppVersion extends BaseEntity { @Column('simple-json', { name: 'definition' }) definition; + @Column('simple-json', { name: 'global_settings' }) + globalSettings; + + @Column({ name: 'show_viewer_navigation' }) + showViewerNavigation: boolean; + + @Column({ name: 'home_page_id' }) + homePageId: string; + @Column({ name: 'app_id' }) appId: string; @@ -47,4 +58,12 @@ export class AppVersion extends BaseEntity { @OneToMany(() => DataQuery, (dataQuery) => dataQuery.appVersion) dataQueries: DataQuery[]; + + @OneToMany(() => Page, (page) => page.appVersion, { onDelete: 'CASCADE' }) + pages: Page[]; + + @OneToMany(() => EventHandler, (eventHandler) => eventHandler.appVersion, { + onDelete: 'CASCADE', + }) + eventHandlers: EventHandler[]; } diff --git a/server/src/entities/component.entity.ts b/server/src/entities/component.entity.ts new file mode 100644 index 0000000000..68649090f4 --- /dev/null +++ b/server/src/entities/component.entity.ts @@ -0,0 +1,30 @@ +import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany } from 'typeorm'; +import { Page } from './page.entity'; +import { Layout } from './layout.entity'; + +@Entity({ name: 'components' }) +export class Component { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ name: 'name' }) + name: string; + + @Column({ name: 'page_id' }) + PageId: string; + + @Column('simple-json') + properties: any; + + @Column('simple-json') + styles: any; + + @Column('simple-json') + validations: any; + + @ManyToOne(() => Page, (page) => page.components) + page: Page; + + @OneToMany(() => Layout, (layout) => layout.component) + layouts: Layout[]; +} diff --git a/server/src/entities/event_handler.entity.ts b/server/src/entities/event_handler.entity.ts new file mode 100644 index 0000000000..944ce9882e --- /dev/null +++ b/server/src/entities/event_handler.entity.ts @@ -0,0 +1,29 @@ +import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'; +import { AppVersion } from './app_version.entity'; + +enum Target { + page = 'page', + component = 'component', + dataQuery = 'data_query', +} + +@Entity({ name: 'event_handlers' }) +export class EventHandler { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ name: 'name' }) + name: string; + + @Column({ name: 'app_version_id' }) + AppVersionId: string; + + @Column({ name: 'source_id' }) + sourceId: string; + + @Column({ name: 'target' }) + target: Target; + + @ManyToOne(() => AppVersion, (appVersion) => appVersion.eventHandlers) + appVersion: AppVersion; +} diff --git a/server/src/entities/layout.entity.ts b/server/src/entities/layout.entity.ts new file mode 100644 index 0000000000..c0ee7ac8c6 --- /dev/null +++ b/server/src/entities/layout.entity.ts @@ -0,0 +1,26 @@ +import { Entity, PrimaryGeneratedColumn, Column, ManyToOne } from 'typeorm'; +import { Component } from './component.entity'; + +@Entity({ name: 'layouts' }) +export class Layout { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column({ name: 'name' }) + name: string; + + @Column({ name: 'type' }) + type: string; + + @Column({ name: 'top' }) + top: number; + + @Column({ name: 'left' }) + left: number; + + @Column({ name: 'component_id' }) + ComponentId: string; + + @ManyToOne(() => Component, (component) => component.layouts) + component: Component; +} diff --git a/server/src/entities/page.entity.ts b/server/src/entities/page.entity.ts new file mode 100644 index 0000000000..0260851136 --- /dev/null +++ b/server/src/entities/page.entity.ts @@ -0,0 +1,27 @@ +import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, OneToMany } from 'typeorm'; +import { AppVersion } from './app_version.entity'; +import { Component } from './component.entity'; + +@Entity({ name: 'pages' }) +export class Page { + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column() + name: string; + + @Column() + AppVersionId: string; + + @Column() + updateId: string; + + @Column() + lastHashedDiff: string; + + @ManyToOne(() => AppVersion, (appVersion) => appVersion.pages) + appVersion: AppVersion; + + @OneToMany(() => Component, (component) => component.page) + components: Component[]; +} diff --git a/server/src/modules/apps/apps.module.ts b/server/src/modules/apps/apps.module.ts index 400ad7d44b..a197ec5088 100644 --- a/server/src/modules/apps/apps.module.ts +++ b/server/src/modules/apps/apps.module.ts @@ -33,6 +33,11 @@ import { Plugin } from 'src/entities/plugin.entity'; import { PluginsHelper } from 'src/helpers/plugins.helper'; import { AppEnvironmentService } from '@services/app_environments.service'; +import { Component } from 'src/entities/component.entity'; +import { Page } from 'src/entities/page.entity'; +import { EventHandler } from 'src/entities/event_handler.entity'; +import { Layout } from 'src/entities/layout.entity'; + @Module({ imports: [ TypeOrmModule.forFeature([ @@ -52,6 +57,10 @@ import { AppEnvironmentService } from '@services/app_environments.service'; Credential, File, Plugin, + Component, + Page, + EventHandler, + Layout, ]), CaslModule, ],