5622 add a syncemail onboarding step (#5689)
- add sync email onboarding step - refactor calendar and email visibility enums - add a new table `keyValuePair` in `core` schema - add a new resolved boolean field `skipSyncEmail` in current user https://github.com/twentyhq/twenty/assets/29927851/de791475-5bfe-47f9-8e90-76c349fba56f
This commit is contained in:
@ -15,10 +15,11 @@ import { StopDataSeedDemoWorkspaceCronCommand } from 'src/database/commands/data
|
||||
import { WorkspaceAddTotalCountCommand } from 'src/database/commands/workspace-add-total-count.command';
|
||||
import { DataSeedDemoWorkspaceCommand } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace-command';
|
||||
import { DataSeedDemoWorkspaceModule } from 'src/database/commands/data-seed-demo-workspace/data-seed-demo-workspace.module';
|
||||
import { UpdateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/0-20-update-message-channel-sync-status-enum.command';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { UpdateMessageChannelVisibilityEnumCommand } from 'src/database/commands/update-message-channel-visibility-enum.command';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { WorkspaceCacheVersionModule } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.module';
|
||||
import { UpdateMessageChannelSyncStatusEnumCommand } from 'src/database/commands/0-20-update-message-channel-sync-status-enum.command';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
|
||||
@Module({
|
||||
@ -45,6 +46,7 @@ import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadat
|
||||
ConfirmationQuestion,
|
||||
StartDataSeedDemoWorkspaceCronCommand,
|
||||
StopDataSeedDemoWorkspaceCronCommand,
|
||||
UpdateMessageChannelVisibilityEnumCommand,
|
||||
UpdateMessageChannelSyncStatusEnumCommand,
|
||||
],
|
||||
})
|
||||
|
||||
@ -0,0 +1,166 @@
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Logger } from '@nestjs/common';
|
||||
|
||||
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||
import { Repository } from 'typeorm';
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import { Workspace } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { TypeORMService } from 'src/database/typeorm/typeorm.service';
|
||||
import { MessageChannelVisibility } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { WorkspaceCacheVersionService } from 'src/engine/metadata-modules/workspace-cache-version/workspace-cache-version.service';
|
||||
|
||||
interface UpdateMessageChannelVisibilityEnumCommandOptions {
|
||||
workspaceId?: string;
|
||||
}
|
||||
|
||||
@Command({
|
||||
name: 'migrate-0.20:update-message-channel-visibility-enum',
|
||||
description:
|
||||
'Change the messageChannel visibility type and update records.visibility',
|
||||
})
|
||||
export class UpdateMessageChannelVisibilityEnumCommand extends CommandRunner {
|
||||
private readonly logger = new Logger(
|
||||
UpdateMessageChannelVisibilityEnumCommand.name,
|
||||
);
|
||||
constructor(
|
||||
@InjectRepository(Workspace, 'core')
|
||||
private readonly workspaceRepository: Repository<Workspace>,
|
||||
@InjectRepository(FieldMetadataEntity, 'metadata')
|
||||
private readonly fieldMetadataRepository: Repository<FieldMetadataEntity>,
|
||||
private readonly typeORMService: TypeORMService,
|
||||
private readonly dataSourceService: DataSourceService,
|
||||
private readonly workspaceCacheVersionService: WorkspaceCacheVersionService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
@Option({
|
||||
flags: '-w, --workspace-id [workspace_id]',
|
||||
description: 'workspace id. Command runs on all workspaces if not provided',
|
||||
required: false,
|
||||
})
|
||||
parseWorkspaceId(value: string): string {
|
||||
return value;
|
||||
}
|
||||
|
||||
async run(
|
||||
_passedParam: string[],
|
||||
options: UpdateMessageChannelVisibilityEnumCommandOptions,
|
||||
): Promise<void> {
|
||||
let workspaceIds: string[] = [];
|
||||
|
||||
if (options.workspaceId) {
|
||||
workspaceIds = [options.workspaceId];
|
||||
} else {
|
||||
workspaceIds = (await this.workspaceRepository.find()).map(
|
||||
(workspace) => workspace.id,
|
||||
);
|
||||
}
|
||||
|
||||
if (!workspaceIds.length) {
|
||||
this.logger.log(chalk.yellow('No workspace found'));
|
||||
|
||||
return;
|
||||
} else {
|
||||
this.logger.log(
|
||||
chalk.green(`Running command on ${workspaceIds.length} workspaces`),
|
||||
);
|
||||
}
|
||||
|
||||
for (const workspaceId of workspaceIds) {
|
||||
const dataSourceMetadatas =
|
||||
await this.dataSourceService.getDataSourcesMetadataFromWorkspaceId(
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
for (const dataSourceMetadata of dataSourceMetadatas) {
|
||||
const workspaceDataSource =
|
||||
await this.typeORMService.connectToDataSource(dataSourceMetadata);
|
||||
|
||||
if (workspaceDataSource) {
|
||||
const queryRunner = workspaceDataSource.createQueryRunner();
|
||||
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
const newMessageChannelVisibilities = Object.values(
|
||||
MessageChannelVisibility,
|
||||
);
|
||||
|
||||
try {
|
||||
await queryRunner.query(
|
||||
`ALTER TYPE "${dataSourceMetadata.schema}"."messageChannel_visibility_enum" RENAME TO "messageChannel_visibility_enum_old"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TYPE "${
|
||||
dataSourceMetadata.schema
|
||||
}"."messageChannel_visibility_enum" AS ENUM ('${newMessageChannelVisibilities.join(
|
||||
"','",
|
||||
)}')`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "${dataSourceMetadata.schema}"."messageChannel" ALTER COLUMN "visibility" DROP DEFAULT`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "${dataSourceMetadata.schema}"."messageChannel" ALTER COLUMN "visibility" TYPE text`,
|
||||
);
|
||||
for (const newMessageChannelVisibility of newMessageChannelVisibilities) {
|
||||
await queryRunner.query(
|
||||
`UPDATE "${
|
||||
dataSourceMetadata.schema
|
||||
}"."messageChannel" SET "visibility" = '${newMessageChannelVisibility}' WHERE "visibility" = '${newMessageChannelVisibility.toLowerCase()}'`,
|
||||
);
|
||||
}
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "${dataSourceMetadata.schema}"."messageChannel" ALTER COLUMN "visibility" TYPE "${dataSourceMetadata.schema}"."messageChannel_visibility_enum" USING "visibility"::text::"${dataSourceMetadata.schema}"."messageChannel_visibility_enum"`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "${dataSourceMetadata.schema}"."messageChannel" ALTER COLUMN "visibility" SET DEFAULT '${MessageChannelVisibility.SHARE_EVERYTHING}'`,
|
||||
);
|
||||
await queryRunner.query(
|
||||
`DROP TYPE "${dataSourceMetadata.schema}"."messageChannel_visibility_enum_old"`,
|
||||
);
|
||||
await queryRunner.commitTransaction();
|
||||
} catch (error) {
|
||||
await queryRunner.rollbackTransaction();
|
||||
this.logger.log(
|
||||
chalk.red(`Running command on workspace ${workspaceId} failed`),
|
||||
);
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.workspaceCacheVersionService.incrementVersion(workspaceId);
|
||||
|
||||
const visibilityFieldsMetadata = await this.fieldMetadataRepository.find({
|
||||
where: { name: 'visibility', workspaceId },
|
||||
});
|
||||
|
||||
for (const visibilityFieldMetadata of visibilityFieldsMetadata) {
|
||||
const newOptions = visibilityFieldMetadata.options.map((option) => {
|
||||
return { ...option, value: option.value.toUpperCase() };
|
||||
});
|
||||
|
||||
const newDefaultValue =
|
||||
typeof visibilityFieldMetadata.defaultValue === 'string'
|
||||
? visibilityFieldMetadata.defaultValue.toUpperCase()
|
||||
: visibilityFieldMetadata.defaultValue;
|
||||
|
||||
await this.fieldMetadataRepository.update(visibilityFieldMetadata.id, {
|
||||
defaultValue: newDefaultValue,
|
||||
options: newOptions,
|
||||
});
|
||||
}
|
||||
|
||||
this.logger.log(
|
||||
chalk.green(`Running command on workspace ${workspaceId} done`),
|
||||
);
|
||||
}
|
||||
|
||||
this.logger.log(chalk.green(`Command completed!`));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user