diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/0-54/0-54-fix-standard-select-fields-position.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/0-54/0-54-fix-standard-select-fields-position.command.ts new file mode 100644 index 000000000..74b78bf4d --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/0-54/0-54-fix-standard-select-fields-position.command.ts @@ -0,0 +1,107 @@ +import { InjectRepository } from '@nestjs/typeorm'; + +import { Command } from 'nest-commander'; +import { Repository } from 'typeorm'; + +import { + ActiveOrSuspendedWorkspacesMigrationCommandRunner, + RunOnWorkspaceArgs, +} from 'src/database/commands/command-runners/active-or-suspended-workspaces-migration.command-runner'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { WorkspaceMetadataVersionService } from 'src/engine/metadata-modules/workspace-metadata-version/services/workspace-metadata-version.service'; +import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; +import { TASK_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids'; + +@Command({ + name: 'upgrade:0-54:fix-standard-select-fields-position', + description: 'Fix standard select fields position', +}) +export class FixStandardSelectFieldsPositionCommand extends ActiveOrSuspendedWorkspacesMigrationCommandRunner { + constructor( + @InjectRepository(Workspace, 'core') + protected readonly workspaceRepository: Repository, + protected readonly twentyORMGlobalManager: TwentyORMGlobalManager, + @InjectRepository(FieldMetadataEntity, 'metadata') + private readonly fieldMetadataRepository: Repository, + private readonly workspaceMetadataVersionService: WorkspaceMetadataVersionService, + ) { + super(workspaceRepository, twentyORMGlobalManager); + } + + override async runOnWorkspace({ + index, + total, + workspaceId, + options, + }: RunOnWorkspaceArgs): Promise { + this.logger.log( + `Running command for workspace ${workspaceId} ${index + 1}/${total}`, + ); + + await this.overrideTaskStatusFieldMetadataPosition({ + workspaceId, + dryRun: options.dryRun, + }); + } + + private async overrideTaskStatusFieldMetadataPosition({ + workspaceId, + dryRun, + }: { + workspaceId: string; + dryRun: boolean | undefined; + }) { + const taskStatusFieldMetadata = await this.fieldMetadataRepository.findOne({ + where: { + workspaceId, + standardId: TASK_STANDARD_FIELD_IDS.status, + }, + }); + + if (!taskStatusFieldMetadata) { + this.logger.warn( + `Task status field metadata not found for workspace ${workspaceId}. Exiting.`, + ); + + return; + } + + const scannedPositions = new Set(); + let biggestPosition = -1; + + // Sort options by position for consistent processing + const sortedOptions = [...taskStatusFieldMetadata.options].sort( + (a, b) => a.position - b.position, + ); + + for (const option of sortedOptions) { + if (scannedPositions.has(option.position)) { + this.logger.warn( + `Found duplicate position ${option.position} for option ${option.value} in task status field metadata for workspace ${workspaceId}.`, + ); + + option.position = biggestPosition + 1; + } + + biggestPosition = Math.max(biggestPosition, option.position); + scannedPositions.add(option.position); + } + + if (!dryRun) { + await this.fieldMetadataRepository.update( + { + workspaceId, + standardId: TASK_STANDARD_FIELD_IDS.status, + }, + { + options: sortedOptions, + }, + ); + + await this.workspaceMetadataVersionService.incrementMetadataVersion( + workspaceId, + ); + } + } +} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/0-54/0-54-upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/0-54/0-54-upgrade-version-command.module.ts new file mode 100644 index 000000000..5dc89fd24 --- /dev/null +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/0-54/0-54-upgrade-version-command.module.ts @@ -0,0 +1,26 @@ +import { Module } from '@nestjs/common'; +import { TypeOrmModule } from '@nestjs/typeorm'; + +import { FixStandardSelectFieldsPositionCommand } from 'src/database/commands/upgrade-version-command/0-54/0-54-fix-standard-select-fields-position.command'; +import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; +import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity'; +import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity'; +import { WorkspaceMetadataVersionModule } from 'src/engine/metadata-modules/workspace-metadata-version/workspace-metadata-version.module'; +import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module'; +import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module'; + +@Module({ + imports: [ + TypeOrmModule.forFeature([Workspace], 'core'), + TypeOrmModule.forFeature( + [FieldMetadataEntity, ObjectMetadataEntity], + 'metadata', + ), + WorkspaceDataSourceModule, + WorkspaceMigrationRunnerModule, + WorkspaceMetadataVersionModule, + ], + providers: [FixStandardSelectFieldsPositionCommand], + exports: [FixStandardSelectFieldsPositionCommand], +}) +export class V0_54_UpgradeVersionCommandModule {} diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts index 21ae5aae8..3114f63d7 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade-version-command.module.ts @@ -7,6 +7,7 @@ import { V0_50_UpgradeVersionCommandModule } from 'src/database/commands/upgrade import { V0_51_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/0-51/0-51-upgrade-version-command.module'; import { V0_52_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/0-52/0-52-upgrade-version-command.module'; import { V0_53_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/0-53/0-53-upgrade-version-command.module'; +import { V0_54_UpgradeVersionCommandModule } from 'src/database/commands/upgrade-version-command/0-54/0-54-upgrade-version-command.module'; import { UpgradeCommand } from 'src/database/commands/upgrade-version-command/upgrade.command'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module'; @@ -20,6 +21,7 @@ import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/worksp V0_51_UpgradeVersionCommandModule, V0_52_UpgradeVersionCommandModule, V0_53_UpgradeVersionCommandModule, + V0_54_UpgradeVersionCommandModule, WorkspaceSyncMetadataModule, ], providers: [UpgradeCommand], diff --git a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts index c763ea656..c7f2e48e7 100644 --- a/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts +++ b/packages/twenty-server/src/database/commands/upgrade-version-command/upgrade.command.ts @@ -23,6 +23,7 @@ import { CopyTypeormMigrationsCommand } from 'src/database/commands/upgrade-vers import { MigrateWorkflowEventListenersToAutomatedTriggersCommand } from 'src/database/commands/upgrade-version-command/0-53/0-53-migrate-workflow-event-listeners-to-automated-triggers.command'; import { RemoveRelationForeignKeyFieldMetadataCommand } from 'src/database/commands/upgrade-version-command/0-53/0-53-remove-relation-foreign-key-field-metadata.command'; import { UpgradeSearchVectorOnPersonEntityCommand } from 'src/database/commands/upgrade-version-command/0-53/0-53-upgrade-search-vector-on-person-entity.command'; +import { FixStandardSelectFieldsPositionCommand } from 'src/database/commands/upgrade-version-command/0-54/0-54-fix-standard-select-fields-position.command'; import { TwentyConfigService } from 'src/engine/core-modules/twenty-config/twenty-config.service'; import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity'; import { TwentyORMGlobalManager } from 'src/engine/twenty-orm/twenty-orm-global.manager'; @@ -66,6 +67,9 @@ export class UpgradeCommand extends UpgradeCommandRunner { protected readonly copyTypeormMigrationsCommand: CopyTypeormMigrationsCommand, protected readonly upgradeSearchVectorOnPersonEntityCommand: UpgradeSearchVectorOnPersonEntityCommand, protected readonly removeRelationForeignKeyFieldMetadataCommand: RemoveRelationForeignKeyFieldMetadataCommand, + + // 0.54 Commands + protected readonly fixStandardSelectFieldsPositionCommand: FixStandardSelectFieldsPositionCommand, ) { super( workspaceRepository, @@ -122,6 +126,11 @@ export class UpgradeCommand extends UpgradeCommandRunner { ], }; + const commands_054: VersionCommands = { + beforeSyncMetadata: [this.fixStandardSelectFieldsPositionCommand], + afterSyncMetadata: [], + }; + this.allCommands = { '0.43.0': commands_043, '0.44.0': commands_044, @@ -129,6 +138,7 @@ export class UpgradeCommand extends UpgradeCommandRunner { '0.51.0': commands_051, '0.52.0': commands_052, '0.53.0': commands_053, + '0.54.0': commands_054, }; } } diff --git a/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts b/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts index 00d198632..54176157d 100644 --- a/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts +++ b/packages/twenty-server/src/modules/task/standard-objects/task.workspace-entity.ts @@ -120,7 +120,7 @@ export class TaskWorkspaceEntity extends BaseWorkspaceEntity { { value: 'DONE', label: 'Done', - position: 1, + position: 2, color: 'green', }, ],