Create view tables inside the core schema (#13309)

Closes https://github.com/twentyhq/core-team-issues/issues/1246

Created, in core schema:
- View
- ViewField
- ViewFilter
- ViewSort
- ViewGroup
- ViewFilterGroup

Generated migration file.
This commit is contained in:
Raphaël Bosi
2025-07-21 16:26:18 +02:00
committed by GitHub
parent 1dee9bc800
commit f6aa556a16
14 changed files with 658 additions and 0 deletions

View File

@ -0,0 +1,5 @@
export enum ViewFilterGroupLogicalOperator {
AND = 'AND',
OR = 'OR',
NOT = 'NOT',
}

View File

@ -0,0 +1,4 @@
export enum ViewOpenRecordIn {
SIDE_PANEL = 'SIDE_PANEL',
RECORD_PAGE = 'RECORD_PAGE',
}

View File

@ -0,0 +1,4 @@
export enum ViewSortDirection {
ASC = 'ASC',
DESC = 'DESC',
}

View File

@ -0,0 +1,77 @@
import { IDField } from '@ptc-org/nestjs-query-graphql';
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
Relation,
Unique,
UpdateDateColumn,
} from 'typeorm';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { View } from 'src/engine/metadata-modules/view/view.entity';
@Entity({ name: 'viewField', schema: 'core' })
@Index('IDX_VIEW_FIELD_WORKSPACE_ID_VIEW_ID', ['workspaceId', 'viewId'])
@Unique('IDX_VIEW_FIELD_FIELD_METADATA_ID_VIEW_ID_UNIQUE', [
'fieldMetadataId',
'viewId',
])
export class ViewField {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false, type: 'uuid' })
fieldMetadataId: string;
@Column({ nullable: false, default: true })
isVisible: boolean;
@Column({ nullable: false, type: 'int', default: 0 })
size: number;
@Column({ nullable: false, type: 'int', default: 0 })
position: number;
@Column({
type: 'enum',
enum: AggregateOperations,
nullable: true,
})
aggregateOperation?: AggregateOperations | null;
@Column({ nullable: false, type: 'uuid' })
viewId: string;
@Column({ nullable: false, type: 'uuid' })
workspaceId: string;
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@DeleteDateColumn({ type: 'timestamptz' })
deletedAt?: Date | null;
@ManyToOne(() => Workspace, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'workspaceId' })
workspace: Relation<Workspace>;
@ManyToOne(() => View, (view) => view.viewFields, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'viewId' })
view: Relation<View>;
}

View File

@ -0,0 +1,73 @@
import { registerEnumType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
Relation,
UpdateDateColumn,
} from 'typeorm';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { ViewFilterGroupLogicalOperator } from 'src/engine/metadata-modules/view/enums/view-filter-group-logical-operator';
import { View } from 'src/engine/metadata-modules/view/view.entity';
registerEnumType(ViewFilterGroupLogicalOperator, {
name: 'ViewFilterGroupLogicalOperator',
});
@Entity({ name: 'viewFilterGroup', schema: 'core' })
@Index('IDX_VIEW_FILTER_GROUP_WORKSPACE_ID_VIEW_ID', ['workspaceId', 'viewId'])
export class ViewFilterGroup {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: true, type: 'uuid' })
parentViewFilterGroupId?: string | null;
@Column({
type: 'enum',
enum: ViewFilterGroupLogicalOperator,
nullable: false,
default: ViewFilterGroupLogicalOperator.NOT,
})
logicalOperator: ViewFilterGroupLogicalOperator;
@Column({ nullable: true, type: 'int' })
positionInViewFilterGroup?: number | null;
@Column({ nullable: false, type: 'uuid' })
viewId: string;
@Column({ nullable: false, type: 'uuid' })
workspaceId: string;
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@DeleteDateColumn({ type: 'timestamptz' })
deletedAt?: Date | null;
@ManyToOne(() => Workspace, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'workspaceId' })
workspace: Relation<Workspace>;
@ManyToOne(() => View, (view) => view.viewFilterGroups, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'viewId' })
view: Relation<View>;
}

