Sync table from frontend (#4894)
This PR: - separates the existing updateSyncStatus endpoint into 2 endpoints - creates mutations and hooks that will call those endpoints - trigger the hook on toggle - removes form logic and add a separated component for toggling --------- Co-authored-by: Thomas Trompette <thomast@twenty.com>
This commit is contained in:
@ -126,11 +126,10 @@ export class RemoteServerService<T extends RemoteServerType> {
|
||||
|
||||
if (remoteTablesToRemove.length) {
|
||||
for (const remoteTable of remoteTablesToRemove) {
|
||||
await this.remoteTableService.updateRemoteTableSyncStatus(
|
||||
await this.remoteTableService.unsyncRemoteTable(
|
||||
{
|
||||
remoteServerId: id,
|
||||
name: remoteTable.name,
|
||||
status: RemoteTableStatus.NOT_SYNCED,
|
||||
},
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
@ -1,9 +1,5 @@
|
||||
import { InputType, Field, ID } from '@nestjs/graphql';
|
||||
|
||||
import { IsEnum } from 'class-validator';
|
||||
|
||||
import { RemoteTableStatus } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
|
||||
|
||||
@InputType()
|
||||
export class RemoteTableInput {
|
||||
@Field(() => ID)
|
||||
@ -12,10 +8,6 @@ export class RemoteTableInput {
|
||||
@Field(() => String)
|
||||
name: string;
|
||||
|
||||
@IsEnum(RemoteTableStatus)
|
||||
@Field(() => RemoteTableStatus)
|
||||
status: RemoteTableStatus;
|
||||
|
||||
@Field(() => String)
|
||||
schema?: string;
|
||||
}
|
||||
|
||||
@ -22,5 +22,5 @@ export class RemoteTableDTO {
|
||||
status: RemoteTableStatus;
|
||||
|
||||
@Field(() => String)
|
||||
schema: string;
|
||||
schema?: string;
|
||||
}
|
||||
|
||||
@ -40,14 +40,11 @@ export class RemotePostgresTableService {
|
||||
|
||||
await dataSource.destroy();
|
||||
|
||||
return columns.map(
|
||||
(column) =>
|
||||
({
|
||||
columnName: column.column_name,
|
||||
dataType: column.data_type,
|
||||
udtName: column.udt_name,
|
||||
}) as RemoteTableColumn,
|
||||
);
|
||||
return columns.map((column) => ({
|
||||
columnName: column.column_name,
|
||||
dataType: column.data_type,
|
||||
udtName: column.udt_name,
|
||||
}));
|
||||
}
|
||||
|
||||
public async fetchTablesFromRemotePostgresSchema(
|
||||
@ -78,12 +75,9 @@ export class RemotePostgresTableService {
|
||||
|
||||
await dataSource.destroy();
|
||||
|
||||
return remotePostgresTables.map(
|
||||
(table) =>
|
||||
({
|
||||
tableName: table.table_name,
|
||||
tableSchema: table.table_schema,
|
||||
}) as RemoteTable,
|
||||
);
|
||||
return remotePostgresTables.map((table) => ({
|
||||
tableName: table.table_name,
|
||||
tableSchema: table.table_schema,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import { RemoteTableDTO } from 'src/engine/metadata-modules/remote-server/remote
|
||||
import { RemoteTableService } from 'src/engine/metadata-modules/remote-server/remote-table/remote-table.service';
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Resolver(() => RemoteTableDTO)
|
||||
@Resolver()
|
||||
export class RemoteTableResolver {
|
||||
constructor(private readonly remoteTableService: RemoteTableService) {}
|
||||
|
||||
@ -26,13 +26,18 @@ export class RemoteTableResolver {
|
||||
}
|
||||
|
||||
@Mutation(() => RemoteTableDTO)
|
||||
async updateRemoteTableSyncStatus(
|
||||
async syncRemoteTable(
|
||||
@Args('input') input: RemoteTableInput,
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
) {
|
||||
return this.remoteTableService.updateRemoteTableSyncStatus(
|
||||
input,
|
||||
workspaceId,
|
||||
);
|
||||
return this.remoteTableService.syncRemoteTable(input, workspaceId);
|
||||
}
|
||||
|
||||
@Mutation(() => RemoteTableDTO)
|
||||
async unsyncRemoteTable(
|
||||
@Args('input') input: RemoteTableInput,
|
||||
@AuthWorkspace() { id: workspaceId }: Workspace,
|
||||
) {
|
||||
return this.remoteTableService.unsyncRemoteTable(input, workspaceId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,10 @@ import {
|
||||
RemoteServerType,
|
||||
RemoteServerEntity,
|
||||
} from 'src/engine/metadata-modules/remote-server/remote-server.entity';
|
||||
import { RemoteTableStatus } from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
|
||||
import {
|
||||
RemoteTableDTO,
|
||||
RemoteTableStatus,
|
||||
} from 'src/engine/metadata-modules/remote-server/remote-table/dtos/remote-table.dto';
|
||||
import {
|
||||
isPostgreSQLIntegrationEnabled,
|
||||
mapUdtNameToFieldType,
|
||||
@ -86,10 +89,7 @@ export class RemoteTableService {
|
||||
}));
|
||||
}
|
||||
|
||||
public async updateRemoteTableSyncStatus(
|
||||
input: RemoteTableInput,
|
||||
workspaceId: string,
|
||||
) {
|
||||
public async syncRemoteTable(input: RemoteTableInput, workspaceId: string) {
|
||||
const remoteServer = await this.remoteServerRepository.findOne({
|
||||
where: {
|
||||
id: input.remoteServerId,
|
||||
@ -101,31 +101,33 @@ export class RemoteTableService {
|
||||
throw new NotFoundException('Remote server does not exist');
|
||||
}
|
||||
|
||||
switch (input.status) {
|
||||
case RemoteTableStatus.SYNCED:
|
||||
await this.createForeignTableAndMetadata(
|
||||
input,
|
||||
remoteServer,
|
||||
workspaceId,
|
||||
);
|
||||
break;
|
||||
case RemoteTableStatus.NOT_SYNCED:
|
||||
await this.removeForeignTableAndMetadata(input, workspaceId);
|
||||
break;
|
||||
default:
|
||||
throw new Error('Unsupported remote table status');
|
||||
}
|
||||
const remoteTable = await this.createForeignTableAndMetadata(
|
||||
input,
|
||||
remoteServer,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
await this.workspaceCacheVersionService.incrementVersion(workspaceId);
|
||||
|
||||
return input;
|
||||
return remoteTable;
|
||||
}
|
||||
|
||||
public async unsyncRemoteTable(input: RemoteTableInput, workspaceId: string) {
|
||||
const remoteTable = await this.removeForeignTableAndMetadata(
|
||||
input,
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
await this.workspaceCacheVersionService.incrementVersion(workspaceId);
|
||||
|
||||
return remoteTable;
|
||||
}
|
||||
|
||||
private async createForeignTableAndMetadata(
|
||||
input: RemoteTableInput,
|
||||
remoteServer: RemoteServerEntity<RemoteServerType>,
|
||||
workspaceId: string,
|
||||
) {
|
||||
): Promise<RemoteTableDTO> {
|
||||
if (!input.schema) {
|
||||
throw new Error('Schema is required for syncing remote table');
|
||||
}
|
||||
@ -198,7 +200,7 @@ export class RemoteTableService {
|
||||
icon: 'IconUser',
|
||||
isRemote: true,
|
||||
remoteTablePrimaryKeyColumnType: remoteTableIdColumn.udtName,
|
||||
} as CreateObjectInput);
|
||||
} satisfies CreateObjectInput);
|
||||
|
||||
for (const column of remoteTableColumns) {
|
||||
const field = await this.fieldMetadataService.createOne({
|
||||
@ -212,7 +214,7 @@ export class RemoteTableService {
|
||||
isRemoteCreation: true,
|
||||
isNullable: true,
|
||||
icon: 'IconUser',
|
||||
} as CreateFieldInput);
|
||||
} satisfies CreateFieldInput);
|
||||
|
||||
if (column.columnName === 'id') {
|
||||
await this.objectMetadataService.updateOne(objectMetadata.id, {
|
||||
@ -220,12 +222,18 @@ export class RemoteTableService {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: input.name,
|
||||
schema: input.schema,
|
||||
status: RemoteTableStatus.SYNCED,
|
||||
};
|
||||
}
|
||||
|
||||
private async removeForeignTableAndMetadata(
|
||||
input: RemoteTableInput,
|
||||
workspaceId: string,
|
||||
) {
|
||||
): Promise<RemoteTableDTO> {
|
||||
const remoteTableName = getRemoteTableName(input.name);
|
||||
|
||||
const currentForeignTableNames =
|
||||
@ -261,6 +269,12 @@ export class RemoteTableService {
|
||||
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
||||
workspaceId,
|
||||
);
|
||||
|
||||
return {
|
||||
name: input.name,
|
||||
schema: input.schema,
|
||||
status: RemoteTableStatus.NOT_SYNCED,
|
||||
};
|
||||
}
|
||||
|
||||
private async fetchTableColumnsSchema(
|
||||
|
||||
Reference in New Issue
Block a user