diff --git a/.deploy/k8s/k8s-manifest.prod.yaml b/.deploy/k8s/k8s-manifest.prod.yaml index 67e542678ad..deeb68ad134 100644 --- a/.deploy/k8s/k8s-manifest.prod.yaml +++ b/.deploy/k8s/k8s-manifest.prod.yaml @@ -48,7 +48,7 @@ kind: Deployment metadata: name: gauzy-prod-api spec: - replicas: 16 + replicas: 32 selector: matchLabels: app: gauzy-prod-api diff --git a/apps/api/src/plugin-config.ts b/apps/api/src/plugin-config.ts index f7f3333d8bd..23ffaf1fcfb 100644 --- a/apps/api/src/plugin-config.ts +++ b/apps/api/src/plugin-config.ts @@ -111,11 +111,11 @@ function getDbConfig(): DataSourceOptions { : 3000, synchronize: process.env.DB_SYNCHRONIZE === 'true' ? true : false, // We are using migrations, synchronize should be set to false. uuidExtension: 'pgcrypto', - // NOTE: in new TypeORM version this unified too `poolSize` in the root of connections option object. // See https://typeorm.io/data-source-options#common-data-source-options + poolSize: process.env.DB_POOL_SIZE ? parseInt(process.env.DB_POOL_SIZE) : 40, extra: { // based on https://node-postgres.com/api/pool max connection pool size - max: process.env.DB_POOL_SIZE || 40, + max: process.env.DB_POOL_SIZE ? parseInt(process.env.DB_POOL_SIZE) : 40, // connection timeout connectionTimeoutMillis: process.env.DB_CONNECTION_TIMEOUT ? parseInt(process.env.DB_CONNECTION_TIMEOUT) diff --git a/apps/gauzy/src/app/@shared/gauzy-button-action/gauzy-button-action.component.html b/apps/gauzy/src/app/@shared/gauzy-button-action/gauzy-button-action.component.html index cabac09b814..c43be43e36c 100644 --- a/apps/gauzy/src/app/@shared/gauzy-button-action/gauzy-button-action.component.html +++ b/apps/gauzy/src/app/@shared/gauzy-button-action/gauzy-button-action.component.html @@ -1,6 +1,6 @@
-
@@ -9,17 +9,17 @@ !isDisable ? 'transition show' : 'transition show-button' " > - - -
diff --git a/apps/gauzy/src/app/pages/employees/employees.component.html b/apps/gauzy/src/app/pages/employees/employees.component.html index 33f5d23a9ef..aff4044cc40 100644 --- a/apps/gauzy/src/app/pages/employees/employees.component.html +++ b/apps/gauzy/src/app/pages/employees/employees.component.html @@ -34,6 +34,7 @@

{ + console.log(chalk.yellow(this.name + ' start running!')); + if (['sqlite', 'better-sqlite3'].includes(queryRunner.connection.options.type)) { + await this.sqliteUpQueryRunner(queryRunner); + } else { + await this.postgresUpQueryRunner(queryRunner); + } + } + + /** + * Down Migration + * + * @param queryRunner + */ + public async down(queryRunner: QueryRunner): Promise { + if (['sqlite', 'better-sqlite3'].includes(queryRunner.connection.options.type)) { + await this.sqliteDownQueryRunner(queryRunner); + } else { + await this.postgresDownQueryRunner(queryRunner); + } + } + + /** + * PostgresDB Up Migration + * + * @param queryRunner + */ + public async postgresUpQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "task_status" ADD "order" integer`); + await queryRunner.query(`ALTER TABLE "task_status" ADD CONSTRAINT "UQ_007307d7c7ddab3fe3a65e30351" UNIQUE ("order")`); + await queryRunner.query(`ALTER TABLE "task_status" ADD "isCollapsed" boolean NOT NULL DEFAULT false`); + } + + /** + * PostgresDB Down Migration + * + * @param queryRunner + */ + public async postgresDownQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "task_status" DROP COLUMN "isCollapsed"`); + await queryRunner.query(`ALTER TABLE "task_status" DROP CONSTRAINT "UQ_007307d7c7ddab3fe3a65e30351"`); + await queryRunner.query(`ALTER TABLE "task_status" DROP COLUMN "order"`); + } + + /** + * SqliteDB and BetterSQlite3DB Up Migration + * + * @param queryRunner + */ + public async sqliteUpQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_a19e8975e5c296640d457dfc11"`); + await queryRunner.query(`DROP INDEX "IDX_68eaba689ed6d3e27ec93d3e88"`); + await queryRunner.query(`DROP INDEX "IDX_b0c955f276679dd2b2735c3936"`); + await queryRunner.query(`DROP INDEX "IDX_9b9a828a49f4bd6383a4073fe2"`); + await queryRunner.query(`DROP INDEX "IDX_efbaf00a743316b394cc31e4a2"`); + await queryRunner.query(`DROP INDEX "IDX_0330b4a942b536d8d1f264abe3"`); + await queryRunner.query(`DROP INDEX "IDX_25d9737ee153411871b4d20c67"`); + await queryRunner.query(`DROP INDEX "IDX_79c525a8c2209e90186bfcbea9"`); + await queryRunner.query(`CREATE TABLE "temporary_task_status" ("id" varchar PRIMARY KEY NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "tenantId" varchar, "organizationId" varchar, "name" varchar NOT NULL, "value" varchar NOT NULL, "description" varchar, "icon" varchar, "color" varchar, "isSystem" boolean NOT NULL DEFAULT (0), "projectId" varchar, "organizationTeamId" varchar, "isActive" boolean DEFAULT (1), "isArchived" boolean DEFAULT (0), "deletedAt" datetime, "order" integer, "isCollapsed" boolean NOT NULL DEFAULT (0), CONSTRAINT "UQ_cc7abdfc6b4db2aee3b5ecad795" UNIQUE ("order"), CONSTRAINT "FK_0330b4a942b536d8d1f264abe32" FOREIGN KEY ("organizationTeamId") REFERENCES "organization_team" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_a19e8975e5c296640d457dfc11f" FOREIGN KEY ("projectId") REFERENCES "organization_project" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_efbaf00a743316b394cc31e4a20" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_9b9a828a49f4bd6383a4073fe23" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE)`); + await queryRunner.query(`INSERT INTO "temporary_task_status"("id", "createdAt", "updatedAt", "tenantId", "organizationId", "name", "value", "description", "icon", "color", "isSystem", "projectId", "organizationTeamId", "isActive", "isArchived", "deletedAt") SELECT "id", "createdAt", "updatedAt", "tenantId", "organizationId", "name", "value", "description", "icon", "color", "isSystem", "projectId", "organizationTeamId", "isActive", "isArchived", "deletedAt" FROM "task_status"`); + await queryRunner.query(`DROP TABLE "task_status"`); + await queryRunner.query(`ALTER TABLE "temporary_task_status" RENAME TO "task_status"`); + await queryRunner.query(`CREATE INDEX "IDX_a19e8975e5c296640d457dfc11" ON "task_status" ("projectId") `); + await queryRunner.query(`CREATE INDEX "IDX_68eaba689ed6d3e27ec93d3e88" ON "task_status" ("value") `); + await queryRunner.query(`CREATE INDEX "IDX_b0c955f276679dd2b2735c3936" ON "task_status" ("name") `); + await queryRunner.query(`CREATE INDEX "IDX_9b9a828a49f4bd6383a4073fe2" ON "task_status" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_efbaf00a743316b394cc31e4a2" ON "task_status" ("tenantId") `); + await queryRunner.query(`CREATE INDEX "IDX_0330b4a942b536d8d1f264abe3" ON "task_status" ("organizationTeamId") `); + await queryRunner.query(`CREATE INDEX "IDX_25d9737ee153411871b4d20c67" ON "task_status" ("isActive") `); + await queryRunner.query(`CREATE INDEX "IDX_79c525a8c2209e90186bfcbea9" ON "task_status" ("isArchived") `); + } + + /** + * SqliteDB and BetterSQlite3DB Down Migration + * + * @param queryRunner + */ + public async sqliteDownQueryRunner(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP INDEX "IDX_79c525a8c2209e90186bfcbea9"`); + await queryRunner.query(`DROP INDEX "IDX_25d9737ee153411871b4d20c67"`); + await queryRunner.query(`DROP INDEX "IDX_0330b4a942b536d8d1f264abe3"`); + await queryRunner.query(`DROP INDEX "IDX_efbaf00a743316b394cc31e4a2"`); + await queryRunner.query(`DROP INDEX "IDX_9b9a828a49f4bd6383a4073fe2"`); + await queryRunner.query(`DROP INDEX "IDX_b0c955f276679dd2b2735c3936"`); + await queryRunner.query(`DROP INDEX "IDX_68eaba689ed6d3e27ec93d3e88"`); + await queryRunner.query(`DROP INDEX "IDX_a19e8975e5c296640d457dfc11"`); + await queryRunner.query(`ALTER TABLE "task_status" RENAME TO "temporary_task_status"`); + await queryRunner.query(`CREATE TABLE "task_status" ("id" varchar PRIMARY KEY NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "tenantId" varchar, "organizationId" varchar, "name" varchar NOT NULL, "value" varchar NOT NULL, "description" varchar, "icon" varchar, "color" varchar, "isSystem" boolean NOT NULL DEFAULT (0), "projectId" varchar, "organizationTeamId" varchar, "isActive" boolean DEFAULT (1), "isArchived" boolean DEFAULT (0), "deletedAt" datetime, CONSTRAINT "FK_0330b4a942b536d8d1f264abe32" FOREIGN KEY ("organizationTeamId") REFERENCES "organization_team" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_a19e8975e5c296640d457dfc11f" FOREIGN KEY ("projectId") REFERENCES "organization_project" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_efbaf00a743316b394cc31e4a20" FOREIGN KEY ("tenantId") REFERENCES "tenant" ("id") ON DELETE CASCADE ON UPDATE NO ACTION, CONSTRAINT "FK_9b9a828a49f4bd6383a4073fe23" FOREIGN KEY ("organizationId") REFERENCES "organization" ("id") ON DELETE CASCADE ON UPDATE CASCADE)`); + await queryRunner.query(`INSERT INTO "task_status"("id", "createdAt", "updatedAt", "tenantId", "organizationId", "name", "value", "description", "icon", "color", "isSystem", "projectId", "organizationTeamId", "isActive", "isArchived", "deletedAt") SELECT "id", "createdAt", "updatedAt", "tenantId", "organizationId", "name", "value", "description", "icon", "color", "isSystem", "projectId", "organizationTeamId", "isActive", "isArchived", "deletedAt" FROM "temporary_task_status"`); + await queryRunner.query(`DROP TABLE "temporary_task_status"`); + await queryRunner.query(`CREATE INDEX "IDX_79c525a8c2209e90186bfcbea9" ON "task_status" ("isArchived") `); + await queryRunner.query(`CREATE INDEX "IDX_25d9737ee153411871b4d20c67" ON "task_status" ("isActive") `); + await queryRunner.query(`CREATE INDEX "IDX_0330b4a942b536d8d1f264abe3" ON "task_status" ("organizationTeamId") `); + await queryRunner.query(`CREATE INDEX "IDX_efbaf00a743316b394cc31e4a2" ON "task_status" ("tenantId") `); + await queryRunner.query(`CREATE INDEX "IDX_9b9a828a49f4bd6383a4073fe2" ON "task_status" ("organizationId") `); + await queryRunner.query(`CREATE INDEX "IDX_b0c955f276679dd2b2735c3936" ON "task_status" ("name") `); + await queryRunner.query(`CREATE INDEX "IDX_68eaba689ed6d3e27ec93d3e88" ON "task_status" ("value") `); + await queryRunner.query(`CREATE INDEX "IDX_a19e8975e5c296640d457dfc11" ON "task_status" ("projectId") `); + } +} diff --git a/packages/core/src/tasks/statuses/default-global-statuses.ts b/packages/core/src/tasks/statuses/default-global-statuses.ts index 26230d5f5d0..f1b1b97e0eb 100644 --- a/packages/core/src/tasks/statuses/default-global-statuses.ts +++ b/packages/core/src/tasks/statuses/default-global-statuses.ts @@ -6,47 +6,59 @@ export const DEFAULT_GLOBAL_STATUSES: ITaskStatus[] = [ value: TaskStatusEnum.OPEN, description: 'The issue/task has been reported and is waiting for the team to action it.', icon: 'task-statuses/open.svg', + order: 0, color: '#D6E4F9', isSystem: true, + isCollapsed: false }, { name: TaskStatusEnum.IN_PROGRESS, value: TaskStatusEnum.IN_PROGRESS, description: 'This issue/task is being actively worked on at the moment by the assignee.', icon: 'task-statuses/in-progress.svg', + order: 1, color: '#ECE8FC', isSystem: true, + isCollapsed: false }, { name: TaskStatusEnum.READY_FOR_REVIEW, value: TaskStatusEnum.READY_FOR_REVIEW, description: 'At this point the merge request / pull request is ready to be reviewed for issue/task.', icon: 'task-statuses/ready.svg', + order: 2, color: '#F5F1CB', isSystem: true, + isCollapsed: false }, { name: TaskStatusEnum.IN_REVIEW, value: TaskStatusEnum.IN_REVIEW, description: 'It needs peer review issue/task before being considered done.', icon: 'task-statuses/in-review.svg', + order: 3, color: '#F3D8B0', isSystem: true, + isCollapsed: false }, { name: TaskStatusEnum.BLOCKED, value: TaskStatusEnum.BLOCKED, description: 'The issue/task is missing information, wait for customer decision, etc.', icon: 'task-statuses/blocked.svg', + order: 4, color: '#F5B8B8', isSystem: true, + isCollapsed: false }, { name: TaskStatusEnum.COMPLETED, value: TaskStatusEnum.COMPLETED, description: 'The issue/task is considered finished. The resolution is correct.', icon: 'task-statuses/completed.svg', + order: 5, color: '#D4EFDF', isSystem: true, + isCollapsed: false }, ]; diff --git a/packages/core/src/tasks/statuses/status.entity.ts b/packages/core/src/tasks/statuses/status.entity.ts index 4caef61091f..ae9c166065b 100644 --- a/packages/core/src/tasks/statuses/status.entity.ts +++ b/packages/core/src/tasks/statuses/status.entity.ts @@ -28,6 +28,11 @@ export class TaskStatus extends TenantOrganizationBaseEntity implements ITaskSta @Column({ nullable: true }) description?: string; + @ApiPropertyOptional({ type: () => Number }) + @IsOptional() + @Column({ nullable: true, unique: true }) + order?: number; + @ApiPropertyOptional({ type: () => String }) @IsOptional() @Column({ nullable: true }) @@ -42,6 +47,10 @@ export class TaskStatus extends TenantOrganizationBaseEntity implements ITaskSta @Column({ default: false, update: false }) isSystem?: boolean; + @ApiPropertyOptional({ type: () => Boolean, default: false }) + @Column({ default: false }) + isCollapsed?: boolean; + fullIconUrl?: string; /* |--------------------------------------------------------------------------