View File

@ -0,0 +1,71 @@
import { IDField } from '@ptc-org/nestjs-query-graphql';
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
Relation,
UpdateDateColumn,
} from 'typeorm';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { View } from 'src/engine/metadata-modules/view/view.entity';
@Entity({ name: 'viewFilter', schema: 'core' })
@Index('IDX_VIEW_FILTER_WORKSPACE_ID_VIEW_ID', ['workspaceId', 'viewId'])
@Index('IDX_VIEW_FILTER_FIELD_METADATA_ID', ['fieldMetadataId'])
export class ViewFilter {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false, type: 'uuid' })
fieldMetadataId: string;
@Column({ nullable: false, default: 'Contains' })
operand: string;
@Column({ nullable: false, type: 'jsonb' })
value: JSON;
@Column({ nullable: true, type: 'uuid' })
viewFilterGroupId?: string | null;
@Column({ nullable: true, type: 'int' })
positionInViewFilterGroup?: number | null;
@Column({ nullable: true, type: 'text', default: null })
subFieldName?: string | null;
@Column({ nullable: false, type: 'uuid' })
viewId: string;
@Column({ nullable: false, type: 'uuid' })
workspaceId: string;
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@DeleteDateColumn({ type: 'timestamptz' })
deletedAt?: Date | null;
@ManyToOne(() => Workspace, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'workspaceId' })
workspace: Relation<Workspace>;
@ManyToOne(() => View, (view) => view.viewFilters, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'viewId' })
view: Relation<View>;
}

View File

@ -0,0 +1,64 @@
import { IDField } from '@ptc-org/nestjs-query-graphql';
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
Relation,
UpdateDateColumn,
} from 'typeorm';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { View } from 'src/engine/metadata-modules/view/view.entity';
@Entity({ name: 'viewGroup', schema: 'core' })
@Index('IDX_VIEW_GROUP_WORKSPACE_ID_VIEW_ID', ['workspaceId', 'viewId'])
export class ViewGroup {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false, type: 'uuid' })
fieldMetadataId: string;
@Column({ nullable: false, default: true })
isVisible: boolean;
@Column({ nullable: false, type: 'text' })
fieldValue: string;
@Column({ nullable: false, type: 'int', default: 0 })
position: number;
@Column({ nullable: false, type: 'uuid' })
viewId: string;
@Column({ nullable: false, type: 'uuid' })
workspaceId: string;
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@DeleteDateColumn({ type: 'timestamptz' })
deletedAt?: Date | null;
@ManyToOne(() => Workspace, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'workspaceId' })
workspace: Relation<Workspace>;
@ManyToOne(() => View, (view) => view.viewGroups, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'viewId' })
view: Relation<View>;
}

View File

@ -0,0 +1,73 @@
import { registerEnumType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
PrimaryGeneratedColumn,
Relation,
Unique,
UpdateDateColumn,
} from 'typeorm';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { ViewSortDirection } from 'src/engine/metadata-modules/view/enums/view-sort-direction';
import { View } from 'src/engine/metadata-modules/view/view.entity';
registerEnumType(ViewSortDirection, { name: 'ViewSortDirection' });
@Entity({ name: 'viewSort', schema: 'core' })
@Index('IDX_VIEW_SORT_WORKSPACE_ID_VIEW_ID', ['workspaceId', 'viewId'])
@Unique('IDX_VIEW_SORT_FIELD_METADATA_ID_VIEW_ID_UNIQUE', [
'fieldMetadataId',
'viewId',
])
export class ViewSort {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false, type: 'uuid' })
fieldMetadataId: string;
@Column({
nullable: false,
type: 'enum',
enum: ViewSortDirection,
default: ViewSortDirection.ASC,
})
direction: ViewSortDirection;
@Column({ nullable: false, type: 'uuid' })
viewId: string;
@Column({ nullable: false, type: 'uuid' })
workspaceId: string;
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@DeleteDateColumn({ type: 'timestamptz' })
deletedAt?: Date | null;
@ManyToOne(() => Workspace, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'workspaceId' })
workspace: Relation<Workspace>;
@ManyToOne(() => View, (view) => view.viewSorts, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'viewId' })
view: Relation<View>;
}

View File

@ -0,0 +1,111 @@
import { registerEnumType } from '@nestjs/graphql';
import { IDField } from '@ptc-org/nestjs-query-graphql';
import {
Column,
CreateDateColumn,
DeleteDateColumn,
Entity,
Index,
JoinColumn,
ManyToOne,
OneToMany,
PrimaryGeneratedColumn,
Relation,
UpdateDateColumn,
} from 'typeorm';
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/graphql-types/scalars';
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
import { ViewField } from 'src/engine/metadata-modules/view/view-field.entity';
import { ViewFilterGroup } from 'src/engine/metadata-modules/view/view-filter-group.entity';
import { ViewFilter } from 'src/engine/metadata-modules/view/view-filter.entity';
import { ViewGroup } from 'src/engine/metadata-modules/view/view-group.entity';
import { ViewSort } from 'src/engine/metadata-modules/view/view-sort.entity';
registerEnumType(ViewOpenRecordIn, { name: 'ViewOpenRecordIn' });
@Entity({ name: 'view', schema: 'core' })
@Index('IDX_VIEW_WORKSPACE_ID_OBJECT_METADATA_ID', [
'workspaceId',
'objectMetadataId',
])
export class View {
@IDField(() => UUIDScalarType)
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ nullable: false, type: 'text', default: '' })
name: string;
@Column({ nullable: false, type: 'uuid' })
objectMetadataId: string;
@Column({ nullable: false, default: 'table' })
type: string;
@Column({ nullable: true, type: 'text', default: 'INDEX' })
key: string;
@Column({ nullable: false, type: 'text' })
icon: string;
@Column({ nullable: false, type: 'int', default: 0 })
position: number;
@Column({ nullable: false, default: false, type: 'boolean' })
isCompact: boolean;
@Column({
type: 'enum',
enum: ViewOpenRecordIn,
nullable: false,
default: ViewOpenRecordIn.SIDE_PANEL,
})
openRecordIn: ViewOpenRecordIn;
@Column({
type: 'enum',
enum: AggregateOperations,
nullable: true,
})
kanbanAggregateOperation?: AggregateOperations | null;
@Column({ nullable: true, type: 'uuid' })
kanbanAggregateOperationFieldMetadataId?: string | null;
@Column({ nullable: false, type: 'uuid' })
workspaceId: string;
@CreateDateColumn({ type: 'timestamptz' })
createdAt: Date;
@UpdateDateColumn({ type: 'timestamptz' })
updatedAt: Date;
@DeleteDateColumn({ type: 'timestamptz' })
deletedAt?: Date | null;
@ManyToOne(() => Workspace, {
onDelete: 'CASCADE',
})
@JoinColumn({ name: 'workspaceId' })
workspace: Relation<Workspace>;
@OneToMany(() => ViewField, (viewField) => viewField.view)
viewFields: Relation<ViewField[]>;
@OneToMany(() => ViewFilter, (viewFilter) => viewFilter.view)
viewFilters: Relation<ViewFilter[]>;
@OneToMany(() => ViewSort, (viewSort) => viewSort.view)
viewSorts: Relation<ViewSort[]>;
@OneToMany(() => ViewGroup, (viewGroup) => viewGroup.view)
viewGroups: Relation<ViewGroup[]>;
@OneToMany(() => ViewFilterGroup, (viewFilterGroup) => viewFilterGroup.view)
viewFilterGroups: Relation<ViewFilterGroup[]>;
}