Remove sync-metadata and IS_WORKSPACE_CREATION_V2_ENABLED feature flag (#16997)
# Introduction Followup of https://github.com/twentyhq/twenty/pull/17001#pullrequestreview-3638508738 close https://github.com/twentyhq/core-team-issues/issues/1910 We've completely decom the `sync-metadata` in production. We're now then removing its implementation in favor of the v2. ## TODO: - [x] Remove sync-metadata implem and commands - [x] Remove workspace decorators - [x] Type each deprecated field to deprecated on their workspaceEntity - [x] Remove the `workspace-sync-metadata` folder entirely - [x] remove workspace migration - [x] workspace migration removal migration - [x] remove the `v2` references from workspace manager file names - [x] remove the `v2` references from workspace manager modules - [ ] Double check impact on translation file path updates ## Note - Removed the gate logic - Remains some service v2 naming, serverless needs to be migrated on v2 fully - Removed workspaceMigration service app health consumption, making it always returning up ( no more down ) cc @FelixMalfait ( quite obsolete health check now, will require complete refactor once we introduce inter app dependency etc )
This commit is contained in:
-220
@@ -1,220 +0,0 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
import { getDataSourceToken, getRepositoryToken } from '@nestjs/typeorm';
|
||||
|
||||
import { type DataSource, type Repository } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { AgentService } from 'src/engine/metadata-modules/ai/ai-agent/agent.service';
|
||||
import { DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { PermissionsService } from 'src/engine/metadata-modules/permissions/permissions.service';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
|
||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
import { GlobalWorkspaceOrmManager } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-orm.manager';
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { TwentyStandardApplicationService } from 'src/engine/workspace-manager/twenty-standard-application/services/twenty-standard-application.service';
|
||||
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
|
||||
import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service';
|
||||
|
||||
describe('WorkspaceManagerService', () => {
|
||||
let service: WorkspaceManagerService;
|
||||
let workspaceMigrationRepository: Repository<WorkspaceMigrationEntity>;
|
||||
let dataSourceRepository: Repository<DataSourceEntity>;
|
||||
let roleTargetRepository: Repository<RoleTargetEntity>;
|
||||
let roleRepository: Repository<RoleEntity>;
|
||||
let serverlessFunctionRepository: Repository<ServerlessFunctionEntity>;
|
||||
let mockDataSource: jest.Mocked<DataSource>;
|
||||
let objectMetadataService: ObjectMetadataService;
|
||||
|
||||
beforeEach(async () => {
|
||||
mockDataSource = {
|
||||
transaction: jest.fn(),
|
||||
} as any;
|
||||
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
WorkspaceManagerService,
|
||||
WorkspaceMigrationService,
|
||||
DataSourceService,
|
||||
{
|
||||
provide: getDataSourceToken(),
|
||||
useValue: mockDataSource,
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(WorkspaceEntity),
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(UserWorkspaceEntity),
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(FieldMetadataEntity),
|
||||
useValue: {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(ObjectMetadataEntity),
|
||||
useValue: {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(WorkspaceMigrationEntity),
|
||||
useValue: {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(DataSourceEntity),
|
||||
useValue: {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RoleTargetEntity),
|
||||
useValue: {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(RoleEntity),
|
||||
useValue: {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: getRepositoryToken(ServerlessFunctionEntity),
|
||||
useValue: {
|
||||
delete: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: PermissionsService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: FeatureFlagService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: RoleService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: ApplicationService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: UserRoleService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: WorkspaceDataSourceService,
|
||||
useValue: {
|
||||
deleteWorkspaceDBSchema: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: WorkspaceSyncMetadataService,
|
||||
useValue: {},
|
||||
},
|
||||
{
|
||||
provide: ObjectMetadataService,
|
||||
useValue: {
|
||||
deleteWorkspaceAllObjectMetadata: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: TwentyStandardApplicationService,
|
||||
useValue: {
|
||||
synchronizeTwentyStandardApplicationOrThrow: jest.fn(),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: AgentService,
|
||||
useValue: {
|
||||
createOneAgent: jest
|
||||
.fn()
|
||||
.mockResolvedValue({ id: 'mock-agent-id' }),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: GlobalWorkspaceOrmManager,
|
||||
useValue: {
|
||||
getDataSourceForWorkspace: jest.fn().mockResolvedValue({
|
||||
transaction: jest.fn(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
useValue: {
|
||||
invalidateEntireCache: jest.fn(),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<WorkspaceManagerService>(WorkspaceManagerService);
|
||||
workspaceMigrationRepository = module.get<
|
||||
Repository<WorkspaceMigrationEntity>
|
||||
>(getRepositoryToken(WorkspaceMigrationEntity));
|
||||
dataSourceRepository = module.get<Repository<DataSourceEntity>>(
|
||||
getRepositoryToken(DataSourceEntity),
|
||||
);
|
||||
roleTargetRepository = module.get<Repository<RoleTargetEntity>>(
|
||||
getRepositoryToken(RoleTargetEntity),
|
||||
);
|
||||
roleRepository = module.get<Repository<RoleEntity>>(
|
||||
getRepositoryToken(RoleEntity),
|
||||
);
|
||||
serverlessFunctionRepository = module.get<
|
||||
Repository<ServerlessFunctionEntity>
|
||||
>(getRepositoryToken(ServerlessFunctionEntity));
|
||||
objectMetadataService = module.get<ObjectMetadataService>(
|
||||
ObjectMetadataService,
|
||||
);
|
||||
});
|
||||
|
||||
it('should be defined', () => {
|
||||
expect(service).toBeDefined();
|
||||
});
|
||||
|
||||
describe('delete', () => {
|
||||
it('should delete all the workspace metadata tables and workspace schema', async () => {
|
||||
await service.delete('workspace-id');
|
||||
expect(
|
||||
objectMetadataService.deleteWorkspaceAllObjectMetadata,
|
||||
).toHaveBeenCalled();
|
||||
expect(workspaceMigrationRepository.delete).toHaveBeenCalledWith({
|
||||
workspaceId: 'workspace-id',
|
||||
});
|
||||
expect(dataSourceRepository.delete).toHaveBeenCalledWith({
|
||||
workspaceId: 'workspace-id',
|
||||
});
|
||||
expect(roleTargetRepository.delete).toHaveBeenCalledWith({
|
||||
workspaceId: 'workspace-id',
|
||||
});
|
||||
expect(roleRepository.delete).toHaveBeenCalledWith({
|
||||
workspaceId: 'workspace-id',
|
||||
});
|
||||
expect(serverlessFunctionRepository.delete).toHaveBeenCalledWith({
|
||||
workspaceId: 'workspace-id',
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -25,7 +25,7 @@ import { TimelineActivitySeederService } from 'src/engine/workspace-manager/dev-
|
||||
import { DevSeederMetadataService } from 'src/engine/workspace-manager/dev-seeder/metadata/services/dev-seeder-metadata.service';
|
||||
import { DevSeederService } from 'src/engine/workspace-manager/dev-seeder/services/dev-seeder.service';
|
||||
import { TwentyStandardApplicationModule } from 'src/engine/workspace-manager/twenty-standard-application/twenty-standard-application.module';
|
||||
import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -46,7 +46,7 @@ import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspa
|
||||
ObjectPermissionModule,
|
||||
WorkspaceManyOrAllFlatEntityMapsCacheModule,
|
||||
WorkspaceCacheModule,
|
||||
WorkspaceMigrationV2Module,
|
||||
WorkspaceMigrationModule,
|
||||
TwentyStandardApplicationModule,
|
||||
],
|
||||
exports: [DevSeederService],
|
||||
|
||||
-270
@@ -1,270 +0,0 @@
|
||||
import { isString } from '@sniptt/guards';
|
||||
import { type DataSource, type QueryRunner } from 'typeorm';
|
||||
|
||||
import { getFlatFieldsFromFlatObjectMetadata } from 'src/engine/api/graphql/workspace-schema-builder/utils/get-flat-fields-for-flat-object-metadata.util';
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ViewFieldEntity } from 'src/engine/metadata-modules/view-field/entities/view-field.entity';
|
||||
import { ViewFilterEntity } from 'src/engine/metadata-modules/view-filter/entities/view-filter.entity';
|
||||
import { ViewGroupEntity } from 'src/engine/metadata-modules/view-group/entities/view-group.entity';
|
||||
import { ViewEntity } from 'src/engine/metadata-modules/view/entities/view.entity';
|
||||
import { ViewKey } from 'src/engine/metadata-modules/view/enums/view-key.enum';
|
||||
import { ViewOpenRecordIn } from 'src/engine/metadata-modules/view/enums/view-open-record-in';
|
||||
import { ViewType } from 'src/engine/metadata-modules/view/enums/view-type.enum';
|
||||
import { ViewVisibility } from 'src/engine/metadata-modules/view/enums/view-visibility.enum';
|
||||
import { ViewOpenRecordInType } from 'src/engine/metadata-modules/view/types/view-open-record-in-type.type';
|
||||
import { type WorkspaceEntityManager } from 'src/engine/twenty-orm/entity-manager/workspace-entity-manager';
|
||||
import { shouldSeedWorkspaceFavorite } from 'src/engine/utils/should-seed-workspace-favorite';
|
||||
import { prefillWorkspaceFavorites } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workspace-favorites';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { calendarEventsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/calendar-events-all.view';
|
||||
import { companiesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/companies-all.view';
|
||||
import { dashboardsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/dashboards-all.view';
|
||||
import { messageThreadsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/message-threads-all.view';
|
||||
import { messagesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/messages-all.view';
|
||||
import { notesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/notes-all.view';
|
||||
import { opportunitiesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/opportunities-all.view';
|
||||
import { opportunitiesByStageView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/opportunity-by-stage.view';
|
||||
import { peopleAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/people-all.view';
|
||||
import { tasksAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-all.view';
|
||||
import { tasksAssignedToMeView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-assigned-to-me';
|
||||
import { tasksByStatusView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/tasks-by-status.view';
|
||||
import { timelineActivitiesAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/timeline-activities-all.view';
|
||||
import { workflowRunsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/workflow-runs-all.view';
|
||||
import { workflowVersionsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/workflow-versions-all.view';
|
||||
import { workflowsAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/workflows-all.view';
|
||||
import { workspaceMembersAllView } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/workspace-members-all.view';
|
||||
|
||||
type PrefillCoreViewsArgs = {
|
||||
coreDataSource: DataSource;
|
||||
workspaceId: string;
|
||||
flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>;
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>;
|
||||
featureFlags?: Record<string, boolean>;
|
||||
workspaceSchemaName: string;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
};
|
||||
|
||||
// This is a temporary function to build the object metadata items from the flat maps.
|
||||
// We should use the maps in the seeders instead.
|
||||
const buildObjectMetadataItemsFromFlatMaps = (
|
||||
flatObjectMetadataMaps: FlatEntityMaps<FlatObjectMetadata>,
|
||||
flatFieldMetadataMaps: FlatEntityMaps<FlatFieldMetadata>,
|
||||
): ObjectMetadataEntity[] => {
|
||||
return Object.values(flatObjectMetadataMaps.byId)
|
||||
.filter((flatObjectMetadata) => flatObjectMetadata !== undefined)
|
||||
.map((flatObjectMetadata) => {
|
||||
const fields = getFlatFieldsFromFlatObjectMetadata(
|
||||
flatObjectMetadata,
|
||||
flatFieldMetadataMaps,
|
||||
);
|
||||
|
||||
return {
|
||||
...flatObjectMetadata,
|
||||
fields,
|
||||
} as unknown as ObjectMetadataEntity;
|
||||
});
|
||||
};
|
||||
|
||||
export const prefillCoreViews = async ({
|
||||
coreDataSource,
|
||||
workspaceId,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
workspaceSchemaName,
|
||||
twentyStandardFlatApplication,
|
||||
}: PrefillCoreViewsArgs): Promise<ViewEntity[]> => {
|
||||
const objectMetadataItems = buildObjectMetadataItemsFromFlatMaps(
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
);
|
||||
const views = [
|
||||
companiesAllView,
|
||||
peopleAllView,
|
||||
opportunitiesAllView,
|
||||
opportunitiesByStageView,
|
||||
notesAllView,
|
||||
tasksAllView,
|
||||
tasksAssignedToMeView,
|
||||
tasksByStatusView,
|
||||
workflowsAllView,
|
||||
workflowVersionsAllView,
|
||||
workflowRunsAllView,
|
||||
dashboardsAllView,
|
||||
workspaceMembersAllView,
|
||||
messagesAllView,
|
||||
messageThreadsAllView,
|
||||
calendarEventsAllView,
|
||||
timelineActivitiesAllView,
|
||||
].map((seeder) =>
|
||||
seeder({
|
||||
objectMetadataItems,
|
||||
useCoreNaming: true,
|
||||
twentyStandardFlatApplication,
|
||||
}),
|
||||
);
|
||||
|
||||
const queryRunner = coreDataSource.createQueryRunner();
|
||||
|
||||
await queryRunner.connect();
|
||||
|
||||
try {
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
const createdViews = await createCoreViews(
|
||||
queryRunner,
|
||||
workspaceId,
|
||||
views,
|
||||
twentyStandardFlatApplication,
|
||||
);
|
||||
|
||||
await prefillWorkspaceFavorites(
|
||||
createdViews
|
||||
.filter(
|
||||
(view) =>
|
||||
view.key === 'INDEX' &&
|
||||
shouldSeedWorkspaceFavorite(
|
||||
view.objectMetadataId,
|
||||
objectMetadataItems,
|
||||
),
|
||||
)
|
||||
.map((view) => view.id),
|
||||
queryRunner.manager as WorkspaceEntityManager,
|
||||
workspaceSchemaName,
|
||||
);
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
return createdViews;
|
||||
} catch (error) {
|
||||
if (queryRunner.isTransactionActive) {
|
||||
try {
|
||||
await queryRunner.rollbackTransaction();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.trace(`Failed to rollback transaction: ${error.message}`);
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
};
|
||||
|
||||
export const createCoreViews = async (
|
||||
queryRunner: QueryRunner,
|
||||
workspaceId: string,
|
||||
viewDefinitions: ViewDefinition[],
|
||||
twentyStandardFlatApplication: FlatApplication,
|
||||
): Promise<ViewEntity[]> => {
|
||||
const coreViews: Partial<ViewEntity>[] = viewDefinitions.map(
|
||||
({
|
||||
id,
|
||||
name,
|
||||
objectMetadataId,
|
||||
type,
|
||||
key,
|
||||
position,
|
||||
icon,
|
||||
isCustom,
|
||||
openRecordIn,
|
||||
mainGroupByFieldMetadataId,
|
||||
kanbanAggregateOperation,
|
||||
kanbanAggregateOperationFieldMetadataId,
|
||||
applicationId,
|
||||
universalIdentifier,
|
||||
}) => ({
|
||||
id,
|
||||
name: isString(name) ? name : name.message || '',
|
||||
objectMetadataId,
|
||||
type: type === 'kanban' ? ViewType.KANBAN : ViewType.TABLE,
|
||||
key: key === ViewKey.INDEX ? ViewKey.INDEX : null,
|
||||
position,
|
||||
icon,
|
||||
isCompact: false,
|
||||
isCustom: isCustom ?? false,
|
||||
openRecordIn:
|
||||
openRecordIn === ViewOpenRecordInType.RECORD_PAGE
|
||||
? ViewOpenRecordIn.RECORD_PAGE
|
||||
: ViewOpenRecordIn.SIDE_PANEL,
|
||||
kanbanAggregateOperation,
|
||||
kanbanAggregateOperationFieldMetadataId,
|
||||
mainGroupByFieldMetadataId,
|
||||
workspaceId,
|
||||
anyFieldFilterValue: null,
|
||||
visibility: ViewVisibility.WORKSPACE,
|
||||
applicationId,
|
||||
universalIdentifier,
|
||||
}),
|
||||
);
|
||||
|
||||
const viewRepository = queryRunner.manager.getRepository(ViewEntity);
|
||||
const createdViews = await viewRepository.save(coreViews);
|
||||
|
||||
for (const viewDefinition of viewDefinitions) {
|
||||
if (viewDefinition.fields && viewDefinition.fields.length > 0) {
|
||||
const coreViewFields: Partial<ViewFieldEntity>[] =
|
||||
viewDefinition.fields.map((field) => ({
|
||||
fieldMetadataId: field.fieldMetadataId,
|
||||
position: field.position,
|
||||
isVisible: field.isVisible,
|
||||
size: field.size,
|
||||
viewId: viewDefinition.id,
|
||||
workspaceId,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
universalIdentifier: field.universalIdentifier,
|
||||
}));
|
||||
|
||||
const viewFieldRepository =
|
||||
queryRunner.manager.getRepository(ViewFieldEntity);
|
||||
|
||||
await viewFieldRepository.save(coreViewFields);
|
||||
}
|
||||
|
||||
if (viewDefinition.filters && viewDefinition.filters.length > 0) {
|
||||
const coreViewFilters: Partial<ViewFilterEntity>[] =
|
||||
viewDefinition.filters.map((filter) => ({
|
||||
fieldMetadataId: filter.fieldMetadataId,
|
||||
viewId: viewDefinition.id,
|
||||
operand: filter.operand,
|
||||
value: filter.value,
|
||||
workspaceId,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
universalIdentifier: filter.universalIdentifier,
|
||||
}));
|
||||
|
||||
const viewFilterRepository =
|
||||
queryRunner.manager.getRepository(ViewFilterEntity);
|
||||
|
||||
await viewFilterRepository.save(coreViewFilters);
|
||||
}
|
||||
|
||||
if (
|
||||
'groups' in viewDefinition &&
|
||||
viewDefinition.groups &&
|
||||
viewDefinition.groups.length > 0
|
||||
) {
|
||||
const coreViewGroups: Partial<ViewGroupEntity>[] =
|
||||
viewDefinition.groups.map((group) => ({
|
||||
fieldMetadataId: group.fieldMetadataId,
|
||||
isVisible: group.isVisible,
|
||||
fieldValue: group.fieldValue,
|
||||
position: group.position,
|
||||
viewId: viewDefinition.id,
|
||||
workspaceId,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
universalIdentifier: group.universalIdentifier,
|
||||
}));
|
||||
|
||||
const viewGroupRepository =
|
||||
queryRunner.manager.getRepository(ViewGroupEntity);
|
||||
|
||||
await viewGroupRepository.save(coreViewGroups);
|
||||
}
|
||||
}
|
||||
|
||||
return createdViews;
|
||||
};
|
||||
-46
@@ -1,46 +0,0 @@
|
||||
import { type MessageDescriptor } from '@lingui/core';
|
||||
import { type ViewFilterOperand } from 'twenty-shared/types';
|
||||
|
||||
import { type AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
|
||||
import { type ViewOpenRecordInType } from 'src/engine/metadata-modules/view/types/view-open-record-in-type.type';
|
||||
|
||||
export interface ViewDefinition {
|
||||
id?: string;
|
||||
name: string | MessageDescriptor;
|
||||
objectMetadataId: string;
|
||||
type: string;
|
||||
key: string | null;
|
||||
position: number;
|
||||
applicationId: string;
|
||||
universalIdentifier: string;
|
||||
icon?: string;
|
||||
isCustom?: boolean;
|
||||
openRecordIn?: ViewOpenRecordInType;
|
||||
kanbanAggregateOperation?: AggregateOperations;
|
||||
kanbanAggregateOperationFieldMetadataId?: string;
|
||||
mainGroupByFieldMetadataId?: string;
|
||||
calendarFieldMetadataId?: string;
|
||||
calendarLayout?: string;
|
||||
fields?: {
|
||||
universalIdentifier: string;
|
||||
fieldMetadataId: string;
|
||||
position: number;
|
||||
isVisible: boolean;
|
||||
size: number;
|
||||
aggregateOperation?: AggregateOperations;
|
||||
}[];
|
||||
filters?: {
|
||||
universalIdentifier: string;
|
||||
fieldMetadataId: string;
|
||||
displayValue: string;
|
||||
operand: ViewFilterOperand;
|
||||
value: string;
|
||||
}[];
|
||||
groups?: {
|
||||
universalIdentifier: string;
|
||||
fieldMetadataId: string;
|
||||
isVisible: boolean;
|
||||
fieldValue: string;
|
||||
position: number;
|
||||
}[];
|
||||
}
|
||||
-160
@@ -1,160 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { DEFAULT_VIEW_FIELD_SIZE } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/constants/DEFAULT_VIEW_FIELD_SIZE';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
CALENDAR_EVENT_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const calendarEventsAllView = ({
|
||||
objectMetadataItems,
|
||||
twentyStandardFlatApplication,
|
||||
useCoreNaming,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const calendarEventObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.calendarEvent,
|
||||
);
|
||||
|
||||
if (!calendarEventObjectMetadata) {
|
||||
throw new Error('CalendarEvent object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Calendar Events',
|
||||
objectMetadataId: calendarEventObjectMetadata.id ?? '',
|
||||
type: 'calendar',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconCalendar',
|
||||
calendarFieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === CALENDAR_EVENT_STANDARD_FIELD_IDS.startsAt,
|
||||
)?.id ?? '',
|
||||
calendarLayout: 'MONTH',
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === CALENDAR_EVENT_STANDARD_FIELD_IDS.title,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: DEFAULT_VIEW_FIELD_SIZE,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.viewFields
|
||||
.title.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === CALENDAR_EVENT_STANDARD_FIELD_IDS.startsAt,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.viewFields
|
||||
.startsAt.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === CALENDAR_EVENT_STANDARD_FIELD_IDS.endsAt,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.viewFields
|
||||
.endsAt.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === CALENDAR_EVENT_STANDARD_FIELD_IDS.isFullDay,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 100,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.viewFields
|
||||
.isFullDay.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === CALENDAR_EVENT_STANDARD_FIELD_IDS.location,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.viewFields
|
||||
.location.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
CALENDAR_EVENT_STANDARD_FIELD_IDS.conferenceLink,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.viewFields
|
||||
.conferenceLink.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === CALENDAR_EVENT_STANDARD_FIELD_IDS.isCanceled,
|
||||
)?.id ?? '',
|
||||
position: 6,
|
||||
isVisible: true,
|
||||
size: 100,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.viewFields
|
||||
.isCanceled.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
calendarEventObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 7,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.calendarEvent.views.allCalendarEvents.viewFields
|
||||
.createdAt.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-156
@@ -1,156 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { DEFAULT_VIEW_FIELD_SIZE } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/constants/DEFAULT_VIEW_FIELD_SIZE';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
COMPANY_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const companiesAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const companyObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.company,
|
||||
);
|
||||
|
||||
if (!companyObjectMetadata) {
|
||||
throw new Error('Company object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.company.views.allCompanies.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Companies',
|
||||
objectMetadataId: companyObjectMetadata.id ?? '',
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconList',
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
companyObjectMetadata.fields.find(
|
||||
(field) => field.standardId === COMPANY_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: DEFAULT_VIEW_FIELD_SIZE,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.company.views.allCompanies.viewFields.name
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
companyObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === COMPANY_STANDARD_FIELD_IDS.domainName,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 100,
|
||||
aggregateOperation: AggregateOperations.COUNT,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.company.views.allCompanies.viewFields.domainName
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
companyObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === COMPANY_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.company.views.allCompanies.viewFields.createdBy
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
companyObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === COMPANY_STANDARD_FIELD_IDS.accountOwner,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.company.views.allCompanies.viewFields.accountOwner
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
companyObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.company.views.allCompanies.viewFields.createdAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
companyObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === COMPANY_STANDARD_FIELD_IDS.employees,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
aggregateOperation: AggregateOperations.MAX,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.company.views.allCompanies.viewFields.employees
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
companyObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === COMPANY_STANDARD_FIELD_IDS.linkedinLink,
|
||||
)?.id ?? '',
|
||||
position: 6,
|
||||
isVisible: true,
|
||||
size: 170,
|
||||
aggregateOperation: AggregateOperations.PERCENTAGE_EMPTY,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.company.views.allCompanies.viewFields.linkedinLink
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
companyObjectMetadata.fields.find(
|
||||
(field) => field.standardId === COMPANY_STANDARD_FIELD_IDS.address,
|
||||
)?.id ?? '',
|
||||
position: 7,
|
||||
isVisible: true,
|
||||
size: 170,
|
||||
aggregateOperation: AggregateOperations.COUNT_NOT_EMPTY,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.company.views.allCompanies.viewFields.address
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-1
@@ -1 +0,0 @@
|
||||
export const DEFAULT_VIEW_FIELD_SIZE = 180;
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ViewOpenRecordInType } from 'src/engine/metadata-modules/view/types/view-open-record-in-type.type';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
DASHBOARD_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const dashboardsAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const dashboardObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.dashboard,
|
||||
);
|
||||
|
||||
if (!dashboardObjectMetadata) {
|
||||
throw new Error('Dashboard object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.dashboard.views.allDashboards.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Dashboards',
|
||||
objectMetadataId: dashboardObjectMetadata.id ?? '',
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconLayoutDashboard',
|
||||
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
dashboardObjectMetadata.fields.find(
|
||||
(field) => field.standardId === DASHBOARD_STANDARD_FIELD_IDS.title,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 200,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.dashboard.views.allDashboards.viewFields.title
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
dashboardObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === DASHBOARD_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.dashboard.views.allDashboards.viewFields.createdBy
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
dashboardObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.dashboard.views.allDashboards.viewFields.createdAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
dashboardObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.dashboard.views.allDashboards.viewFields.updatedAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-75
@@ -1,75 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { DEFAULT_VIEW_FIELD_SIZE } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/constants/DEFAULT_VIEW_FIELD_SIZE';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
MESSAGE_THREAD_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const messageThreadsAllView = ({
|
||||
objectMetadataItems,
|
||||
twentyStandardFlatApplication,
|
||||
useCoreNaming,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const messageThreadObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.messageThread,
|
||||
);
|
||||
|
||||
if (!messageThreadObjectMetadata) {
|
||||
throw new Error('MessageThread object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.messageThread.views.allMessageThreads.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Message Threads',
|
||||
objectMetadataId: messageThreadObjectMetadata.id ?? '',
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconList',
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageThreadObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === MESSAGE_THREAD_STANDARD_FIELD_IDS.messages,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: DEFAULT_VIEW_FIELD_SIZE,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.messageThread.views.allMessageThreads.viewFields
|
||||
.messages.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageThreadObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.messageThread.views.allMessageThreads.viewFields
|
||||
.createdAt.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-139
@@ -1,139 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { DEFAULT_VIEW_FIELD_SIZE } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/constants/DEFAULT_VIEW_FIELD_SIZE';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
MESSAGE_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const messagesAllView = ({
|
||||
objectMetadataItems,
|
||||
twentyStandardFlatApplication,
|
||||
useCoreNaming,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const messageObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.message,
|
||||
);
|
||||
|
||||
if (!messageObjectMetadata) {
|
||||
throw new Error('Message object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.message.views.allMessages.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Messages',
|
||||
objectMetadataId: messageObjectMetadata.id ?? '',
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconList',
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageObjectMetadata.fields.find(
|
||||
(field) => field.standardId === MESSAGE_STANDARD_FIELD_IDS.subject,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: DEFAULT_VIEW_FIELD_SIZE,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.message.views.allMessages.viewFields.subject
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === MESSAGE_STANDARD_FIELD_IDS.messageThread,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.message.views.allMessages.viewFields.messageThread
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
MESSAGE_STANDARD_FIELD_IDS.messageParticipants,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.message.views.allMessages.viewFields
|
||||
.messageParticipants.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === MESSAGE_STANDARD_FIELD_IDS.receivedAt,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.message.views.allMessages.viewFields.receivedAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === MESSAGE_STANDARD_FIELD_IDS.headerMessageId,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 180,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.message.views.allMessages.viewFields.headerMessageId
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageObjectMetadata.fields.find(
|
||||
(field) => field.standardId === MESSAGE_STANDARD_FIELD_IDS.text,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 200,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.message.views.allMessages.viewFields.text
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
messageObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 6,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.message.views.allMessages.viewFields.createdAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-119
@@ -1,119 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
NOTE_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const notesAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const noteObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.note,
|
||||
);
|
||||
|
||||
if (!noteObjectMetadata) {
|
||||
throw new Error('Note object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.note.views.allNotes.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Notes',
|
||||
objectMetadataId: noteObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconNotes',
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
noteObjectMetadata.fields.find(
|
||||
(field) => field.standardId === NOTE_STANDARD_FIELD_IDS.title,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.note.views.allNotes.viewFields.title
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
noteObjectMetadata.fields.find(
|
||||
(field) => field.standardId === NOTE_STANDARD_FIELD_IDS.noteTargets,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.note.views.allNotes.viewFields.noteTargets
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
noteObjectMetadata.fields.find(
|
||||
(field) => field.standardId === NOTE_STANDARD_FIELD_IDS.bodyV2,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.note.views.allNotes.viewFields.bodyV2
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
noteObjectMetadata.fields.find(
|
||||
(field) => field.standardId === NOTE_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.note.views.allNotes.viewFields.createdBy
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
noteObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.note.views.allNotes.viewFields.createdAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
/*
|
||||
TODO: Add later, since we don't have real-time it probably doesn't work well?
|
||||
{
|
||||
fieldMetadataId:
|
||||
objectMetadataMap[STANDARD_OBJECT_IDS.note].fields[.updatedAt
|
||||
],
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210},
|
||||
*/
|
||||
],
|
||||
};
|
||||
};
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import { OPPORTUNITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const opportunitiesAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const opportunityObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.opportunity,
|
||||
);
|
||||
|
||||
if (!opportunityObjectMetadata) {
|
||||
throw new Error('Opportunity object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.opportunity.views.allOpportunities.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Opportunities',
|
||||
objectMetadataId: opportunityObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconList',
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) => field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.allOpportunities.viewFields.name
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.amount,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
aggregateOperation: AggregateOperations.AVG,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.allOpportunities.viewFields.amount
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.allOpportunities.viewFields
|
||||
.createdBy.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.closeDate,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
aggregateOperation: AggregateOperations.MIN,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.allOpportunities.viewFields
|
||||
.closeDate.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.company,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.allOpportunities.viewFields.company
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
OPPORTUNITY_STANDARD_FIELD_IDS.pointOfContact,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.allOpportunities.viewFields
|
||||
.pointOfContact.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-202
@@ -1,202 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import { OPPORTUNITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const opportunitiesByStageView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const opportunityObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.opportunity,
|
||||
);
|
||||
|
||||
if (!opportunityObjectMetadata) {
|
||||
throw new Error('Opportunity object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.universalIdentifier;
|
||||
|
||||
const stageFieldMetadataId =
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) => field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.stage,
|
||||
)?.id ?? '';
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`By Stage` : 'By Stage',
|
||||
objectMetadataId: opportunityObjectMetadata.id,
|
||||
type: 'kanban',
|
||||
key: null,
|
||||
position: 2,
|
||||
icon: 'IconLayoutKanban',
|
||||
kanbanAggregateOperation: AggregateOperations.SUM,
|
||||
kanbanAggregateOperationFieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) => field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.amount,
|
||||
)?.id ?? '',
|
||||
filters: [],
|
||||
mainGroupByFieldMetadataId: stageFieldMetadataId,
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) => field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewFields.name
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.amount,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewFields.amount
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewFields.createdBy
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.closeDate,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewFields.closeDate
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.company,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewFields.company
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
OPPORTUNITY_STANDARD_FIELD_IDS.pointOfContact,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewFields.pointOfContact
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
groups: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.stage,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'NEW',
|
||||
position: 0,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewGroups!.new
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.stage,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'SCREENING',
|
||||
position: 1,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewGroups!.screening
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.stage,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'MEETING',
|
||||
position: 2,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewGroups!.meeting
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.stage,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'PROPOSAL',
|
||||
position: 3,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewGroups!.proposal
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
opportunityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === OPPORTUNITY_STANDARD_FIELD_IDS.stage,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'CUSTOMER',
|
||||
position: 4,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.opportunity.views.byStage.viewGroups!.customer
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-174
@@ -1,174 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { AggregateOperations } from 'src/engine/api/graphql/graphql-query-runner/constants/aggregate-operations.constant';
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
PERSON_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const peopleAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const personObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.person,
|
||||
);
|
||||
|
||||
if (!personObjectMetadata) {
|
||||
throw new Error('Person object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.person.views.allPeople.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All People',
|
||||
objectMetadataId: personObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconList',
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) => field.standardId === PERSON_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.name
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) => field.standardId === PERSON_STANDARD_FIELD_IDS.emails,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
aggregateOperation: AggregateOperations.COUNT_UNIQUE_VALUES,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.emails
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) => field.standardId === PERSON_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.createdBy
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) => field.standardId === PERSON_STANDARD_FIELD_IDS.company,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.company
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) => field.standardId === PERSON_STANDARD_FIELD_IDS.phones,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
aggregateOperation: AggregateOperations.PERCENTAGE_EMPTY,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.phones
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
aggregateOperation: AggregateOperations.MIN,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.createdAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) => field.standardId === PERSON_STANDARD_FIELD_IDS.city,
|
||||
)?.id ?? '',
|
||||
position: 6,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.city
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) => field.standardId === PERSON_STANDARD_FIELD_IDS.jobTitle,
|
||||
)?.id ?? '',
|
||||
position: 7,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.jobTitle
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === PERSON_STANDARD_FIELD_IDS.linkedinLink,
|
||||
)?.id ?? '',
|
||||
position: 8,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.linkedinLink
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
personObjectMetadata.fields.find(
|
||||
(field) => field.standardId === PERSON_STANDARD_FIELD_IDS.xLink,
|
||||
)?.id ?? '',
|
||||
position: 9,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.person.views.allPeople.viewFields.xLink
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-164
@@ -1,164 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
TASK_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const tasksAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const taskObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.task,
|
||||
);
|
||||
|
||||
if (!taskObjectMetadata) {
|
||||
throw new Error('Task object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.task.views.allTasks.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Tasks',
|
||||
objectMetadataId: taskObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconList',
|
||||
filters: [] /* [
|
||||
{
|
||||
fieldMetadataId:
|
||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
||||
TASK_STANDARD_FIELD_IDS.type
|
||||
],
|
||||
displayValue: 'Task',
|
||||
operand: 'is',
|
||||
value: '["TASK"]'},
|
||||
],*/,
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.title,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.allTasks.viewFields.title
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.allTasks.viewFields.status
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.taskTargets,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.allTasks.viewFields.taskTargets
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.allTasks.viewFields.createdBy
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.dueAt,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.allTasks.viewFields.dueAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.assignee,
|
||||
)?.id ?? '',
|
||||
position: 6,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.allTasks.viewFields.assignee
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.bodyV2,
|
||||
)?.id ?? '',
|
||||
position: 7,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.allTasks.viewFields.bodyV2
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 8,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.allTasks.viewFields.createdAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
/*
|
||||
TODO: Add later, since we don't have real-time it probably doesn't work well?
|
||||
{
|
||||
fieldMetadataId:
|
||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[.updatedAt
|
||||
],
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210},
|
||||
*/
|
||||
],
|
||||
};
|
||||
};
|
||||
-212
@@ -1,212 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { ViewFilterOperand } from 'twenty-shared/types';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
TASK_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const tasksAssignedToMeView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const taskObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.task,
|
||||
);
|
||||
|
||||
if (!taskObjectMetadata) {
|
||||
throw new Error('Task object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`Assigned to Me` : 'Assigned to Me',
|
||||
objectMetadataId: taskObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: null,
|
||||
position: 2,
|
||||
icon: 'IconUserCircle',
|
||||
mainGroupByFieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
filters: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.assignee,
|
||||
)?.id ?? '',
|
||||
displayValue: 'Me',
|
||||
operand: ViewFilterOperand.IS,
|
||||
value: JSON.stringify({
|
||||
isCurrentWorkspaceMemberSelected: true,
|
||||
selectedRecordIds: [],
|
||||
}),
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewFilters!.assigneeIsMe
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.title,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewFields.title
|
||||
.universalIdentifier,
|
||||
},
|
||||
/*{
|
||||
fieldMetadataId:
|
||||
objectMetadataStandardIdToIdMap[STANDARD_OBJECT_IDS.task].fields[
|
||||
TASK_STANDARD_FIELD_IDS.status
|
||||
],
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150},*/
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.taskTargets,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewFields.taskTargets
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewFields.createdBy
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.dueAt,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewFields.dueAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.assignee,
|
||||
)?.id ?? '',
|
||||
position: 6,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewFields.assignee
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.bodyV2,
|
||||
)?.id ?? '',
|
||||
position: 7,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewFields.bodyV2
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 8,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewFields.createdAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
groups: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'TODO',
|
||||
position: 0,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewGroups!.todo
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'IN_PROGRESS',
|
||||
position: 1,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewGroups!.inProgress
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'DONE',
|
||||
position: 2,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewGroups!.done
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: '',
|
||||
position: 3,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.assignedToMe.viewGroups!.empty
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-170
@@ -1,170 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
TASK_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const tasksByStatusView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const taskObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.task,
|
||||
);
|
||||
|
||||
if (!taskObjectMetadata) {
|
||||
throw new Error('Task object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.task.views.byStatus.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`By Status` : 'By Status',
|
||||
objectMetadataId: taskObjectMetadata.id,
|
||||
type: 'kanban',
|
||||
key: null,
|
||||
position: 1,
|
||||
icon: 'IconLayoutKanban',
|
||||
mainGroupByFieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
filters: [] /* [
|
||||
{
|
||||
fieldMetadataId:
|
||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[
|
||||
TASK_STANDARD_FIELD_IDS.type
|
||||
],
|
||||
displayValue: 'Task',
|
||||
operand: 'is',
|
||||
value: '["TASK"]'},
|
||||
],*/,
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.title,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.byStatus.viewFields.title
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.byStatus.viewFields.status
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.dueAt,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.byStatus.viewFields.dueAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.assignee,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.byStatus.viewFields.assignee
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 6,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.byStatus.viewFields.createdAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
/*
|
||||
TODO: Add later, since we don't have real-time it probably doesn't work well?
|
||||
{
|
||||
fieldMetadataId:
|
||||
objectMetadataMap[STANDARD_OBJECT_IDS.task].fields[.updatedAt
|
||||
],
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210},
|
||||
*/
|
||||
],
|
||||
groups: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'TODO',
|
||||
position: 0,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.byStatus.viewGroups!.todo
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'IN_PROGRESS',
|
||||
position: 1,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.byStatus.viewGroups!.inProgress
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
taskObjectMetadata.fields.find(
|
||||
(field) => field.standardId === TASK_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
isVisible: true,
|
||||
fieldValue: 'DONE',
|
||||
position: 2,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.task.views.byStatus.viewGroups!.done
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-120
@@ -1,120 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ViewOpenRecordInType } from 'src/engine/metadata-modules/view/types/view-open-record-in-type.type';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { DEFAULT_VIEW_FIELD_SIZE } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/constants/DEFAULT_VIEW_FIELD_SIZE';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import { TIMELINE_ACTIVITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const timelineActivitiesAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const timelineActivityObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.timelineActivity,
|
||||
);
|
||||
|
||||
if (!timelineActivityObjectMetadata) {
|
||||
throw new Error('TimelineActivity object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.timelineActivity.views.allTimelineActivities
|
||||
.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming
|
||||
? msg`All {objectLabelPlural}`
|
||||
: 'All Timeline Activities',
|
||||
objectMetadataId: timelineActivityObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconList',
|
||||
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
timelineActivityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: DEFAULT_VIEW_FIELD_SIZE,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.timelineActivity.views.allTimelineActivities
|
||||
.viewFields.name.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
timelineActivityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.happensAt,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.timelineActivity.views.allTimelineActivities
|
||||
.viewFields.happensAt.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
timelineActivityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.properties,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 200,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.timelineActivity.views.allTimelineActivities
|
||||
.viewFields.properties.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
timelineActivityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.workspaceMember,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.timelineActivity.views.allTimelineActivities
|
||||
.viewFields.workspaceMember.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
timelineActivityObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
TIMELINE_ACTIVITY_STANDARD_FIELD_IDS.linkedRecordCachedName,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 200,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.timelineActivity.views.allTimelineActivities
|
||||
.viewFields.linkedRecordCachedName.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ViewOpenRecordInType } from 'src/engine/metadata-modules/view/types/view-open-record-in-type.type';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import { WORKFLOW_RUN_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const workflowRunsAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const workflowRunObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.workflowRun,
|
||||
);
|
||||
|
||||
if (!workflowRunObjectMetadata) {
|
||||
throw new Error('Workflow run object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.workflowRun.views.allWorkflowRuns.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Workflow Runs',
|
||||
objectMetadataId: workflowRunObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconHistoryToggle',
|
||||
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowRunObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_RUN_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowRun.views.allWorkflowRuns.viewFields.name
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowRunObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_RUN_STANDARD_FIELD_IDS.workflow,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowRun.views.allWorkflowRuns.viewFields.workflow
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowRunObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_RUN_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowRun.views.allWorkflowRuns.viewFields.status
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowRunObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_RUN_STANDARD_FIELD_IDS.startedAt,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowRun.views.allWorkflowRuns.viewFields
|
||||
.startedAt.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowRunObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_RUN_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowRun.views.allWorkflowRuns.viewFields
|
||||
.createdBy.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowRunObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
WORKFLOW_RUN_STANDARD_FIELD_IDS.workflowVersion,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowRun.views.allWorkflowRuns.viewFields
|
||||
.workflowVersion.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ViewOpenRecordInType } from 'src/engine/metadata-modules/view/types/view-open-record-in-type.type';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
WORKFLOW_VERSION_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const workflowVersionsAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const workflowVersionObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.workflowVersion,
|
||||
);
|
||||
|
||||
if (!workflowVersionObjectMetadata) {
|
||||
throw new Error('Workflow version object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.workflowVersion.views.allWorkflowVersions
|
||||
.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming
|
||||
? msg`All {objectLabelPlural}`
|
||||
: 'All Workflow Versions',
|
||||
objectMetadataId: workflowVersionObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconVersions',
|
||||
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowVersionObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_VERSION_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 210,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowVersion.views.allWorkflowVersions.viewFields
|
||||
.name.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowVersionObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_VERSION_STANDARD_FIELD_IDS.workflow,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowVersion.views.allWorkflowVersions.viewFields
|
||||
.workflow.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowVersionObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_VERSION_STANDARD_FIELD_IDS.status,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowVersion.views.allWorkflowVersions.viewFields
|
||||
.status.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowVersionObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowVersion.views.allWorkflowVersions.viewFields
|
||||
.updatedAt.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowVersionObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_VERSION_STANDARD_FIELD_IDS.runs,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: false,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflowVersion.views.allWorkflowVersions.viewFields
|
||||
.runs.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-126
@@ -1,126 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { ViewOpenRecordInType } from 'src/engine/metadata-modules/view/types/view-open-record-in-type.type';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
WORKFLOW_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const workflowsAllView = ({
|
||||
objectMetadataItems,
|
||||
useCoreNaming = false,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const workflowObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.workflow,
|
||||
);
|
||||
|
||||
if (!workflowObjectMetadata) {
|
||||
throw new Error('Workflow object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.workflow.views.allWorkflows.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming ? msg`All {objectLabelPlural}` : 'All Workflows',
|
||||
objectMetadataId: workflowObjectMetadata.id,
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconSettingsAutomation',
|
||||
openRecordIn: ViewOpenRecordInType.RECORD_PAGE,
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowObjectMetadata.fields.find(
|
||||
(field) => field.standardId === WORKFLOW_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflow.views.allWorkflows.viewFields.name
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_STANDARD_FIELD_IDS.statuses,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflow.views.allWorkflows.viewFields.statuses
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.updatedAt,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflow.views.allWorkflows.viewFields.updatedAt
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_STANDARD_FIELD_IDS.createdBy,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflow.views.allWorkflows.viewFields.createdBy
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKFLOW_STANDARD_FIELD_IDS.versions,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflow.views.allWorkflows.viewFields.versions
|
||||
.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workflowObjectMetadata.fields.find(
|
||||
(field) => field.standardId === WORKFLOW_STANDARD_FIELD_IDS.runs,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: false,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workflow.views.allWorkflows.viewFields.runs
|
||||
.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
-174
@@ -1,174 +0,0 @@
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { STANDARD_OBJECT_IDS } from 'twenty-shared/metadata';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { type FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type ViewDefinition } from 'src/engine/workspace-manager/standard-objects-prefill-data/types/view-definition.interface';
|
||||
import { DEFAULT_VIEW_FIELD_SIZE } from 'src/engine/workspace-manager/standard-objects-prefill-data/views/constants/DEFAULT_VIEW_FIELD_SIZE';
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import {
|
||||
BASE_OBJECT_STANDARD_FIELD_IDS,
|
||||
WORKSPACE_MEMBER_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
|
||||
export const workspaceMembersAllView = ({
|
||||
objectMetadataItems,
|
||||
twentyStandardFlatApplication,
|
||||
useCoreNaming,
|
||||
}: {
|
||||
objectMetadataItems: ObjectMetadataEntity[];
|
||||
useCoreNaming?: boolean;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}): ViewDefinition => {
|
||||
const workspaceMemberObjectMetadata = objectMetadataItems.find(
|
||||
(object) => object.standardId === STANDARD_OBJECT_IDS.workspaceMember,
|
||||
);
|
||||
|
||||
if (!workspaceMemberObjectMetadata) {
|
||||
throw new Error('WorkspaceMember object metadata not found');
|
||||
}
|
||||
|
||||
const viewUniversalIdentifier =
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers
|
||||
.universalIdentifier;
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: viewUniversalIdentifier,
|
||||
applicationId: twentyStandardFlatApplication.id,
|
||||
name: useCoreNaming
|
||||
? msg`All {objectLabelPlural}`
|
||||
: 'All Workspace Members',
|
||||
objectMetadataId: workspaceMemberObjectMetadata.id ?? '',
|
||||
type: 'table',
|
||||
key: 'INDEX',
|
||||
position: 0,
|
||||
icon: 'IconList',
|
||||
filters: [],
|
||||
fields: [
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKSPACE_MEMBER_STANDARD_FIELD_IDS.name,
|
||||
)?.id ?? '',
|
||||
position: 0,
|
||||
isVisible: true,
|
||||
size: DEFAULT_VIEW_FIELD_SIZE,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.name.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
WORKSPACE_MEMBER_STANDARD_FIELD_IDS.userEmail,
|
||||
)?.id ?? '',
|
||||
position: 1,
|
||||
isVisible: true,
|
||||
size: 180,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.userEmail.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
WORKSPACE_MEMBER_STANDARD_FIELD_IDS.avatarUrl,
|
||||
)?.id ?? '',
|
||||
position: 2,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.avatarUrl.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
WORKSPACE_MEMBER_STANDARD_FIELD_IDS.colorScheme,
|
||||
)?.id ?? '',
|
||||
position: 3,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.colorScheme.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKSPACE_MEMBER_STANDARD_FIELD_IDS.locale,
|
||||
)?.id ?? '',
|
||||
position: 4,
|
||||
isVisible: true,
|
||||
size: 120,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.locale.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === WORKSPACE_MEMBER_STANDARD_FIELD_IDS.timeZone,
|
||||
)?.id ?? '',
|
||||
position: 5,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.timeZone.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
WORKSPACE_MEMBER_STANDARD_FIELD_IDS.dateFormat,
|
||||
)?.id ?? '',
|
||||
position: 6,
|
||||
isVisible: true,
|
||||
size: 120,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.dateFormat.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId ===
|
||||
WORKSPACE_MEMBER_STANDARD_FIELD_IDS.timeFormat,
|
||||
)?.id ?? '',
|
||||
position: 7,
|
||||
isVisible: true,
|
||||
size: 120,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.timeFormat.universalIdentifier,
|
||||
},
|
||||
{
|
||||
fieldMetadataId:
|
||||
workspaceMemberObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.standardId === BASE_OBJECT_STANDARD_FIELD_IDS.createdAt,
|
||||
)?.id ?? '',
|
||||
position: 8,
|
||||
isVisible: true,
|
||||
size: 150,
|
||||
universalIdentifier:
|
||||
STANDARD_OBJECTS.workspaceMember.views.allWorkspaceMembers.viewFields
|
||||
.createdAt.universalIdentifier,
|
||||
},
|
||||
],
|
||||
};
|
||||
};
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { HELPER_AGENT } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-agents/agents/helper-agent';
|
||||
import { HELPER_AGENT } from 'src/engine/workspace-manager/workspace-migration/constant/standard-agent-ids';
|
||||
|
||||
export const STANDARD_AGENT = {
|
||||
helper: {
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import {
|
||||
WORKFLOW_STANDARD_FIELD_IDS,
|
||||
WORKFLOW_VERSION_STANDARD_FIELD_IDS,
|
||||
WORKSPACE_MEMBER_STANDARD_FIELD_IDS,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
} from 'src/engine/workspace-manager/workspace-migration/constant/standard-field-ids';
|
||||
|
||||
export const STANDARD_OBJECTS = {
|
||||
attachment: {
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
import { ADMIN_ROLE } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/admin-role';
|
||||
import { ADMIN_ROLE } from 'src/engine/metadata-modules/role/constants/admin-role';
|
||||
|
||||
export const STANDARD_ROLE = {
|
||||
admin: { universalIdentifier: ADMIN_ROLE.standardId },
|
||||
|
||||
+4
-4
@@ -14,9 +14,9 @@ import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/works
|
||||
import { STANDARD_OBJECTS } from 'src/engine/workspace-manager/twenty-standard-application/constants/standard-object.constant';
|
||||
import { TWENTY_STANDARD_ALL_METADATA_NAME } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-all-metadata-name.constant';
|
||||
import { computeTwentyStandardApplicationAllFlatEntityMaps } from 'src/engine/workspace-manager/twenty-standard-application/utils/twenty-standard-application-all-flat-entity-maps.constant';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
||||
import { FromToAllFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
import { FromToAllFlatEntityMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
import { FavoriteWorkspaceEntity } from 'src/modules/favorite/standard-objects/favorite.workspace-entity';
|
||||
|
||||
@Injectable()
|
||||
@@ -117,7 +117,7 @@ export class TwentyStandardApplicationService {
|
||||
);
|
||||
|
||||
if (isDefined(validateAndBuildResult)) {
|
||||
throw new WorkspaceMigrationBuilderExceptionV2(
|
||||
throw new WorkspaceMigrationBuilderException(
|
||||
validateAndBuildResult,
|
||||
'Multiple validation errors occurred while synchronizing twenty-standard application',
|
||||
);
|
||||
|
||||
+3
-3
@@ -1,9 +1,9 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { ApplicationModule } from 'src/engine/core-modules/application/application.module';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module';
|
||||
import { GlobalWorkspaceDataSourceModule } from 'src/engine/twenty-orm/global-workspace-datasource/global-workspace-datasource.module';
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
import { TwentyStandardApplicationService } from './services/twenty-standard-application.service';
|
||||
|
||||
@@ -12,7 +12,7 @@ import { TwentyStandardApplicationService } from './services/twenty-standard-app
|
||||
imports: [
|
||||
ApplicationModule,
|
||||
WorkspaceCacheModule,
|
||||
WorkspaceMigrationV2Module,
|
||||
WorkspaceMigrationModule,
|
||||
GlobalWorkspaceDataSourceModule,
|
||||
],
|
||||
exports: [TwentyStandardApplicationService],
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_COMPANY } from 'src/modules/company/standard-objects/company.workspace-entity';
|
||||
|
||||
export const buildCompanyStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_DASHBOARD } from 'src/modules/dashboard/standard-objects/dashboard.workspace-entity';
|
||||
|
||||
export const buildDashboardStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_NOTES } from 'src/modules/note/standard-objects/note.workspace-entity';
|
||||
|
||||
export const buildNoteStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_OPPORTUNITY } from 'src/modules/opportunity/standard-objects/opportunity.workspace-entity';
|
||||
|
||||
export const buildOpportunityStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_PERSON } from 'src/modules/person/standard-objects/person.workspace-entity';
|
||||
|
||||
export const buildPersonStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_TASKS } from 'src/modules/task/standard-objects/task.workspace-entity';
|
||||
|
||||
export const buildTaskStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
type CreateStandardFieldArgs,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { TIMELINE_ACTIVITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-sync-metadata/constants/standard-field-ids';
|
||||
import { TIMELINE_ACTIVITY_STANDARD_FIELD_IDS } from 'src/engine/workspace-manager/workspace-migration/constant/standard-field-ids';
|
||||
|
||||
export const buildTimelineActivityStandardFlatFieldMetadatas = ({
|
||||
now,
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_WORKFLOW_RUNS } from 'src/modules/workflow/common/standard-objects/workflow-run.workspace-entity';
|
||||
|
||||
export const buildWorkflowRunStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_WORKFLOWS } from 'src/modules/workflow/common/standard-objects/workflow.workspace-entity';
|
||||
|
||||
export const buildWorkflowStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import { SEARCH_FIELDS_FOR_WORKFLOW_VERSIONS } from 'src/modules/workflow/common/standard-objects/workflow-version.workspace-entity';
|
||||
|
||||
export const buildWorkflowVersionStandardFlatFieldMetadatas = ({
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ import {
|
||||
createStandardFieldFlatMetadata,
|
||||
} from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-field-flat-metadata.util';
|
||||
import { createStandardRelationFieldFlatMetadata } from 'src/engine/workspace-manager/twenty-standard-application/utils/field-metadata/create-standard-relation-field-flat-metadata.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
import { getTsVectorColumnExpressionFromFields } from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
import {
|
||||
SEARCH_FIELDS_FOR_WORKSPACE_MEMBER,
|
||||
WorkspaceMemberNumberFormatEnum,
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
import { Column, Index, JoinColumn, ManyToOne, type Relation } from 'typeorm';
|
||||
|
||||
import type { ApplicationEntity } from 'src/engine/core-modules/application/application.entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/workspace-sync/types/workspace-related-entity';
|
||||
import { WorkspaceRelatedEntity } from 'src/engine/workspace-manager/types/workspace-related-entity';
|
||||
|
||||
@Index(['workspaceId', 'universalIdentifier'], {
|
||||
unique: true,
|
||||
+1
-1
@@ -3,7 +3,7 @@ import { FieldMetadataType } from 'twenty-shared/types';
|
||||
import {
|
||||
type FieldTypeAndNameMetadata,
|
||||
getTsVectorColumnExpressionFromFields,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/get-ts-vector-column-expression.util';
|
||||
} from 'src/engine/workspace-manager/utils/get-ts-vector-column-expression.util';
|
||||
|
||||
const nameTextField = { name: 'name', type: FieldMetadataType.TEXT };
|
||||
const nameFullNameField = {
|
||||
+3
-8
@@ -8,15 +8,11 @@ import {
|
||||
computeCompositeColumnName,
|
||||
} from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
|
||||
import {
|
||||
WorkspaceMigrationException,
|
||||
WorkspaceMigrationExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.exception';
|
||||
import {
|
||||
isSearchableFieldType,
|
||||
type SearchableFieldType,
|
||||
} from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-searchable-field.util';
|
||||
import { isSearchableSubfield } from 'src/engine/workspace-manager/workspace-sync-metadata/utils/is-searchable-subfield.util';
|
||||
} from 'src/engine/workspace-manager/utils/is-searchable-field.util';
|
||||
import { isSearchableSubfield } from 'src/engine/workspace-manager/utils/is-searchable-subfield.util';
|
||||
|
||||
export type FieldTypeAndNameMetadata = {
|
||||
name: string;
|
||||
@@ -51,9 +47,8 @@ const getColumnExpressionsFromField = (
|
||||
);
|
||||
|
||||
if (!compositeType) {
|
||||
throw new WorkspaceMigrationException(
|
||||
throw new Error(
|
||||
`Composite type not found for field metadata type: ${fieldMetadataTypeAndName.type}`,
|
||||
WorkspaceMigrationExceptionCode.INVALID_FIELD_METADATA,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -10,18 +10,16 @@ import { DataSourceModule } from 'src/engine/metadata-modules/data-source/data-s
|
||||
import { FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheModule } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.module';
|
||||
import { ObjectMetadataModule } from 'src/engine/metadata-modules/object-metadata/object-metadata.module';
|
||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
import { PermissionsModule } from 'src/engine/metadata-modules/permissions/permissions.module';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RoleModule } from 'src/engine/metadata-modules/role/role.module';
|
||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
import { UserRoleModule } from 'src/engine/metadata-modules/user-role/user-role.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { DevSeederModule } from 'src/engine/workspace-manager/dev-seeder/dev-seeder.module';
|
||||
import { WorkspaceMigrationV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-v2.module';
|
||||
import { WorkspaceSyncMetadataModule } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.module';
|
||||
import { TwentyStandardApplicationModule } from 'src/engine/workspace-manager/twenty-standard-application/twenty-standard-application.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
|
||||
import { WorkspaceManagerService } from './workspace-manager.service';
|
||||
|
||||
@@ -29,11 +27,9 @@ import { WorkspaceManagerService } from './workspace-manager.service';
|
||||
imports: [
|
||||
WorkspaceDataSourceModule,
|
||||
WorkspaceMigrationModule,
|
||||
WorkspaceMigrationV2Module,
|
||||
ObjectMetadataModule,
|
||||
DevSeederModule,
|
||||
DataSourceModule,
|
||||
WorkspaceSyncMetadataModule,
|
||||
FeatureFlagModule,
|
||||
PermissionsModule,
|
||||
AiAgentModule,
|
||||
|
||||
@@ -5,30 +5,22 @@ import { DataSource, Repository } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { FlatApplication } from 'src/engine/core-modules/application/types/flat-application.type';
|
||||
import { fromApplicationEntityToFlatApplication } from 'src/engine/core-modules/application/utils/from-application-entity-to-flat-application.util';
|
||||
import { FeatureFlagKey } from 'src/engine/core-modules/feature-flag/enums/feature-flag-key.enum';
|
||||
import { FeatureFlagService } from 'src/engine/core-modules/feature-flag/services/feature-flag.service';
|
||||
import { UserWorkspaceEntity } from 'src/engine/core-modules/user-workspace/user-workspace.entity';
|
||||
import { WorkspaceEntity } from 'src/engine/core-modules/workspace/workspace.entity';
|
||||
import { type DataSourceEntity } from 'src/engine/metadata-modules/data-source/data-source.entity';
|
||||
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { ObjectMetadataService } from 'src/engine/metadata-modules/object-metadata/object-metadata.service';
|
||||
import { RoleTargetEntity } from 'src/engine/metadata-modules/role-target/role-target.entity';
|
||||
import { ADMIN_ROLE } from 'src/engine/metadata-modules/role/constants/admin-role';
|
||||
import { RoleEntity } from 'src/engine/metadata-modules/role/role.entity';
|
||||
import { RoleService } from 'src/engine/metadata-modules/role/role.service';
|
||||
import { ServerlessFunctionEntity } from 'src/engine/metadata-modules/serverless-function/serverless-function.entity';
|
||||
import { UserRoleService } from 'src/engine/metadata-modules/user-role/user-role.service';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { prefillCompanies } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-companies';
|
||||
import { prefillCoreViews } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-core-views';
|
||||
import { prefillPeople } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-people';
|
||||
import { prefillWorkflows } from 'src/engine/workspace-manager/standard-objects-prefill-data/prefill-workflows';
|
||||
import { standardObjectsPrefillData } from 'src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill-data';
|
||||
import { TwentyStandardApplicationService } from 'src/engine/workspace-manager/twenty-standard-application/services/twenty-standard-application.service';
|
||||
import { ADMIN_ROLE } from 'src/engine/workspace-manager/workspace-sync-metadata/standard-roles/roles/admin-role';
|
||||
import { WorkspaceSyncMetadataService } from 'src/engine/workspace-manager/workspace-sync-metadata/workspace-sync-metadata.service';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceManagerService {
|
||||
@@ -38,7 +30,6 @@ export class WorkspaceManagerService {
|
||||
@InjectDataSource()
|
||||
private readonly coreDataSource: DataSource,
|
||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
||||
private readonly objectMetadataService: ObjectMetadataService,
|
||||
private readonly dataSourceService: DataSourceService,
|
||||
@InjectRepository(UserWorkspaceEntity)
|
||||
@@ -56,8 +47,6 @@ export class WorkspaceManagerService {
|
||||
private readonly serverlessFunctionRepository: Repository<ServerlessFunctionEntity>,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly featureFlagService: FeatureFlagService,
|
||||
private readonly workspaceSyncMetadataService: WorkspaceSyncMetadataService,
|
||||
) {}
|
||||
|
||||
public async init({
|
||||
@@ -81,58 +70,26 @@ export class WorkspaceManagerService {
|
||||
);
|
||||
|
||||
const dataSourceMetadataCreationStart = performance.now();
|
||||
const dataSourceMetadata =
|
||||
await this.dataSourceService.createDataSourceMetadata(
|
||||
|
||||
await this.dataSourceService.createDataSourceMetadata(
|
||||
workspaceId,
|
||||
schemaName,
|
||||
);
|
||||
|
||||
await this.applicationService.createTwentyStandardApplication({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.twentyStandardApplicationService.synchronizeTwentyStandardApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
schemaName,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
const featureFlags =
|
||||
await this.featureFlagService.getWorkspaceFeatureFlagsMap(workspaceId);
|
||||
|
||||
const twentyStandardApplication =
|
||||
await this.applicationService.createTwentyStandardApplication({
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
const isV2SyncEnabled =
|
||||
featureFlags[FeatureFlagKey.IS_WORKSPACE_CREATION_V2_ENABLED];
|
||||
|
||||
if (isV2SyncEnabled) {
|
||||
await this.twentyStandardApplicationService.synchronizeTwentyStandardApplicationOrThrow(
|
||||
{
|
||||
workspaceId,
|
||||
},
|
||||
);
|
||||
|
||||
await this.prefillCreatedWorkspaceRecords({
|
||||
workspaceId,
|
||||
schemaName,
|
||||
});
|
||||
} else {
|
||||
await this.workspaceSyncMetadataService.synchronize({
|
||||
workspaceId,
|
||||
dataSourceId: dataSourceMetadata.id,
|
||||
featureFlags,
|
||||
});
|
||||
|
||||
const prefillStandardObjectsStart = performance.now();
|
||||
|
||||
await this.prefillWorkspaceWithStandardObjectsRecords({
|
||||
dataSourceMetadata,
|
||||
workspaceId,
|
||||
featureFlags,
|
||||
twentyStandardFlatApplication: fromApplicationEntityToFlatApplication(
|
||||
twentyStandardApplication,
|
||||
),
|
||||
});
|
||||
|
||||
const prefillStandardObjectsEnd = performance.now();
|
||||
|
||||
this.logger.log(
|
||||
`Prefill standard objects took ${prefillStandardObjectsEnd - prefillStandardObjectsStart}ms`,
|
||||
);
|
||||
}
|
||||
await this.prefillCreatedWorkspaceRecords({
|
||||
workspaceId,
|
||||
schemaName,
|
||||
});
|
||||
|
||||
const dataSourceMetadataCreationEnd = performance.now();
|
||||
|
||||
@@ -204,43 +161,6 @@ export class WorkspaceManagerService {
|
||||
}
|
||||
}
|
||||
|
||||
private async prefillWorkspaceWithStandardObjectsRecords({
|
||||
dataSourceMetadata,
|
||||
workspaceId,
|
||||
featureFlags,
|
||||
twentyStandardFlatApplication,
|
||||
}: {
|
||||
dataSourceMetadata: DataSourceEntity;
|
||||
workspaceId: string;
|
||||
featureFlags: Record<string, boolean>;
|
||||
twentyStandardFlatApplication: FlatApplication;
|
||||
}) {
|
||||
const { flatObjectMetadataMaps, flatFieldMetadataMaps } =
|
||||
await this.flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps(
|
||||
{
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatObjectMetadataMaps', 'flatFieldMetadataMaps'],
|
||||
},
|
||||
);
|
||||
|
||||
await standardObjectsPrefillData(
|
||||
this.coreDataSource,
|
||||
dataSourceMetadata.schema,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
);
|
||||
|
||||
await prefillCoreViews({
|
||||
twentyStandardFlatApplication,
|
||||
coreDataSource: this.coreDataSource,
|
||||
workspaceId,
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
workspaceSchemaName: dataSourceMetadata.schema,
|
||||
featureFlags,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Should be removed once AddWorkspaceForeignKeysMigrationCommand has been run successfully in production
|
||||
* As we will be able to rely on foreignKey delete cascading
|
||||
@@ -261,7 +181,6 @@ export class WorkspaceManagerService {
|
||||
workspaceId,
|
||||
});
|
||||
|
||||
await this.workspaceMigrationService.deleteAllWithinWorkspace(workspaceId);
|
||||
await this.dataSourceService.delete(workspaceId);
|
||||
}
|
||||
|
||||
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
import { WorkspaceMigrationIndexFactory } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-index.factory';
|
||||
|
||||
import { WorkspaceMigrationFieldRelationFactory } from './workspace-migration-field-relation.factory';
|
||||
import { WorkspaceMigrationFieldFactory } from './workspace-migration-field.factory';
|
||||
import { WorkspaceMigrationObjectFactory } from './workspace-migration-object.factory';
|
||||
|
||||
export const workspaceMigrationBuilderFactories = [
|
||||
WorkspaceMigrationObjectFactory,
|
||||
WorkspaceMigrationFieldFactory,
|
||||
WorkspaceMigrationFieldRelationFactory,
|
||||
WorkspaceMigrationIndexFactory,
|
||||
];
|
||||
-91
@@ -1,91 +0,0 @@
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
|
||||
import { type IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { createIndexMigration } from 'src/engine/workspace-manager/workspace-migration-builder/factories/utils/workspace-migration-index.factory.utils';
|
||||
import { getMockFieldMetadataEntity } from 'src/utils/__test__/get-field-metadata-entity.mock';
|
||||
|
||||
describe('WorkspaceMigrationIndexFactory', () => {
|
||||
it('should create index migrations for simple fields', async () => {
|
||||
const simpleField = getMockFieldMetadataEntity({
|
||||
workspaceId: '20202020-0000-0000-0000-000000000000',
|
||||
objectMetadataId: '20202020-0000-0000-0000-000000000001',
|
||||
id: 'f1',
|
||||
type: FieldMetadataType.TEXT,
|
||||
name: 'simpleField',
|
||||
label: 'Simple Field',
|
||||
isNullable: true,
|
||||
isLabelSyncedWithName: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
});
|
||||
|
||||
const objectMetadata = {
|
||||
id: '20202020-0000-0000-0000-000000000002',
|
||||
workspaceId: '20202020-0000-0000-0000-000000000000',
|
||||
nameSingular: 'Test',
|
||||
fields: [simpleField],
|
||||
isCustom: false,
|
||||
};
|
||||
const indexMetadata = {
|
||||
name: 'idx_simple',
|
||||
isUnique: true,
|
||||
indexType: 'BTREE',
|
||||
indexWhereClause: null,
|
||||
indexFieldMetadatas: [{ fieldMetadataId: 'f1', order: 0 }],
|
||||
} as IndexMetadataEntity;
|
||||
const map = new Map([[objectMetadata, [indexMetadata]]]);
|
||||
const result = (await createIndexMigration(map)) as any;
|
||||
|
||||
expect(result).toHaveLength(1);
|
||||
const firstMigration = result[0].migrations[0];
|
||||
|
||||
expect(firstMigration.action).toBe('alter_indexes');
|
||||
expect(firstMigration.indexes[0].name).toBe('idx_simple');
|
||||
expect(firstMigration.indexes[0].columns).toEqual(['simpleField']);
|
||||
expect(firstMigration.indexes[0].type).toBe('BTREE');
|
||||
expect(firstMigration.indexes[0].isUnique).toBe(true);
|
||||
expect(firstMigration.indexes[0].where).toBeNull();
|
||||
});
|
||||
|
||||
it('should create index migrations for relation fields', async () => {
|
||||
const relationField = getMockFieldMetadataEntity({
|
||||
workspaceId: '20202020-0000-0000-0000-000000000000',
|
||||
objectMetadataId: '20202020-0000-0000-0000-000000000001',
|
||||
id: 'f2',
|
||||
type: FieldMetadataType.RELATION,
|
||||
name: 'author',
|
||||
label: 'Author',
|
||||
isNullable: true,
|
||||
isLabelSyncedWithName: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
settings: {
|
||||
relationType: RelationType.MANY_TO_ONE,
|
||||
joinColumnName: 'authorId',
|
||||
},
|
||||
});
|
||||
|
||||
const objectMetadata = {
|
||||
id: '20202020-0000-0000-0000-000000000003',
|
||||
workspaceId: '20202020-0000-0000-0000-000000000000',
|
||||
nameSingular: 'Attachment',
|
||||
fields: [relationField],
|
||||
isCustom: false,
|
||||
};
|
||||
const indexMetadata = {
|
||||
name: 'idx_rel',
|
||||
isUnique: false,
|
||||
indexType: 'BTREE',
|
||||
indexWhereClause: null,
|
||||
indexFieldMetadatas: [{ fieldMetadataId: 'f2', order: 0 }],
|
||||
} as IndexMetadataEntity;
|
||||
const map = new Map([[objectMetadata, [indexMetadata]]]);
|
||||
const result = (await createIndexMigration(map)) as any;
|
||||
|
||||
const firstMigration = result[0].migrations[0];
|
||||
|
||||
expect(firstMigration.indexes[0].columns).toEqual(['authorId']);
|
||||
});
|
||||
});
|
||||
-162
@@ -1,162 +0,0 @@
|
||||
import {
|
||||
type CompositeType,
|
||||
compositeTypeDefinitions,
|
||||
FieldMetadataType,
|
||||
} from 'twenty-shared/types';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { computeCompositeColumnName } from 'src/engine/metadata-modules/field-metadata/utils/compute-column-name.util';
|
||||
import { isCompositeFieldMetadataType } from 'src/engine/metadata-modules/field-metadata/utils/is-composite-field-metadata-type.util';
|
||||
import { type IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
||||
import {
|
||||
type WorkspaceMigrationEntity,
|
||||
WorkspaceMigrationIndexActionType,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
import { isFieldMetadataEntityOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
|
||||
|
||||
export const createIndexMigration = async (
|
||||
indexMetadataByObjectMetadataMap: Map<
|
||||
Pick<
|
||||
ObjectMetadataEntity,
|
||||
'id' | 'workspaceId' | 'nameSingular' | 'isCustom'
|
||||
> & {
|
||||
fields: Pick<FieldMetadataEntity, 'id' | 'name' | 'type' | 'settings'>[];
|
||||
},
|
||||
IndexMetadataEntity[]
|
||||
>,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> => {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const [
|
||||
objectMetadata,
|
||||
indexMetadataCollection,
|
||||
] of indexMetadataByObjectMetadataMap) {
|
||||
const targetTable = computeObjectTargetTable(objectMetadata);
|
||||
|
||||
const fieldsById = Object.fromEntries(
|
||||
objectMetadata.fields.map((field) => [field.id, field]),
|
||||
);
|
||||
|
||||
const indexes = indexMetadataCollection.map((indexMetadata) => {
|
||||
const columns = indexMetadata.indexFieldMetadatas
|
||||
.sort((a, b) => a.order - b.order)
|
||||
.map((indexFieldMetadata) => {
|
||||
const fieldMetadata = fieldsById[indexFieldMetadata.fieldMetadataId];
|
||||
|
||||
if (!fieldMetadata) {
|
||||
throw new Error(
|
||||
`Field metadata with id ${indexFieldMetadata.fieldMetadataId} not found in object metadata with id ${objectMetadata.id}`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
isFieldMetadataEntityOfType(
|
||||
fieldMetadata,
|
||||
FieldMetadataType.RELATION,
|
||||
) ||
|
||||
isFieldMetadataEntityOfType(
|
||||
fieldMetadata,
|
||||
FieldMetadataType.MORPH_RELATION,
|
||||
)
|
||||
) {
|
||||
if (!fieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`Join column name is not supported for relation fields`,
|
||||
);
|
||||
}
|
||||
|
||||
return fieldMetadata.settings.joinColumnName;
|
||||
}
|
||||
|
||||
if (!isCompositeFieldMetadataType(fieldMetadata.type)) {
|
||||
return fieldMetadata.name;
|
||||
}
|
||||
|
||||
const compositeType = compositeTypeDefinitions.get(
|
||||
fieldMetadata.type,
|
||||
) as CompositeType;
|
||||
|
||||
const columns = compositeType.properties
|
||||
.filter((property) => property.isIncludedInUniqueConstraint)
|
||||
.map((property) =>
|
||||
computeCompositeColumnName(fieldMetadata, property),
|
||||
);
|
||||
|
||||
return columns;
|
||||
})
|
||||
.flat()
|
||||
.filter(isDefined);
|
||||
|
||||
return {
|
||||
name: indexMetadata.name,
|
||||
action: WorkspaceMigrationIndexActionType.CREATE,
|
||||
isUnique: indexMetadata.isUnique,
|
||||
columns,
|
||||
type: indexMetadata.indexType,
|
||||
where: indexMetadata.indexWhereClause,
|
||||
};
|
||||
});
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: objectMetadata.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`create-${objectMetadata.nameSingular}-indexes`,
|
||||
),
|
||||
isCustom: false,
|
||||
migrations: [
|
||||
{
|
||||
name: targetTable,
|
||||
action: WorkspaceMigrationTableActionType.ALTER_INDEXES,
|
||||
indexes,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
};
|
||||
|
||||
export const deleteIndexMigration = async (
|
||||
indexMetadataByObjectMetadataMap: Map<
|
||||
ObjectMetadataEntity,
|
||||
IndexMetadataEntity[]
|
||||
>,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> => {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const [
|
||||
objectMetadata,
|
||||
indexMetadataCollection,
|
||||
] of indexMetadataByObjectMetadataMap) {
|
||||
const targetTable = computeObjectTargetTable(objectMetadata);
|
||||
|
||||
const indexes = indexMetadataCollection.map((indexMetadata) => ({
|
||||
name: indexMetadata.name,
|
||||
action: WorkspaceMigrationIndexActionType.DROP,
|
||||
columns: [],
|
||||
isUnique: indexMetadata.isUnique,
|
||||
}));
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: objectMetadata.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`delete-${objectMetadata.nameSingular}-indexes`,
|
||||
),
|
||||
isCustom: false,
|
||||
migrations: [
|
||||
{
|
||||
name: targetTable,
|
||||
action: WorkspaceMigrationTableActionType.ALTER_INDEXES,
|
||||
indexes,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
};
|
||||
-411
@@ -1,411 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { RelationType } from 'src/engine/metadata-modules/field-metadata/interfaces/relation-type.interface';
|
||||
import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface';
|
||||
|
||||
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
||||
import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
type WorkspaceMigrationEntity,
|
||||
type WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
import { isFieldMetadataEntityOfType } from 'src/engine/utils/is-field-metadata-of-type.util';
|
||||
import { type FieldMetadataUpdate } from 'src/engine/workspace-manager/workspace-migration-builder/factories/workspace-migration-field.factory';
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationFieldRelationFactory {
|
||||
constructor(
|
||||
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
||||
) {}
|
||||
|
||||
async create(
|
||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
fieldMetadataCollection: FieldMetadataEntity<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>[],
|
||||
action:
|
||||
| WorkspaceMigrationBuilderAction.CREATE
|
||||
| WorkspaceMigrationBuilderAction.DELETE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
async create(
|
||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
fieldMetadataUpdateCollection: FieldMetadataUpdate<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>[],
|
||||
action: WorkspaceMigrationBuilderAction.UPDATE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
/**
|
||||
* Deletion of the relation is handled by field deletion
|
||||
*/
|
||||
async create(
|
||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
fieldMetadataCollectionOrFieldMetadataUpdateCollection:
|
||||
| FieldMetadataEntity<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>[]
|
||||
| FieldMetadataUpdate<
|
||||
FieldMetadataType.RELATION | FieldMetadataType.MORPH_RELATION
|
||||
>[],
|
||||
action: WorkspaceMigrationBuilderAction,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const originalObjectMetadataMap = originalObjectMetadataCollection.reduce(
|
||||
(result, currentObject) => {
|
||||
result[currentObject.id] = currentObject;
|
||||
|
||||
return result;
|
||||
},
|
||||
{} as Record<string, ObjectMetadataEntity>,
|
||||
);
|
||||
|
||||
switch (action) {
|
||||
case WorkspaceMigrationBuilderAction.CREATE:
|
||||
return this.createFieldRelationMigration(
|
||||
originalObjectMetadataMap,
|
||||
fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataEntity<FieldMetadataType.RELATION>[],
|
||||
);
|
||||
case WorkspaceMigrationBuilderAction.UPDATE:
|
||||
return this.updateFieldRelationMigration(
|
||||
originalObjectMetadataMap,
|
||||
fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataUpdate<FieldMetadataType.RELATION>[],
|
||||
);
|
||||
case WorkspaceMigrationBuilderAction.DELETE:
|
||||
return this.deleteFieldRelationMigration(
|
||||
originalObjectMetadataMap,
|
||||
fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataEntity<FieldMetadataType.RELATION>[],
|
||||
);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private async updateFieldRelationMigration(
|
||||
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||
fieldMetadataUpdateCollection: FieldMetadataUpdate<FieldMetadataType.RELATION>[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const {
|
||||
altered: sourceFieldMetadata,
|
||||
} of fieldMetadataUpdateCollection) {
|
||||
const sourceObjectMetadata =
|
||||
originalObjectMetadataMap[sourceFieldMetadata.objectMetadataId];
|
||||
const targetObjectMetadata =
|
||||
originalObjectMetadataMap[
|
||||
sourceFieldMetadata.relationTargetObjectMetadataId
|
||||
];
|
||||
|
||||
if (!sourceObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.objectMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
sourceFieldMetadata.settings.relationType !== RelationType.MANY_TO_ONE
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings.joinColumnName) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.id} has no join column name in settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!targetObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.relationTargetObjectMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
const targetFieldMetadata = targetObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.id === sourceFieldMetadata.relationTargetFieldMetadataId,
|
||||
);
|
||||
|
||||
if (!targetFieldMetadata) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.relationTargetFieldMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!isFieldMetadataEntityOfType(
|
||||
targetFieldMetadata,
|
||||
FieldMetadataType.RELATION,
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.relationTargetFieldMetadataId} is not a relation`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!targetFieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
);
|
||||
}
|
||||
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP_FOREIGN_KEY,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
referencedTableName:
|
||||
computeObjectTargetTable(targetObjectMetadata),
|
||||
referencedTableColumnName: 'id',
|
||||
onDelete: sourceFieldMetadata.settings.onDelete,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: sourceFieldMetadata.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`update-relation-from-${sourceObjectMetadata.nameSingular}-to-${targetObjectMetadata.nameSingular}`,
|
||||
),
|
||||
isCustom: false,
|
||||
migrations,
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
|
||||
private async createFieldRelationMigration(
|
||||
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||
fieldRelationMetadataCollection: FieldMetadataEntity<FieldMetadataType.RELATION>[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const sourceFieldMetadata of fieldRelationMetadataCollection) {
|
||||
const sourceObjectMetadata =
|
||||
originalObjectMetadataMap[sourceFieldMetadata.objectMetadataId];
|
||||
const targetObjectMetadata =
|
||||
originalObjectMetadataMap[
|
||||
sourceFieldMetadata.relationTargetObjectMetadataId
|
||||
];
|
||||
|
||||
if (!sourceObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.objectMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
sourceFieldMetadata.settings.relationType !== RelationType.MANY_TO_ONE
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings.joinColumnName) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.id} has no join column name in settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!targetObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.relationTargetObjectMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
const targetFieldMetadata = targetObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.id === sourceFieldMetadata.relationTargetFieldMetadataId,
|
||||
);
|
||||
|
||||
if (!targetFieldMetadata) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.relationTargetFieldMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!isFieldMetadataEntityOfType(
|
||||
targetFieldMetadata,
|
||||
FieldMetadataType.RELATION,
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.relationTargetFieldMetadataId} is not a relation`,
|
||||
);
|
||||
}
|
||||
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
...this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.CREATE,
|
||||
sourceFieldMetadata,
|
||||
),
|
||||
],
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
referencedTableName:
|
||||
computeObjectTargetTable(targetObjectMetadata),
|
||||
referencedTableColumnName: 'id',
|
||||
onDelete: sourceFieldMetadata.settings.onDelete,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: sourceFieldMetadata.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`create-relation-from-${sourceObjectMetadata.nameSingular}-to-${targetObjectMetadata.nameSingular}`,
|
||||
),
|
||||
isCustom: false,
|
||||
migrations,
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
|
||||
private async deleteFieldRelationMigration(
|
||||
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||
fieldRelationMetadataCollection: FieldMetadataEntity<FieldMetadataType.RELATION>[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const sourceFieldMetadata of fieldRelationMetadataCollection) {
|
||||
const sourceObjectMetadata =
|
||||
originalObjectMetadataMap[sourceFieldMetadata.objectMetadataId];
|
||||
const targetObjectMetadata =
|
||||
originalObjectMetadataMap[
|
||||
sourceFieldMetadata.relationTargetObjectMetadataId
|
||||
];
|
||||
|
||||
if (!sourceObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.objectMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no settings`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
sourceFieldMetadata.settings.relationType !== RelationType.MANY_TO_ONE
|
||||
) {
|
||||
// Only MANY_TO_ONE relations deletion have consequences on the database schema
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!targetObjectMetadata) {
|
||||
throw new Error(
|
||||
`ObjectMetadata with id ${sourceFieldMetadata.relationTargetObjectMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
const targetFieldMetadata = targetObjectMetadata.fields.find(
|
||||
(field) =>
|
||||
field.id === sourceFieldMetadata.relationTargetFieldMetadataId,
|
||||
);
|
||||
|
||||
if (!targetFieldMetadata) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.relationTargetFieldMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
!isFieldMetadataEntityOfType(
|
||||
targetFieldMetadata,
|
||||
FieldMetadataType.RELATION,
|
||||
)
|
||||
) {
|
||||
throw new Error(
|
||||
`FieldMetadata with id ${sourceFieldMetadata.relationTargetFieldMetadataId} is not a relation`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!sourceFieldMetadata.settings.joinColumnName) {
|
||||
throw new Error(
|
||||
`FieldMetadata for relation with id ${sourceFieldMetadata.id} has no join column name, it should not generate a workspace migration`,
|
||||
);
|
||||
}
|
||||
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP_FOREIGN_KEY,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: computeObjectTargetTable(sourceObjectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP,
|
||||
columnName: sourceFieldMetadata.settings.joinColumnName,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: sourceFieldMetadata.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`update-relation-from-${sourceObjectMetadata.nameSingular}-to-${targetObjectMetadata.nameSingular}`,
|
||||
),
|
||||
isCustom: false,
|
||||
migrations,
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
}
|
||||
-260
@@ -1,260 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import diff from 'microdiff';
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface';
|
||||
|
||||
import { type FieldMetadataEntity } from 'src/engine/metadata-modules/field-metadata/field-metadata.entity';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
||||
import {
|
||||
type WorkspaceMigrationColumnAction,
|
||||
WorkspaceMigrationColumnActionType,
|
||||
type WorkspaceMigrationEntity,
|
||||
type WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
|
||||
export interface FieldMetadataUpdate<
|
||||
Type extends FieldMetadataType = FieldMetadataType,
|
||||
> {
|
||||
current: FieldMetadataEntity<Type>;
|
||||
altered: FieldMetadataEntity<Type>;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationFieldFactory {
|
||||
constructor(
|
||||
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
||||
) {}
|
||||
|
||||
async create(
|
||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
fieldMetadataCollection: FieldMetadataEntity[],
|
||||
action:
|
||||
| WorkspaceMigrationBuilderAction.CREATE
|
||||
| WorkspaceMigrationBuilderAction.DELETE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
async create(
|
||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
fieldMetadataUpdateCollection: FieldMetadataUpdate[],
|
||||
action: WorkspaceMigrationBuilderAction.UPDATE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
async create(
|
||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
fieldMetadataCollectionOrFieldMetadataUpdateCollection:
|
||||
| FieldMetadataEntity[]
|
||||
| FieldMetadataUpdate[],
|
||||
action: WorkspaceMigrationBuilderAction,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const originalObjectMetadataMap = originalObjectMetadataCollection.reduce(
|
||||
(result, currentObject) => {
|
||||
result[currentObject.id] = currentObject;
|
||||
|
||||
return result;
|
||||
},
|
||||
{} as Record<string, ObjectMetadataEntity>,
|
||||
);
|
||||
|
||||
switch (action) {
|
||||
case WorkspaceMigrationBuilderAction.CREATE:
|
||||
return await this.createFieldMigration(
|
||||
originalObjectMetadataMap,
|
||||
fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataEntity[],
|
||||
);
|
||||
case WorkspaceMigrationBuilderAction.UPDATE:
|
||||
return await this.updateFieldMigration(
|
||||
originalObjectMetadataMap,
|
||||
fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataUpdate[],
|
||||
);
|
||||
case WorkspaceMigrationBuilderAction.DELETE:
|
||||
return await this.deleteFieldMigration(
|
||||
originalObjectMetadataMap,
|
||||
fieldMetadataCollectionOrFieldMetadataUpdateCollection as FieldMetadataEntity[],
|
||||
);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private async createFieldMigration(
|
||||
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||
fieldMetadataCollection: FieldMetadataEntity[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
if (fieldMetadataCollection.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const fieldMetadataCollectionGroupByObjectMetadataId =
|
||||
fieldMetadataCollection.reduce(
|
||||
(result, currentFieldMetadata) => {
|
||||
result[currentFieldMetadata.objectMetadataId] = [
|
||||
...(result[currentFieldMetadata.objectMetadataId] || []),
|
||||
currentFieldMetadata,
|
||||
];
|
||||
|
||||
return result;
|
||||
},
|
||||
{} as Record<string, FieldMetadataEntity[]>,
|
||||
);
|
||||
|
||||
for (const objectMetadataId in fieldMetadataCollectionGroupByObjectMetadataId) {
|
||||
const fieldMetadataCollection =
|
||||
fieldMetadataCollectionGroupByObjectMetadataId[objectMetadataId];
|
||||
|
||||
const columns: WorkspaceMigrationColumnAction[] = [];
|
||||
|
||||
const objectMetadata =
|
||||
originalObjectMetadataMap[fieldMetadataCollection[0]?.objectMetadataId];
|
||||
|
||||
for (const fieldMetadata of fieldMetadataCollection) {
|
||||
columns.push(
|
||||
...this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.CREATE,
|
||||
fieldMetadata,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: objectMetadata.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`create-${objectMetadata.nameSingular}-fields`,
|
||||
),
|
||||
isCustom: objectMetadata.isCustom,
|
||||
migrations: [
|
||||
{
|
||||
name: computeObjectTargetTable(
|
||||
originalObjectMetadataMap[objectMetadataId],
|
||||
),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
|
||||
private async updateFieldMigration(
|
||||
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||
fieldMetadataUpdateCollection: FieldMetadataUpdate[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
if (fieldMetadataUpdateCollection.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
for (const fieldMetadataUpdate of fieldMetadataUpdateCollection) {
|
||||
const columnActions = this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.ALTER,
|
||||
fieldMetadataUpdate.current,
|
||||
fieldMetadataUpdate.altered,
|
||||
);
|
||||
|
||||
const isMigrationNeeded = columnActions.reduce(
|
||||
(result, currentColumnAction) => {
|
||||
if (
|
||||
currentColumnAction.action ===
|
||||
WorkspaceMigrationColumnActionType.CREATE ||
|
||||
currentColumnAction.action ===
|
||||
WorkspaceMigrationColumnActionType.DROP
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (
|
||||
currentColumnAction.action ===
|
||||
WorkspaceMigrationColumnActionType.ALTER
|
||||
) {
|
||||
return (
|
||||
diff(
|
||||
currentColumnAction.currentColumnDefinition,
|
||||
currentColumnAction.alteredColumnDefinition,
|
||||
).length > 0
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
false,
|
||||
);
|
||||
|
||||
if (isMigrationNeeded) {
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(
|
||||
originalObjectMetadataMap[
|
||||
fieldMetadataUpdate.current.objectMetadataId
|
||||
],
|
||||
),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.ALTER,
|
||||
fieldMetadataUpdate.current,
|
||||
fieldMetadataUpdate.altered,
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: fieldMetadataUpdate.current.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`update-${fieldMetadataUpdate.altered.name}`,
|
||||
),
|
||||
isCustom: fieldMetadataUpdate.altered.isCustom,
|
||||
migrations,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
|
||||
private async deleteFieldMigration(
|
||||
originalObjectMetadataMap: Record<string, ObjectMetadataEntity>,
|
||||
fieldMetadataCollection: FieldMetadataEntity[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const fieldMetadata of fieldMetadataCollection) {
|
||||
// We're skipping relation fields, because they're just representation and not real columns
|
||||
if (fieldMetadata.type === FieldMetadataType.RELATION) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(
|
||||
originalObjectMetadataMap[fieldMetadata.objectMetadataId],
|
||||
),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: [
|
||||
{
|
||||
action: WorkspaceMigrationColumnActionType.DROP,
|
||||
columnName: fieldMetadata.name,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: fieldMetadata.workspaceId,
|
||||
name: generateMigrationName(`delete-${fieldMetadata.name}`),
|
||||
isCustom: fieldMetadata.isCustom,
|
||||
migrations,
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
}
|
||||
-59
@@ -1,59 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface';
|
||||
|
||||
import { type IndexMetadataEntity } from 'src/engine/metadata-modules/index-metadata/index-metadata.entity';
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { type WorkspaceMigrationEntity } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import {
|
||||
createIndexMigration,
|
||||
deleteIndexMigration,
|
||||
} from 'src/engine/workspace-manager/workspace-migration-builder/factories/utils/workspace-migration-index.factory.utils';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationIndexFactory {
|
||||
constructor() {}
|
||||
|
||||
async create(
|
||||
originalObjectMetadataCollection: ObjectMetadataEntity[],
|
||||
indexMetadataCollection: IndexMetadataEntity[],
|
||||
action: WorkspaceMigrationBuilderAction,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const originalObjectMetadataMap = Object.fromEntries(
|
||||
originalObjectMetadataCollection.map((obj) => [obj.id, obj]),
|
||||
);
|
||||
|
||||
const indexMetadataByObjectMetadataMap = new Map<
|
||||
ObjectMetadataEntity,
|
||||
IndexMetadataEntity[]
|
||||
>();
|
||||
|
||||
indexMetadataCollection.forEach((currentIndexMetadata) => {
|
||||
const objectMetadata =
|
||||
originalObjectMetadataMap[currentIndexMetadata.objectMetadataId];
|
||||
|
||||
if (!objectMetadata) {
|
||||
throw new Error(
|
||||
`Object metadata with id ${currentIndexMetadata.objectMetadataId} not found`,
|
||||
);
|
||||
}
|
||||
|
||||
if (!indexMetadataByObjectMetadataMap.has(objectMetadata)) {
|
||||
indexMetadataByObjectMetadataMap.set(objectMetadata, []);
|
||||
}
|
||||
|
||||
indexMetadataByObjectMetadataMap
|
||||
?.get(objectMetadata)
|
||||
?.push(currentIndexMetadata);
|
||||
});
|
||||
|
||||
switch (action) {
|
||||
case WorkspaceMigrationBuilderAction.CREATE:
|
||||
return createIndexMigration(indexMetadataByObjectMetadataMap);
|
||||
case WorkspaceMigrationBuilderAction.DELETE:
|
||||
return deleteIndexMigration(indexMetadataByObjectMetadataMap);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
}
|
||||
-163
@@ -1,163 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { WorkspaceMigrationBuilderAction } from 'src/engine/workspace-manager/workspace-migration-builder/interfaces/workspace-migration-builder-action.interface';
|
||||
|
||||
import { type ObjectMetadataEntity } from 'src/engine/metadata-modules/object-metadata/object-metadata.entity';
|
||||
import { generateMigrationName } from 'src/engine/metadata-modules/workspace-migration/utils/generate-migration-name.util';
|
||||
import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
type WorkspaceMigrationEntity,
|
||||
type WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceMigrationFactory } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.factory';
|
||||
import { computeObjectTargetTable } from 'src/engine/utils/compute-object-target-table.util';
|
||||
|
||||
export interface ObjectMetadataUpdate {
|
||||
current: ObjectMetadataEntity;
|
||||
altered: ObjectMetadataEntity;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationObjectFactory {
|
||||
constructor(
|
||||
private readonly workspaceMigrationFactory: WorkspaceMigrationFactory,
|
||||
) {}
|
||||
|
||||
async create(
|
||||
objectMetadataCollection: ObjectMetadataEntity[],
|
||||
action: WorkspaceMigrationBuilderAction.CREATE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
async create(
|
||||
objectMetadataUpdateCollection: ObjectMetadataUpdate[],
|
||||
action: WorkspaceMigrationBuilderAction.UPDATE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
async create(
|
||||
objectMetadataCollection: ObjectMetadataEntity[],
|
||||
action: WorkspaceMigrationBuilderAction.DELETE,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]>;
|
||||
|
||||
async create(
|
||||
objectMetadataCollectionOrObjectMetadataUpdateCollection:
|
||||
| ObjectMetadataEntity[]
|
||||
| ObjectMetadataUpdate[],
|
||||
action: WorkspaceMigrationBuilderAction,
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
switch (action) {
|
||||
case WorkspaceMigrationBuilderAction.CREATE:
|
||||
return this.createObjectMigration(
|
||||
objectMetadataCollectionOrObjectMetadataUpdateCollection as ObjectMetadataEntity[],
|
||||
);
|
||||
case WorkspaceMigrationBuilderAction.UPDATE:
|
||||
return this.updateObjectMigration(
|
||||
objectMetadataCollectionOrObjectMetadataUpdateCollection as ObjectMetadataUpdate[],
|
||||
);
|
||||
case WorkspaceMigrationBuilderAction.DELETE:
|
||||
return this.deleteObjectMigration(
|
||||
objectMetadataCollectionOrObjectMetadataUpdateCollection as ObjectMetadataEntity[],
|
||||
);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private async createObjectMigration(
|
||||
objectMetadataCollection: ObjectMetadataEntity[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const objectMetadata of objectMetadataCollection) {
|
||||
const migrations: WorkspaceMigrationTableAction[] = [
|
||||
{
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.CREATE,
|
||||
},
|
||||
];
|
||||
|
||||
for (const field of objectMetadata.fields) {
|
||||
if (field.type === FieldMetadataType.RELATION) {
|
||||
continue;
|
||||
}
|
||||
|
||||
migrations.push({
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
columns: this.workspaceMigrationFactory.createColumnActions(
|
||||
WorkspaceMigrationColumnActionType.CREATE,
|
||||
field,
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
workspaceMigrations.push({
|
||||
workspaceId: objectMetadata.workspaceId,
|
||||
name: generateMigrationName(`create-${objectMetadata.nameSingular}`),
|
||||
isCustom: objectMetadata.isCustom,
|
||||
migrations,
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
|
||||
private async updateObjectMigration(
|
||||
objectMetadataUpdateCollection: ObjectMetadataUpdate[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const objectMetadataUpdate of objectMetadataUpdateCollection) {
|
||||
const oldTableName = computeObjectTargetTable(
|
||||
objectMetadataUpdate.current,
|
||||
);
|
||||
const newTableName = computeObjectTargetTable(
|
||||
objectMetadataUpdate.altered,
|
||||
);
|
||||
|
||||
if (oldTableName !== newTableName) {
|
||||
workspaceMigrations.push({
|
||||
workspaceId: objectMetadataUpdate.current.workspaceId,
|
||||
name: generateMigrationName(
|
||||
`rename-${objectMetadataUpdate.current.nameSingular}`,
|
||||
),
|
||||
isCustom: objectMetadataUpdate.altered.isCustom,
|
||||
migrations: [
|
||||
{
|
||||
name: oldTableName,
|
||||
newName: newTableName,
|
||||
action: WorkspaceMigrationTableActionType.ALTER,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
|
||||
private async deleteObjectMigration(
|
||||
objectMetadataCollection: ObjectMetadataEntity[],
|
||||
): Promise<Partial<WorkspaceMigrationEntity>[]> {
|
||||
const workspaceMigrations: Partial<WorkspaceMigrationEntity>[] = [];
|
||||
|
||||
for (const objectMetadata of objectMetadataCollection) {
|
||||
workspaceMigrations.push({
|
||||
workspaceId: objectMetadata.workspaceId,
|
||||
name: generateMigrationName(`delete-${objectMetadata.nameSingular}`),
|
||||
isCustom: objectMetadata.isCustom,
|
||||
migrations: [
|
||||
{
|
||||
name: computeObjectTargetTable(objectMetadata),
|
||||
action: WorkspaceMigrationTableActionType.DROP,
|
||||
columns: [],
|
||||
} satisfies WorkspaceMigrationTableAction,
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
return workspaceMigrations;
|
||||
}
|
||||
}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
export enum WorkspaceMigrationBuilderAction {
|
||||
CREATE = 'create',
|
||||
UPDATE = 'update',
|
||||
DELETE = 'delete',
|
||||
}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
|
||||
import { workspaceMigrationBuilderFactories } from './factories';
|
||||
|
||||
@Module({
|
||||
imports: [WorkspaceMigrationModule, FeatureFlagModule],
|
||||
providers: [...workspaceMigrationBuilderFactories],
|
||||
exports: [...workspaceMigrationBuilderFactories],
|
||||
})
|
||||
export class WorkspaceMigrationBuilderModule {}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
import { Command, CommandRunner, Option } from 'nest-commander';
|
||||
|
||||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.service';
|
||||
|
||||
interface ExecuteWorkspaceMigrationsOptions {
|
||||
workspaceId: string;
|
||||
}
|
||||
|
||||
@Command({
|
||||
name: 'workspace:apply-pending-migrations',
|
||||
description: 'Apply pending migrations',
|
||||
})
|
||||
export class WorkspaceExecutePendingMigrationsCommand extends CommandRunner {
|
||||
constructor(
|
||||
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
|
||||
) {
|
||||
super();
|
||||
}
|
||||
|
||||
async run(
|
||||
_passedParam: string[],
|
||||
options: ExecuteWorkspaceMigrationsOptions,
|
||||
): Promise<void> {
|
||||
await this.workspaceMigrationRunnerService.executeMigrationFromPendingMigrations(
|
||||
options.workspaceId,
|
||||
);
|
||||
}
|
||||
|
||||
@Option({
|
||||
flags: '-w, --workspace-id [workspace_id]',
|
||||
description: 'workspace id',
|
||||
required: true,
|
||||
})
|
||||
parseWorkspaceId(value: string): string {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
-11
@@ -1,11 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceMigrationRunnerModule } from 'src/engine/workspace-manager/workspace-migration-runner/workspace-migration-runner.module';
|
||||
|
||||
import { WorkspaceExecutePendingMigrationsCommand } from './workspace-execute-pending-migrations.command';
|
||||
|
||||
@Module({
|
||||
imports: [WorkspaceMigrationRunnerModule],
|
||||
providers: [WorkspaceExecutePendingMigrationsCommand],
|
||||
})
|
||||
export class WorkspaceMigrationRunnerCommandsModule {}
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
import { Test, type TestingModule } from '@nestjs/testing';
|
||||
|
||||
import { DataSource, type QueryRunner, TableColumn } from 'typeorm';
|
||||
|
||||
import {
|
||||
WorkspaceMigrationColumnActionType,
|
||||
type WorkspaceMigrationColumnAlter,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceMigrationEnumService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service';
|
||||
|
||||
describe('WorkspaceMigrationEnumService', () => {
|
||||
let service: WorkspaceMigrationEnumService;
|
||||
let queryRunner: QueryRunner;
|
||||
|
||||
beforeEach(async () => {
|
||||
const module: TestingModule = await Test.createTestingModule({
|
||||
providers: [
|
||||
WorkspaceMigrationEnumService,
|
||||
{
|
||||
provide: DataSource,
|
||||
useValue: {
|
||||
createQueryRunner: () => ({
|
||||
query: jest.fn(),
|
||||
addColumn: jest.fn(),
|
||||
}),
|
||||
},
|
||||
},
|
||||
],
|
||||
}).compile();
|
||||
|
||||
service = module.get<WorkspaceMigrationEnumService>(
|
||||
WorkspaceMigrationEnumService,
|
||||
);
|
||||
queryRunner = module.get(DataSource).createQueryRunner();
|
||||
});
|
||||
|
||||
describe('alterEnum', () => {
|
||||
it('should handle enum column alteration with renamed values', async () => {
|
||||
const mockMigrationColumn: WorkspaceMigrationColumnAlter = {
|
||||
action: WorkspaceMigrationColumnActionType.ALTER,
|
||||
currentColumnDefinition: {
|
||||
columnName: 'status',
|
||||
columnType: 'enum',
|
||||
enum: ['ACTIVE', 'INACTIVE'],
|
||||
isNullable: false,
|
||||
defaultValue: 'ACTIVE',
|
||||
},
|
||||
alteredColumnDefinition: {
|
||||
columnName: 'status',
|
||||
columnType: 'enum',
|
||||
enum: [
|
||||
{ from: 'ACTIVE', to: 'ENABLED' },
|
||||
{ from: 'INACTIVE', to: 'DISABLED' },
|
||||
],
|
||||
isNullable: false,
|
||||
defaultValue: 'ENABLED',
|
||||
},
|
||||
};
|
||||
|
||||
jest.spyOn(queryRunner, 'query').mockImplementation((query: string) => {
|
||||
if (query.includes('information_schema.columns')) {
|
||||
return Promise.resolve([{ udt_name: 'test_status_enum' }]);
|
||||
}
|
||||
if (query.includes('SELECT id')) {
|
||||
return Promise.resolve([
|
||||
{ id: '1', status: 'ACTIVE' },
|
||||
{ id: '2', status: 'INACTIVE' },
|
||||
]);
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
||||
await service.alterEnum(
|
||||
queryRunner,
|
||||
'test_schema',
|
||||
'test_table',
|
||||
mockMigrationColumn,
|
||||
);
|
||||
|
||||
expect(queryRunner.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('information_schema.columns'),
|
||||
['test_schema', 'test_table', 'status'],
|
||||
);
|
||||
expect(queryRunner.query).toHaveBeenCalledWith(
|
||||
expect.stringContaining('ALTER TYPE'),
|
||||
);
|
||||
expect(queryRunner.addColumn).toHaveBeenCalledWith(
|
||||
'test_schema.test_table',
|
||||
new TableColumn({
|
||||
name: 'status',
|
||||
type: 'enum',
|
||||
enum: ['ENABLED', 'DISABLED'],
|
||||
isNullable: false,
|
||||
default: 'ENABLED',
|
||||
enumName: 'test_table_status_enum',
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
-372
@@ -1,372 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { type QueryRunner, TableColumn } from 'typeorm';
|
||||
|
||||
import {
|
||||
type WorkspaceMigrationColumnAction,
|
||||
WorkspaceMigrationColumnActionType,
|
||||
type WorkspaceMigrationColumnAlter,
|
||||
type WorkspaceMigrationColumnCreate,
|
||||
type WorkspaceMigrationColumnCreateForeignKey,
|
||||
type WorkspaceMigrationColumnDrop,
|
||||
type WorkspaceMigrationColumnDropForeignKey,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceMigrationEnumService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service';
|
||||
import { WorkspaceMigrationTypeService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-type.service';
|
||||
import { type PostgresQueryRunner } from 'src/engine/workspace-manager/workspace-migration-runner/types/postgres-query-runner.type';
|
||||
import { computePostgresEnumName } from 'src/engine/workspace-manager/workspace-migration-runner/utils/compute-postgres-enum-name.util';
|
||||
import { convertOnDeleteActionToOnDelete } from 'src/engine/workspace-manager/workspace-migration-runner/utils/convert-on-delete-action-to-on-delete.util';
|
||||
import { typeormBuildCreateColumnSql } from 'src/engine/workspace-manager/workspace-migration-runner/utils/internal/typeorm-build-create-column-sql.util';
|
||||
import { removeSqlDDLInjection } from 'src/engine/workspace-manager/workspace-migration-runner/utils/remove-sql-injection.util';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationColumnService {
|
||||
constructor(
|
||||
private readonly workspaceMigrationEnumService: WorkspaceMigrationEnumService,
|
||||
private readonly workspaceMigrationTypeService: WorkspaceMigrationTypeService,
|
||||
) {}
|
||||
|
||||
public async handleColumnChanges(
|
||||
queryRunner: PostgresQueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
columnMigrations?: WorkspaceMigrationColumnAction[],
|
||||
) {
|
||||
if (!columnMigrations || columnMigrations.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const columnsByAction = this.groupColumnsByAction(columnMigrations);
|
||||
|
||||
if (columnsByAction.create.length > 0) {
|
||||
await this.handleCreateColumns(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
columnsByAction.create,
|
||||
);
|
||||
}
|
||||
|
||||
if (columnsByAction.drop.length > 0) {
|
||||
await this.handleDropColumns(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
columnsByAction.drop,
|
||||
);
|
||||
}
|
||||
|
||||
if (columnsByAction.alter.length > 0) {
|
||||
for (const column of columnsByAction.alter) {
|
||||
await this.alterColumn(queryRunner, schemaName, tableName, column);
|
||||
}
|
||||
}
|
||||
|
||||
if (columnsByAction.createForeignKey.length > 0) {
|
||||
for (const column of columnsByAction.createForeignKey) {
|
||||
await this.createForeignKey(queryRunner, schemaName, tableName, column);
|
||||
}
|
||||
}
|
||||
|
||||
if (columnsByAction.dropForeignKey.length > 0) {
|
||||
for (const column of columnsByAction.dropForeignKey) {
|
||||
await this.dropForeignKey(queryRunner, schemaName, tableName, column);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private groupColumnsByAction(
|
||||
columnMigrations: WorkspaceMigrationColumnAction[],
|
||||
) {
|
||||
return columnMigrations.reduce(
|
||||
(acc, column) => {
|
||||
switch (column.action) {
|
||||
case WorkspaceMigrationColumnActionType.CREATE:
|
||||
acc.create.push(column as WorkspaceMigrationColumnCreate);
|
||||
break;
|
||||
case WorkspaceMigrationColumnActionType.ALTER:
|
||||
acc.alter.push(column as WorkspaceMigrationColumnAlter);
|
||||
break;
|
||||
case WorkspaceMigrationColumnActionType.CREATE_FOREIGN_KEY:
|
||||
acc.createForeignKey.push(
|
||||
column as WorkspaceMigrationColumnCreateForeignKey,
|
||||
);
|
||||
break;
|
||||
case WorkspaceMigrationColumnActionType.DROP_FOREIGN_KEY:
|
||||
acc.dropForeignKey.push(
|
||||
column as WorkspaceMigrationColumnDropForeignKey,
|
||||
);
|
||||
break;
|
||||
case WorkspaceMigrationColumnActionType.DROP:
|
||||
acc.drop.push(column as WorkspaceMigrationColumnDrop);
|
||||
break;
|
||||
}
|
||||
|
||||
return acc;
|
||||
},
|
||||
{
|
||||
create: [] as WorkspaceMigrationColumnCreate[],
|
||||
alter: [] as WorkspaceMigrationColumnAlter[],
|
||||
createForeignKey: [] as WorkspaceMigrationColumnCreateForeignKey[],
|
||||
dropForeignKey: [] as WorkspaceMigrationColumnDropForeignKey[],
|
||||
drop: [] as WorkspaceMigrationColumnDrop[],
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
public createTableColumnFromMigration(
|
||||
tableName: string,
|
||||
column: WorkspaceMigrationColumnCreate,
|
||||
): TableColumn {
|
||||
const enumName = column.enum?.length
|
||||
? `${tableName}_${column.columnName}_enum`
|
||||
: undefined;
|
||||
|
||||
return new TableColumn({
|
||||
name: column.columnName,
|
||||
type: column.columnType,
|
||||
default: column.defaultValue,
|
||||
isPrimary: column.columnName === 'id',
|
||||
enum: column.enum?.filter(
|
||||
(value): value is string => typeof value === 'string',
|
||||
),
|
||||
enumName: enumName,
|
||||
isArray: column.isArray,
|
||||
isNullable: column.isNullable,
|
||||
asExpression: column.asExpression,
|
||||
generatedType: column.generatedType,
|
||||
});
|
||||
}
|
||||
|
||||
public async handleCreateColumns(
|
||||
queryRunner: PostgresQueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
createColumnMigrations: WorkspaceMigrationColumnCreate[],
|
||||
) {
|
||||
for (const createColumnMigration of createColumnMigrations) {
|
||||
// TODO: remove once refactor is complete, id column is already created during table creation
|
||||
if (createColumnMigration.columnName === 'id') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isDefined(createColumnMigration.enum)) {
|
||||
const enumName = computePostgresEnumName({
|
||||
tableName,
|
||||
columnName: createColumnMigration.columnName,
|
||||
});
|
||||
|
||||
const joinedEnumValues = createColumnMigration.enum
|
||||
.map((value) => removeSqlDDLInjection(value.toString()))
|
||||
.map((value) => `'${value}'`)
|
||||
.join(',');
|
||||
|
||||
// TODO: remove once drop table as been refactored to remove the enum types
|
||||
await queryRunner.query(`DROP TYPE IF EXISTS "${enumName}"`);
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE TYPE "${enumName}" AS ENUM (${joinedEnumValues})`,
|
||||
);
|
||||
}
|
||||
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "${schemaName}"."${tableName}" ADD ${typeormBuildCreateColumnSql(
|
||||
{
|
||||
table: { name: tableName },
|
||||
column: {
|
||||
name: createColumnMigration.columnName,
|
||||
type: createColumnMigration.columnType,
|
||||
precision:
|
||||
createColumnMigration.columnType === 'timestamptz'
|
||||
? 3
|
||||
: undefined,
|
||||
isArray: createColumnMigration.isArray ?? false,
|
||||
isNullable: createColumnMigration.isNullable,
|
||||
default: createColumnMigration.defaultValue,
|
||||
asExpression: createColumnMigration.asExpression,
|
||||
generatedType: createColumnMigration.generatedType,
|
||||
},
|
||||
},
|
||||
)}`,
|
||||
);
|
||||
|
||||
if (createColumnMigration.columnName === 'id') {
|
||||
const pkName = queryRunner.connection.namingStrategy.primaryKeyName(
|
||||
tableName,
|
||||
[createColumnMigration.columnName],
|
||||
);
|
||||
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "${schemaName}"."${tableName} ADD CONSTRAINT "${pkName}" PRIMARY KEY (${removeSqlDDLInjection(createColumnMigration.columnName)})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async handleDropColumns(
|
||||
queryRunner: PostgresQueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
dropColumns: WorkspaceMigrationColumnDrop[],
|
||||
) {
|
||||
if (dropColumns.length === 0) return;
|
||||
|
||||
const columnNames = dropColumns.map((column) => column.columnName);
|
||||
|
||||
await queryRunner.dropColumns(`${schemaName}.${tableName}`, columnNames);
|
||||
}
|
||||
|
||||
public async alterColumn(
|
||||
queryRunner: PostgresQueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
migrationColumn: WorkspaceMigrationColumnAlter,
|
||||
) {
|
||||
const enumValues = migrationColumn.alteredColumnDefinition.enum;
|
||||
|
||||
// TODO: Maybe we can do something better if we can recreate the old `TableColumn` object
|
||||
if (enumValues) {
|
||||
// This is returning the old enum values to avoid TypeORM dropping the enum type
|
||||
await this.workspaceMigrationEnumService.alterEnum(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
migrationColumn,
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
migrationColumn.currentColumnDefinition.columnType !==
|
||||
migrationColumn.alteredColumnDefinition.columnType
|
||||
) {
|
||||
await this.workspaceMigrationTypeService.alterType(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
migrationColumn,
|
||||
);
|
||||
|
||||
migrationColumn.currentColumnDefinition.columnType =
|
||||
migrationColumn.alteredColumnDefinition.columnType;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
await queryRunner.changeColumn(
|
||||
`${schemaName}.${tableName}`,
|
||||
new TableColumn({
|
||||
name: migrationColumn.currentColumnDefinition.columnName,
|
||||
type: migrationColumn.currentColumnDefinition.columnType,
|
||||
default: migrationColumn.currentColumnDefinition.defaultValue,
|
||||
enum: migrationColumn.currentColumnDefinition.enum?.filter(
|
||||
(value): value is string => typeof value === 'string',
|
||||
),
|
||||
isArray: migrationColumn.currentColumnDefinition.isArray,
|
||||
isNullable: migrationColumn.currentColumnDefinition.isNullable,
|
||||
/* For now unique constraints are created at a higher level
|
||||
as we need to handle soft-delete and a bug on empty strings
|
||||
*/
|
||||
// isUnique: migrationColumn.currentColumnDefinition.isUnique,
|
||||
}),
|
||||
new TableColumn({
|
||||
name: migrationColumn.alteredColumnDefinition.columnName,
|
||||
type: migrationColumn.alteredColumnDefinition.columnType,
|
||||
default: migrationColumn.alteredColumnDefinition.defaultValue,
|
||||
enum: migrationColumn.currentColumnDefinition.enum?.filter(
|
||||
(value): value is string => typeof value === 'string',
|
||||
),
|
||||
isArray: migrationColumn.alteredColumnDefinition.isArray,
|
||||
isNullable: migrationColumn.alteredColumnDefinition.isNullable,
|
||||
asExpression: migrationColumn.alteredColumnDefinition.asExpression,
|
||||
generatedType: migrationColumn.alteredColumnDefinition.generatedType,
|
||||
/* For now unique constraints are created at a higher level
|
||||
as we need to handle soft-delete and a bug on empty strings
|
||||
*/
|
||||
// isUnique: migrationColumn.alteredColumnDefinition.isUnique,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private async createForeignKey(
|
||||
queryRunner: PostgresQueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
migrationColumn: WorkspaceMigrationColumnCreateForeignKey,
|
||||
) {
|
||||
// Code reference:
|
||||
// https://github.com/typeorm/typeorm/blob/master/src/driver/postgres/PostgresQueryRunner.ts#L2894
|
||||
const foreignKeyName = queryRunner.connection.namingStrategy.foreignKeyName(
|
||||
tableName,
|
||||
[migrationColumn.columnName],
|
||||
`${schemaName}.${migrationColumn.referencedTableName}`,
|
||||
[migrationColumn.referencedTableColumnName],
|
||||
);
|
||||
|
||||
let sql =
|
||||
`ALTER TABLE "${schemaName}"."${tableName}" ADD CONSTRAINT "${
|
||||
foreignKeyName
|
||||
}" FOREIGN KEY ("${removeSqlDDLInjection(migrationColumn.columnName)}") ` +
|
||||
`REFERENCES "${schemaName}"."${removeSqlDDLInjection(migrationColumn.referencedTableName)}"("${removeSqlDDLInjection(migrationColumn.referencedTableColumnName)}")`;
|
||||
|
||||
if (migrationColumn.onDelete)
|
||||
sql += ` ON DELETE ${convertOnDeleteActionToOnDelete(migrationColumn.onDelete)}`;
|
||||
|
||||
await queryRunner.query(sql);
|
||||
}
|
||||
|
||||
private async dropForeignKey(
|
||||
queryRunner: PostgresQueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
migrationColumn: WorkspaceMigrationColumnDropForeignKey,
|
||||
) {
|
||||
const foreignKeyName = await this.getForeignKeyName(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
migrationColumn.columnName,
|
||||
);
|
||||
|
||||
if (!foreignKeyName) {
|
||||
throw new Error(
|
||||
`Foreign key not found for column ${migrationColumn.columnName}`,
|
||||
);
|
||||
}
|
||||
|
||||
await queryRunner.dropForeignKey(
|
||||
`${schemaName}.${tableName}`,
|
||||
foreignKeyName,
|
||||
);
|
||||
}
|
||||
|
||||
private async getForeignKeyName(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
columnName: string,
|
||||
): Promise<string | undefined> {
|
||||
const foreignKeys = await queryRunner.query(
|
||||
`
|
||||
SELECT
|
||||
tc.constraint_name AS constraint_name
|
||||
FROM
|
||||
information_schema.table_constraints AS tc
|
||||
JOIN
|
||||
information_schema.key_column_usage AS kcu
|
||||
ON tc.constraint_name = kcu.constraint_name
|
||||
AND tc.table_schema = kcu.table_schema
|
||||
WHERE
|
||||
tc.constraint_type = 'FOREIGN KEY'
|
||||
AND tc.table_schema = $1
|
||||
AND tc.table_name = $2
|
||||
AND kcu.column_name = $3
|
||||
`,
|
||||
[schemaName, tableName, columnName],
|
||||
);
|
||||
|
||||
return foreignKeys[0]?.constraint_name;
|
||||
}
|
||||
}
|
||||
-259
@@ -1,259 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { isDefined } from 'class-validator';
|
||||
import { type QueryRunner, TableColumn } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
|
||||
import { serializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/serialize-default-value';
|
||||
import { unserializeDefaultValue } from 'src/engine/metadata-modules/field-metadata/utils/unserialize-default-value';
|
||||
import {
|
||||
type WorkspaceMigrationColumnAlter,
|
||||
type WorkspaceMigrationRenamedEnum,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import {
|
||||
WorkspaceMigrationException,
|
||||
WorkspaceMigrationExceptionCode,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.exception';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationEnumService {
|
||||
async alterEnum(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
migrationColumn: WorkspaceMigrationColumnAlter,
|
||||
) {
|
||||
const oldEnumTypeName = await this.getEnumTypeName(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
migrationColumn.currentColumnDefinition.columnName,
|
||||
);
|
||||
|
||||
// Rename column name
|
||||
if (
|
||||
migrationColumn.currentColumnDefinition.columnName !==
|
||||
migrationColumn.alteredColumnDefinition.columnName
|
||||
) {
|
||||
await this.renameColumn(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
migrationColumn.currentColumnDefinition.columnName,
|
||||
migrationColumn.alteredColumnDefinition.columnName,
|
||||
);
|
||||
}
|
||||
|
||||
const columnDefinition = migrationColumn.alteredColumnDefinition;
|
||||
const tempEnumTypeName = `${oldEnumTypeName}_temp`;
|
||||
const newEnumTypeName = `${tableName}_${columnDefinition.columnName}_enum`;
|
||||
const enumValues =
|
||||
columnDefinition.enum?.map((enumValue) => {
|
||||
if (typeof enumValue === 'string') {
|
||||
return enumValue;
|
||||
}
|
||||
|
||||
return enumValue.to;
|
||||
}) ?? [];
|
||||
const renamedEnumValues = columnDefinition.enum?.filter(
|
||||
(enumValue): enumValue is WorkspaceMigrationRenamedEnum =>
|
||||
typeof enumValue !== 'string',
|
||||
);
|
||||
|
||||
const oldColumnName = `old_${v4()}`;
|
||||
|
||||
// Rename old column
|
||||
await this.renameColumn(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
columnDefinition.columnName,
|
||||
oldColumnName,
|
||||
);
|
||||
await this.renameEnumType(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
oldEnumTypeName,
|
||||
tempEnumTypeName,
|
||||
);
|
||||
|
||||
await queryRunner.addColumn(
|
||||
`${schemaName}.${tableName}`,
|
||||
new TableColumn({
|
||||
name: columnDefinition.columnName,
|
||||
type: columnDefinition.columnType,
|
||||
default: columnDefinition.defaultValue,
|
||||
enum: enumValues,
|
||||
enumName: newEnumTypeName,
|
||||
isArray: columnDefinition.isArray,
|
||||
isNullable: columnDefinition.isNullable,
|
||||
isUnique: columnDefinition.isUnique,
|
||||
}),
|
||||
);
|
||||
|
||||
await this.migrateEnumValues(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
migrationColumn,
|
||||
tableName,
|
||||
oldColumnName,
|
||||
enumValues,
|
||||
renamedEnumValues,
|
||||
);
|
||||
|
||||
// Drop old column
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "${schemaName}"."${tableName}"
|
||||
DROP COLUMN "${oldColumnName}"
|
||||
`);
|
||||
// Drop temp enum type
|
||||
await this.dropOldEnumType(queryRunner, schemaName, tempEnumTypeName);
|
||||
}
|
||||
|
||||
private async renameColumn(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
oldColumnName: string,
|
||||
newColumnName: string,
|
||||
) {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "${schemaName}"."${tableName}"
|
||||
RENAME COLUMN "${oldColumnName}" TO "${newColumnName}"
|
||||
`);
|
||||
}
|
||||
|
||||
private migrateEnumValue({
|
||||
value,
|
||||
renamedEnumValues,
|
||||
allEnumValues,
|
||||
defaultValueFallback,
|
||||
}: {
|
||||
value: string;
|
||||
renamedEnumValues?: WorkspaceMigrationRenamedEnum[];
|
||||
allEnumValues?: string[];
|
||||
defaultValueFallback?: string;
|
||||
}) {
|
||||
if (renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to) {
|
||||
return renamedEnumValues?.find((enumVal) => enumVal?.from === value)?.to;
|
||||
}
|
||||
|
||||
if (allEnumValues?.includes(value)) {
|
||||
const isDestinationOfRename = renamedEnumValues?.some(
|
||||
(enumVal) => enumVal.to === value,
|
||||
);
|
||||
|
||||
if (!isDestinationOfRename) {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDefined(defaultValueFallback)) {
|
||||
return defaultValueFallback;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private async migrateEnumValues(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
migrationColumn: WorkspaceMigrationColumnAlter,
|
||||
tableName: string,
|
||||
oldColumnName: string,
|
||||
enumValues: string[],
|
||||
renamedEnumValues?: WorkspaceMigrationRenamedEnum[],
|
||||
) {
|
||||
const columnDefinition = migrationColumn.alteredColumnDefinition;
|
||||
|
||||
const values = await queryRunner.query(
|
||||
`SELECT id, "${oldColumnName}" FROM "${schemaName}"."${tableName}"`,
|
||||
);
|
||||
|
||||
for (const value of values) {
|
||||
let val = value[oldColumnName];
|
||||
|
||||
if (/^\{.*\}$/.test(val)) {
|
||||
val = serializeDefaultValue(
|
||||
val
|
||||
.slice(1, -1)
|
||||
.split(',')
|
||||
.map((v: string) => v.trim())
|
||||
.map((v: string) =>
|
||||
this.migrateEnumValue({
|
||||
value: v,
|
||||
renamedEnumValues: renamedEnumValues,
|
||||
allEnumValues: enumValues,
|
||||
}),
|
||||
)
|
||||
.filter((v: string | null) => isDefined(v)),
|
||||
);
|
||||
} else if (typeof val === 'string') {
|
||||
const migratedValue = this.migrateEnumValue({
|
||||
value: val,
|
||||
renamedEnumValues: renamedEnumValues,
|
||||
allEnumValues: enumValues,
|
||||
defaultValueFallback: columnDefinition.isNullable
|
||||
? null
|
||||
: unserializeDefaultValue(columnDefinition.defaultValue),
|
||||
});
|
||||
|
||||
val = isDefined(migratedValue) ? `'${migratedValue}'` : null;
|
||||
}
|
||||
|
||||
await queryRunner.query(`
|
||||
UPDATE "${schemaName}"."${tableName}"
|
||||
SET "${columnDefinition.columnName}" = ${val}
|
||||
WHERE id='${value.id}'
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
private async dropOldEnumType(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
oldEnumTypeName: string,
|
||||
) {
|
||||
await queryRunner.query(
|
||||
`DROP TYPE IF EXISTS "${schemaName}"."${oldEnumTypeName}"`,
|
||||
);
|
||||
}
|
||||
|
||||
private async renameEnumType(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
oldEnumTypeName: string,
|
||||
newEnumTypeName: string,
|
||||
) {
|
||||
await queryRunner.query(`
|
||||
ALTER TYPE "${schemaName}"."${oldEnumTypeName}"
|
||||
RENAME TO "${newEnumTypeName}"
|
||||
`);
|
||||
}
|
||||
|
||||
private async getEnumTypeName(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
columnName: string,
|
||||
): Promise<string> {
|
||||
const [result] = await queryRunner.query(
|
||||
`SELECT udt_name, data_type FROM information_schema.columns WHERE table_schema = $1 AND table_name = $2 AND column_name = $3`,
|
||||
[schemaName, tableName, columnName],
|
||||
);
|
||||
|
||||
if (!result) {
|
||||
throw new WorkspaceMigrationException(
|
||||
`Enum type name not found for column ${columnName} in table ${tableName} while trying to alter enum`,
|
||||
WorkspaceMigrationExceptionCode.ENUM_TYPE_NAME_NOT_FOUND,
|
||||
);
|
||||
}
|
||||
|
||||
const enumTypeName =
|
||||
result.data_type === 'ARRAY'
|
||||
? result.udt_name.replace(/^_/, '')
|
||||
: result.udt_name;
|
||||
|
||||
return enumTypeName;
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
|
||||
import { type QueryRunner } from 'typeorm';
|
||||
|
||||
import { type WorkspaceMigrationColumnAlter } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationTypeService {
|
||||
constructor() {}
|
||||
|
||||
async alterType(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
migrationColumn: WorkspaceMigrationColumnAlter,
|
||||
) {
|
||||
const columnDefinition = migrationColumn.alteredColumnDefinition;
|
||||
const computedColumnType = ` ${columnDefinition.columnType}${
|
||||
columnDefinition.columnType === 'timestamptz' ? `(3)` : ''
|
||||
}`;
|
||||
|
||||
// Update the column type
|
||||
// If casting is not possible, the query will fail
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "${schemaName}"."${tableName}"
|
||||
ALTER COLUMN "${columnDefinition.columnName}" TYPE ${computedColumnType}
|
||||
USING "${columnDefinition.columnName}"::${computedColumnType}
|
||||
`);
|
||||
|
||||
// Update the column default value
|
||||
if (columnDefinition.defaultValue) {
|
||||
await queryRunner.query(`
|
||||
ALTER TABLE "${schemaName}"."${tableName}"
|
||||
ALTER COLUMN "${columnDefinition.columnName}" SET DEFAULT ${columnDefinition.defaultValue}::${columnDefinition.columnType};
|
||||
`);
|
||||
}
|
||||
}
|
||||
}
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
import { type QueryRunner } from 'typeorm';
|
||||
|
||||
export type PostgresQueryRunner = QueryRunner & {
|
||||
connection: QueryRunner['connection'] & {
|
||||
driver: QueryRunner['connection']['driver'] & {
|
||||
uuidGenerator: () => string;
|
||||
};
|
||||
};
|
||||
};
|
||||
-95
@@ -1,95 +0,0 @@
|
||||
import { typeormBuildCreateColumnSql } from './typeorm-build-create-column-sql.util';
|
||||
|
||||
describe('typeormBuildCreateColumnSql', () => {
|
||||
const table = { name: 'my_table' };
|
||||
|
||||
it('should generate SQL for a simple text column', () => {
|
||||
const column = {
|
||||
name: 'col1',
|
||||
type: 'text',
|
||||
isArray: false,
|
||||
isNullable: false,
|
||||
default: undefined,
|
||||
generatedType: undefined,
|
||||
asExpression: undefined,
|
||||
};
|
||||
const sql = typeormBuildCreateColumnSql({ table, column });
|
||||
|
||||
expect(sql).toBe('"col1" text NOT NULL');
|
||||
});
|
||||
|
||||
it('should generate SQL for a text[] (array) column', () => {
|
||||
const column = {
|
||||
name: 'col2',
|
||||
type: 'text',
|
||||
isArray: true,
|
||||
isNullable: true,
|
||||
default: undefined,
|
||||
generatedType: undefined,
|
||||
asExpression: undefined,
|
||||
};
|
||||
const sql = typeormBuildCreateColumnSql({ table, column });
|
||||
|
||||
expect(sql).toBe('"col2" text[]');
|
||||
});
|
||||
|
||||
it('should generate SQL for an enum column', () => {
|
||||
const column = {
|
||||
name: 'col3',
|
||||
type: 'enum',
|
||||
isArray: false,
|
||||
isNullable: true,
|
||||
default: undefined,
|
||||
generatedType: undefined,
|
||||
asExpression: undefined,
|
||||
};
|
||||
const sql = typeormBuildCreateColumnSql({ table, column });
|
||||
|
||||
expect(sql).toBe('"col3" "my_table_col3_enum"');
|
||||
});
|
||||
|
||||
it('should generate SQL for an enum[] (array) column', () => {
|
||||
const column = {
|
||||
name: 'col4',
|
||||
type: 'enum',
|
||||
isArray: true,
|
||||
isNullable: false,
|
||||
default: undefined,
|
||||
generatedType: undefined,
|
||||
asExpression: undefined,
|
||||
};
|
||||
const sql = typeormBuildCreateColumnSql({ table, column });
|
||||
|
||||
expect(sql).toBe('"col4" "my_table_col4_enum"[] NOT NULL');
|
||||
});
|
||||
|
||||
it('should include default and nullability', () => {
|
||||
const column = {
|
||||
name: 'col5',
|
||||
type: 'text',
|
||||
isArray: false,
|
||||
isNullable: false,
|
||||
default: "'default'",
|
||||
generatedType: undefined,
|
||||
asExpression: undefined,
|
||||
};
|
||||
const sql = typeormBuildCreateColumnSql({ table, column });
|
||||
|
||||
expect(sql).toBe('"col5" text NOT NULL DEFAULT \'default\'');
|
||||
});
|
||||
|
||||
it('should include generatedType and asExpression', () => {
|
||||
const column = {
|
||||
name: 'col6',
|
||||
type: 'text',
|
||||
isArray: false,
|
||||
isNullable: true,
|
||||
default: undefined,
|
||||
generatedType: 'STORED' as const,
|
||||
asExpression: 'lower(col6)',
|
||||
};
|
||||
const sql = typeormBuildCreateColumnSql({ table, column });
|
||||
|
||||
expect(sql).toBe('"col6" text GENERATED ALWAYS AS (lower(col6)) STORED');
|
||||
});
|
||||
});
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
// This code is from TypeORM and is used to build the SQL for creating a column
|
||||
|
||||
import { type Table, type TableColumn } from 'typeorm';
|
||||
|
||||
import { computePostgresEnumName } from 'src/engine/workspace-manager/workspace-migration-runner/utils/compute-postgres-enum-name.util';
|
||||
|
||||
// Do not modify: https://github.com/typeorm/typeorm/blob/master/src/driver/postgres/PostgresQueryRunner.ts#L4713
|
||||
export const typeormBuildCreateColumnSql = ({
|
||||
table,
|
||||
column,
|
||||
}: {
|
||||
table: Pick<Table, 'name'>;
|
||||
column: Pick<
|
||||
TableColumn,
|
||||
| 'name'
|
||||
| 'type'
|
||||
| 'isArray'
|
||||
| 'isNullable'
|
||||
| 'default'
|
||||
| 'generatedType'
|
||||
| 'asExpression'
|
||||
| 'precision'
|
||||
>;
|
||||
}): string => {
|
||||
let columnSql = '"' + column.name + '"';
|
||||
|
||||
if (column.type === 'enum' || column.type === 'simple-enum') {
|
||||
columnSql += ` "${computePostgresEnumName({
|
||||
tableName: table.name,
|
||||
columnName: column.name,
|
||||
})}"`;
|
||||
} else {
|
||||
columnSql += ' ' + column.type;
|
||||
if (column.precision) columnSql += `(${column.precision})`;
|
||||
}
|
||||
|
||||
if (column.isArray) columnSql += '[]';
|
||||
|
||||
if (column.generatedType === 'STORED' && column.asExpression) {
|
||||
columnSql += ` GENERATED ALWAYS AS (${column.asExpression}) STORED`;
|
||||
}
|
||||
|
||||
if (column.isNullable !== true) columnSql += ' NOT NULL';
|
||||
if (column.default !== undefined && column.default !== null)
|
||||
columnSql += ' DEFAULT ' + column.default;
|
||||
|
||||
return columnSql;
|
||||
};
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
import { type TableColumnOptions } from 'typeorm';
|
||||
|
||||
export const tableDefaultColumns = (): TableColumnOptions[] => [
|
||||
{
|
||||
name: 'id',
|
||||
type: 'uuid',
|
||||
isPrimary: true,
|
||||
default: 'public.uuid_generate_v4()',
|
||||
},
|
||||
];
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceMigrationModule } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.module';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { WorkspaceMigrationColumnService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-column.service';
|
||||
import { WorkspaceMigrationEnumService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-enum.service';
|
||||
import { WorkspaceMigrationTypeService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-type.service';
|
||||
|
||||
import { WorkspaceMigrationRunnerService } from './workspace-migration-runner.service';
|
||||
|
||||
@Module({
|
||||
imports: [WorkspaceDataSourceModule, WorkspaceMigrationModule],
|
||||
providers: [
|
||||
WorkspaceMigrationRunnerService,
|
||||
WorkspaceMigrationEnumService,
|
||||
WorkspaceMigrationTypeService,
|
||||
WorkspaceMigrationColumnService,
|
||||
],
|
||||
exports: [WorkspaceMigrationRunnerService],
|
||||
})
|
||||
export class WorkspaceMigrationRunnerModule {}
|
||||
-415
@@ -1,415 +0,0 @@
|
||||
import { Injectable, Logger } from '@nestjs/common';
|
||||
import { InjectDataSource } from '@nestjs/typeorm';
|
||||
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { DataSource, type QueryRunner, Table, type TableColumn } from 'typeorm';
|
||||
|
||||
import {
|
||||
IndexMetadataException,
|
||||
IndexMetadataExceptionCode,
|
||||
} from 'src/engine/metadata-modules/index-metadata/index-field-metadata.exception';
|
||||
import { IndexType } from 'src/engine/metadata-modules/index-metadata/types/indexType.types';
|
||||
import {
|
||||
type WorkspaceMigrationColumnAction,
|
||||
WorkspaceMigrationColumnActionType,
|
||||
type WorkspaceMigrationColumnCreate,
|
||||
type WorkspaceMigrationForeignTable,
|
||||
type WorkspaceMigrationIndexAction,
|
||||
WorkspaceMigrationIndexActionType,
|
||||
type WorkspaceMigrationTableAction,
|
||||
WorkspaceMigrationTableActionType,
|
||||
} from 'src/engine/metadata-modules/workspace-migration/workspace-migration.entity';
|
||||
import { WorkspaceMigrationService } from 'src/engine/metadata-modules/workspace-migration/workspace-migration.service';
|
||||
import { getWorkspaceSchemaName } from 'src/engine/workspace-datasource/utils/get-workspace-schema-name.util';
|
||||
import { WorkspaceMigrationColumnService } from 'src/engine/workspace-manager/workspace-migration-runner/services/workspace-migration-column.service';
|
||||
import { type PostgresQueryRunner } from 'src/engine/workspace-manager/workspace-migration-runner/types/postgres-query-runner.type';
|
||||
import { tableDefaultColumns } from 'src/engine/workspace-manager/workspace-migration-runner/utils/table-default-column.util';
|
||||
|
||||
export const RELATION_MIGRATION_PRIORITY_PREFIX = '1000';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationRunnerService {
|
||||
private readonly logger = new Logger(WorkspaceMigrationRunnerService.name);
|
||||
|
||||
constructor(
|
||||
@InjectDataSource()
|
||||
private readonly coreDataSource: DataSource,
|
||||
private readonly workspaceMigrationService: WorkspaceMigrationService,
|
||||
private readonly workspaceMigrationColumnService: WorkspaceMigrationColumnService,
|
||||
) {}
|
||||
|
||||
public async executeMigrationFromPendingMigrationsWithinTransaction(
|
||||
workspaceId: string,
|
||||
transactionQueryRunner: QueryRunner,
|
||||
): Promise<WorkspaceMigrationTableAction[]> {
|
||||
const pendingMigrations =
|
||||
await this.workspaceMigrationService.getPendingMigrations(
|
||||
workspaceId,
|
||||
transactionQueryRunner,
|
||||
);
|
||||
|
||||
if (pendingMigrations.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const migrationActionsWithParent = pendingMigrations.flatMap(
|
||||
(pendingMigration) =>
|
||||
(pendingMigration.migrations || []).map((tableAction) => ({
|
||||
tableAction,
|
||||
parentMigrationId: pendingMigration.id,
|
||||
})),
|
||||
);
|
||||
|
||||
const schemaName = getWorkspaceSchemaName(workspaceId);
|
||||
|
||||
await transactionQueryRunner.query(
|
||||
`SET LOCAL search_path TO ${schemaName}`,
|
||||
);
|
||||
|
||||
// temporary fix to skip view migrations issue during upgrade 1.8 -> 1.10
|
||||
const migrationActionsWithParentTmp = [
|
||||
...migrationActionsWithParent.filter(
|
||||
({ tableAction }) => tableAction.name !== 'view',
|
||||
),
|
||||
...migrationActionsWithParent.filter(
|
||||
({ tableAction }) => tableAction.name === 'view',
|
||||
),
|
||||
];
|
||||
|
||||
for (const {
|
||||
tableAction,
|
||||
parentMigrationId,
|
||||
} of migrationActionsWithParentTmp) {
|
||||
await this.handleTableChanges(
|
||||
transactionQueryRunner as PostgresQueryRunner,
|
||||
schemaName,
|
||||
tableAction,
|
||||
);
|
||||
|
||||
await transactionQueryRunner.query(
|
||||
`UPDATE "core"."workspaceMigration" SET "appliedAt" = NOW() WHERE "id" = $1 AND "workspaceId" = $2`,
|
||||
[parentMigrationId, workspaceId],
|
||||
);
|
||||
}
|
||||
|
||||
return migrationActionsWithParentTmp.map((item) => item.tableAction);
|
||||
}
|
||||
|
||||
public async executeMigrationFromPendingMigrations(
|
||||
workspaceId: string,
|
||||
): Promise<WorkspaceMigrationTableAction[]> {
|
||||
const queryRunner = this.coreDataSource.createQueryRunner();
|
||||
|
||||
await queryRunner.connect();
|
||||
await queryRunner.startTransaction();
|
||||
|
||||
try {
|
||||
const result =
|
||||
await this.executeMigrationFromPendingMigrationsWithinTransaction(
|
||||
workspaceId,
|
||||
queryRunner,
|
||||
);
|
||||
|
||||
await queryRunner.commitTransaction();
|
||||
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Error executing migration: ${error.message}`,
|
||||
error.stack,
|
||||
);
|
||||
if (queryRunner.isTransactionActive) {
|
||||
try {
|
||||
await queryRunner.rollbackTransaction();
|
||||
} catch (error) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.trace(`Failed to rollback transaction: ${error.message}`);
|
||||
}
|
||||
}
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
}
|
||||
|
||||
private async handleTableChanges(
|
||||
queryRunner: PostgresQueryRunner,
|
||||
schemaName: string,
|
||||
tableMigration: WorkspaceMigrationTableAction,
|
||||
) {
|
||||
switch (tableMigration.action) {
|
||||
case WorkspaceMigrationTableActionType.CREATE:
|
||||
await this.createTable(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableMigration.name,
|
||||
tableMigration.columns,
|
||||
);
|
||||
break;
|
||||
case WorkspaceMigrationTableActionType.ALTER: {
|
||||
if (tableMigration.newName) {
|
||||
await this.renameTable(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableMigration.name,
|
||||
tableMigration.newName,
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (tableMigration.columns && tableMigration.columns.length > 0) {
|
||||
await this.workspaceMigrationColumnService.handleColumnChanges(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableMigration.newName ?? tableMigration.name,
|
||||
tableMigration.columns,
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WorkspaceMigrationTableActionType.DROP:
|
||||
await queryRunner.dropTable(`${schemaName}.${tableMigration.name}`);
|
||||
break;
|
||||
case 'create_foreign_table':
|
||||
await this.createForeignTable(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableMigration.name,
|
||||
tableMigration?.foreignTable,
|
||||
);
|
||||
break;
|
||||
case 'drop_foreign_table':
|
||||
await queryRunner.query(
|
||||
`DROP FOREIGN TABLE ${schemaName}."${tableMigration.name}"`,
|
||||
);
|
||||
break;
|
||||
case WorkspaceMigrationTableActionType.ALTER_FOREIGN_TABLE:
|
||||
await this.alterForeignTable(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableMigration.name,
|
||||
tableMigration.columns,
|
||||
);
|
||||
break;
|
||||
|
||||
case WorkspaceMigrationTableActionType.ALTER_INDEXES:
|
||||
if (tableMigration.indexes && tableMigration.indexes.length > 0) {
|
||||
const tableName = tableMigration.newName ?? tableMigration.name;
|
||||
|
||||
await this.handleIndexesChanges(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
tableMigration.indexes,
|
||||
);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Error(
|
||||
`Migration table action ${tableMigration.action} not supported`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private async handleIndexesChanges(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
indexes: WorkspaceMigrationIndexAction[],
|
||||
) {
|
||||
for (const index of indexes) {
|
||||
switch (index.action) {
|
||||
case WorkspaceMigrationIndexActionType.CREATE:
|
||||
await this.createIndex(queryRunner, schemaName, tableName, index);
|
||||
break;
|
||||
case WorkspaceMigrationIndexActionType.DROP:
|
||||
await this.dropIndex(queryRunner, schemaName, tableName, index.name);
|
||||
break;
|
||||
default:
|
||||
throw new Error(`Migration index action not supported`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async createIndex(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
index: WorkspaceMigrationIndexAction,
|
||||
) {
|
||||
try {
|
||||
if (isDefined(index.type) && index.type !== IndexType.BTREE) {
|
||||
const quotedColumns = index.columns.map((column) => `"${column}"`);
|
||||
|
||||
await queryRunner.query(`
|
||||
CREATE INDEX IF NOT EXISTS "${index.name}" ON "${schemaName}"."${tableName}" USING ${index.type} (${quotedColumns.join(', ')})
|
||||
`);
|
||||
} else {
|
||||
const quotedColumns = index.columns.map((column) => `"${column}"`);
|
||||
const isUnique = index.isUnique ? 'UNIQUE' : '';
|
||||
const whereClause = index.where ? `WHERE ${index.where}` : '';
|
||||
|
||||
await queryRunner.query(`
|
||||
CREATE ${isUnique} INDEX IF NOT EXISTS "${index.name}" ON "${schemaName}"."${tableName}" (${quotedColumns.join(', ')}) ${whereClause}
|
||||
`);
|
||||
}
|
||||
} catch (error) {
|
||||
// Ignore error if index already exists
|
||||
if (error.code === '42P07') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (error.code === '23505') {
|
||||
throw new IndexMetadataException(
|
||||
`Unique index creation failed because of unique constraint violation`,
|
||||
IndexMetadataExceptionCode.INDEX_CREATION_FAILED,
|
||||
{
|
||||
userFriendlyMessage: msg`Cannot enable uniqueness due to existing duplicate values. Please review and fix your data first (including soft deleted records).`,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private async dropIndex(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
indexName: string,
|
||||
) {
|
||||
try {
|
||||
await queryRunner.dropIndex(`${schemaName}.${tableName}`, indexName);
|
||||
} catch (error) {
|
||||
// Ignore error if index does not exist
|
||||
if (
|
||||
error.message ===
|
||||
`Supplied index ${indexName} was not found in table ${schemaName}.${tableName}`
|
||||
) {
|
||||
return;
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
private async createTable(
|
||||
queryRunner: PostgresQueryRunner,
|
||||
schemaName: string,
|
||||
tableName: string,
|
||||
columns?: WorkspaceMigrationColumnAction[],
|
||||
) {
|
||||
const tableColumns: TableColumn[] = [];
|
||||
|
||||
if (columns && columns.length > 0) {
|
||||
const createColumns = columns.filter(
|
||||
(column) => column.action === WorkspaceMigrationColumnActionType.CREATE,
|
||||
) as WorkspaceMigrationColumnCreate[];
|
||||
|
||||
for (const column of createColumns) {
|
||||
tableColumns.push(
|
||||
this.workspaceMigrationColumnService.createTableColumnFromMigration(
|
||||
tableName,
|
||||
column,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await queryRunner.createTable(
|
||||
new Table({
|
||||
name: tableName,
|
||||
schema: schemaName,
|
||||
columns: tableColumns.length > 0 ? tableColumns : tableDefaultColumns(),
|
||||
}),
|
||||
true,
|
||||
);
|
||||
|
||||
if (columns && columns.length > 0) {
|
||||
const nonCreateColumns = columns.filter(
|
||||
(column) => column.action !== WorkspaceMigrationColumnActionType.CREATE,
|
||||
);
|
||||
|
||||
if (nonCreateColumns.length > 0) {
|
||||
await this.workspaceMigrationColumnService.handleColumnChanges(
|
||||
queryRunner,
|
||||
schemaName,
|
||||
tableName,
|
||||
nonCreateColumns,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async renameTable(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
oldTableName: string,
|
||||
newTableName: string,
|
||||
) {
|
||||
await queryRunner.renameTable(
|
||||
`${schemaName}.${oldTableName}`,
|
||||
newTableName,
|
||||
);
|
||||
}
|
||||
|
||||
private async createForeignTable(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
name: string,
|
||||
foreignTable: WorkspaceMigrationForeignTable | undefined,
|
||||
) {
|
||||
if (!foreignTable) {
|
||||
return;
|
||||
}
|
||||
|
||||
const foreignTableColumns = foreignTable.columns
|
||||
.map(
|
||||
(column) =>
|
||||
`"${column.columnName}" ${column.columnType} OPTIONS (column_name '${column.distantColumnName}')`,
|
||||
)
|
||||
.join(', ');
|
||||
|
||||
const serverOptions = Object.entries(foreignTable.referencedTable)
|
||||
.map(([key, value]) => `${key} '${value}'`)
|
||||
.join(', ');
|
||||
|
||||
await queryRunner.query(
|
||||
`CREATE FOREIGN TABLE ${schemaName}."${name}" (${foreignTableColumns}) SERVER "${foreignTable.foreignDataWrapperId}" OPTIONS (${serverOptions})`,
|
||||
);
|
||||
|
||||
await queryRunner.query(`
|
||||
COMMENT ON FOREIGN TABLE "${schemaName}"."${name}" IS '@graphql({"primary_key_columns": ["id"], "totalCount": {"enabled": true}})';
|
||||
`);
|
||||
}
|
||||
|
||||
private async alterForeignTable(
|
||||
queryRunner: QueryRunner,
|
||||
schemaName: string,
|
||||
name: string,
|
||||
columns: WorkspaceMigrationColumnAction[] | undefined,
|
||||
) {
|
||||
const columnUpdatesQuery = columns
|
||||
?.map((column) => {
|
||||
switch (column.action) {
|
||||
case WorkspaceMigrationColumnActionType.DROP:
|
||||
return `DROP COLUMN "${column.columnName}"`;
|
||||
case WorkspaceMigrationColumnActionType.CREATE:
|
||||
return `ADD COLUMN "${column.columnName}" ${column.columnType}`;
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
})
|
||||
.filter(Boolean)
|
||||
.join(', ');
|
||||
|
||||
await queryRunner.query(
|
||||
`ALTER FOREIGN TABLE ${schemaName}."${name}" ${columnUpdatesQuery};`,
|
||||
);
|
||||
}
|
||||
}
|
||||
-79
@@ -1,79 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { FeatureFlagModule } from 'src/engine/core-modules/feature-flag/feature-flag.module';
|
||||
import { FlatFieldMetadataTypeValidatorService } from 'src/engine/metadata-modules/flat-field-metadata/services/flat-field-metadata-type-validator.service';
|
||||
import { WorkspaceMigrationV2AgentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/agent/workspace-migration-v2-agent-actions-builder.service';
|
||||
import { WorkspaceMigrationV2SkillActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/skill/workspace-migration-v2-skill-actions-builder.service';
|
||||
import { WorkspaceMigrationV2CronTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service';
|
||||
import { WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service';
|
||||
import { WorkspaceMigrationV2FieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/workspace-migration-v2-field-actions-builder.service';
|
||||
import { WorkspaceMigrationV2IndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/workspace-migration-v2-object-actions-builder.service';
|
||||
import { WorkspaceMigrationV2PageLayoutTabActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/page-layout-tab/workspace-migration-v2-page-layout-tab-actions-builder.service';
|
||||
import { WorkspaceMigrationV2PageLayoutWidgetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/page-layout-widget/workspace-migration-v2-page-layout-widget-actions-builder.service';
|
||||
import { WorkspaceMigrationV2PageLayoutActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/page-layout/workspace-migration-v2-page-layout-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RoleTargetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role-target/workspace-migration-v2-role-target-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RoleActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role/workspace-migration-v2-role-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RowLevelPermissionPredicateGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/row-level-permission-predicate-group/workspace-migration-v2-row-level-permission-predicate-group-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RowLevelPermissionPredicateActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/row-level-permission-predicate/workspace-migration-v2-row-level-permission-predicate-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewFilterActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter/workspace-migration-v2-view-filter-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewFilterGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter-group/workspace-migration-v2-view-filter-group-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-group/workspace-migration-v2-view-group-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service';
|
||||
import { WorkspaceMigrationBuilderValidatorsModule } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/validators/workspace-migration-builder-validators.module';
|
||||
|
||||
@Module({
|
||||
imports: [FeatureFlagModule, WorkspaceMigrationBuilderValidatorsModule],
|
||||
providers: [
|
||||
FlatFieldMetadataTypeValidatorService,
|
||||
WorkspaceMigrationV2ObjectActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewFieldActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewFilterActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewFilterGroupActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewGroupActionsBuilderService,
|
||||
WorkspaceMigrationV2IndexActionsBuilderService,
|
||||
WorkspaceMigrationV2ServerlessFunctionActionsBuilderService,
|
||||
WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2FieldActionsBuilderService,
|
||||
WorkspaceMigrationV2CronTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2RouteTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2RoleActionsBuilderService,
|
||||
WorkspaceMigrationV2RoleTargetActionsBuilderService,
|
||||
WorkspaceMigrationV2AgentActionsBuilderService,
|
||||
WorkspaceMigrationV2SkillActionsBuilderService,
|
||||
WorkspaceMigrationV2PageLayoutActionsBuilderService,
|
||||
WorkspaceMigrationV2PageLayoutWidgetActionsBuilderService,
|
||||
WorkspaceMigrationV2PageLayoutTabActionsBuilderService,
|
||||
WorkspaceMigrationV2RowLevelPermissionPredicateActionsBuilderService,
|
||||
WorkspaceMigrationV2RowLevelPermissionPredicateGroupActionsBuilderService,
|
||||
],
|
||||
exports: [
|
||||
WorkspaceMigrationV2ViewActionsBuilderService,
|
||||
WorkspaceMigrationV2IndexActionsBuilderService,
|
||||
WorkspaceMigrationV2ObjectActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewFieldActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewFilterActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewFilterGroupActionsBuilderService,
|
||||
WorkspaceMigrationV2ViewGroupActionsBuilderService,
|
||||
WorkspaceMigrationV2FieldActionsBuilderService,
|
||||
WorkspaceMigrationV2ServerlessFunctionActionsBuilderService,
|
||||
WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2CronTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2RouteTriggerActionsBuilderService,
|
||||
WorkspaceMigrationV2RoleActionsBuilderService,
|
||||
WorkspaceMigrationV2RoleTargetActionsBuilderService,
|
||||
WorkspaceMigrationV2AgentActionsBuilderService,
|
||||
WorkspaceMigrationV2SkillActionsBuilderService,
|
||||
WorkspaceMigrationV2PageLayoutActionsBuilderService,
|
||||
WorkspaceMigrationV2PageLayoutWidgetActionsBuilderService,
|
||||
WorkspaceMigrationV2PageLayoutTabActionsBuilderService,
|
||||
WorkspaceMigrationV2RowLevelPermissionPredicateActionsBuilderService,
|
||||
WorkspaceMigrationV2RowLevelPermissionPredicateGroupActionsBuilderService,
|
||||
FlatFieldMetadataTypeValidatorService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceMigrationBuilderV2Module {}
|
||||
-156
@@ -1,156 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceSchemaManagerModule } from 'src/engine/twenty-orm/workspace-schema-manager/workspace-schema-manager.module';
|
||||
import { CreateAgentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/agent/services/create-agent-action-handler.service';
|
||||
import { DeleteAgentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/agent/services/delete-agent-action-handler.service';
|
||||
import { UpdateAgentActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/agent/services/update-agent-action-handler.service';
|
||||
import { CreateSkillActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/skill/services/create-skill-action-handler.service';
|
||||
import { DeleteSkillActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/skill/services/delete-skill-action-handler.service';
|
||||
import { UpdateSkillActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/skill/services/update-skill-action-handler.service';
|
||||
import { CreateCronTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/cron-trigger/services/create-cron-trigger-action-handler.service';
|
||||
import { DeleteCronTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/cron-trigger/services/delete-cron-trigger-action-handler.service';
|
||||
import { UpdateCronTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/cron-trigger/services/update-cron-trigger-action-handler.service';
|
||||
import { CreateDatabaseEventTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/database-event-trigger/services/create-database-event-trigger-action-handler.service';
|
||||
import { DeleteDatabaseEventTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/database-event-trigger/services/delete-database-event-trigger-action-handler.service';
|
||||
import { UpdateDatabaseEventTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/database-event-trigger/services/update-database-event-trigger-action-handler.service';
|
||||
import { CreateFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/field/services/create-field-action-handler.service';
|
||||
import { DeleteFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/field/services/delete-field-action-handler.service';
|
||||
import { UpdateFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/field/services/update-field-action-handler.service';
|
||||
import { CreateIndexActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/index/services/create-index-action-handler.service';
|
||||
import { DeleteIndexActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/index/services/delete-index-action-handler.service';
|
||||
import { UpdateIndexActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/index/services/update-index-action-handler.service';
|
||||
import { CreateObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/create-object-action-handler.service';
|
||||
import { DeleteObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/delete-object-action-handler.service';
|
||||
import { UpdateObjectActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/object/services/update-object-action-handler.service';
|
||||
import { CreatePageLayoutTabActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout-tab/services/create-page-layout-tab-action-handler.service';
|
||||
import { DeletePageLayoutTabActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout-tab/services/delete-page-layout-tab-action-handler.service';
|
||||
import { UpdatePageLayoutTabActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout-tab/services/update-page-layout-tab-action-handler.service';
|
||||
import { CreatePageLayoutWidgetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout-widget/services/create-page-layout-widget-action-handler.service';
|
||||
import { DeletePageLayoutWidgetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout-widget/services/delete-page-layout-widget-action-handler.service';
|
||||
import { UpdatePageLayoutWidgetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout-widget/services/update-page-layout-widget-action-handler.service';
|
||||
import { CreatePageLayoutActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout/services/create-page-layout-action-handler.service';
|
||||
import { DeletePageLayoutActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout/services/delete-page-layout-action-handler.service';
|
||||
import { UpdatePageLayoutActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/page-layout/services/update-page-layout-action-handler.service';
|
||||
import { CreateRoleTargetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/role-target/services/create-role-target-action-handler.service';
|
||||
import { DeleteRoleTargetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/role-target/services/delete-role-target-action-handler.service';
|
||||
import { UpdateRoleTargetActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/role-target/services/update-role-target-action-handler.service';
|
||||
import { CreateRoleActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/role/services/create-role-action-handler.service';
|
||||
import { DeleteRoleActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/role/services/delete-role-action-handler.service';
|
||||
import { UpdateRoleActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/role/services/update-role-action-handler.service';
|
||||
import { CreateRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/create-route-trigger-action-handler.service';
|
||||
import { DeleteRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/delete-route-trigger-action-handler.service';
|
||||
import { UpdateRouteTriggerActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/route-trigger/services/update-route-trigger-action-handler.service';
|
||||
import { CreateRowLevelPermissionPredicateGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/row-level-permission-predicate-group/services/create-row-level-permission-predicate-group-action-handler.service';
|
||||
import { DeleteRowLevelPermissionPredicateGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/row-level-permission-predicate-group/services/delete-row-level-permission-predicate-group-action-handler.service';
|
||||
import { UpdateRowLevelPermissionPredicateGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/row-level-permission-predicate-group/services/update-row-level-permission-predicate-group-action-handler.service';
|
||||
import { CreateRowLevelPermissionPredicateActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/row-level-permission-predicate/services/create-row-level-permission-predicate-action-handler.service';
|
||||
import { DeleteRowLevelPermissionPredicateActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/row-level-permission-predicate/services/delete-row-level-permission-predicate-action-handler.service';
|
||||
import { UpdateRowLevelPermissionPredicateActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/row-level-permission-predicate/services/update-row-level-permission-predicate-action-handler.service';
|
||||
import { CreateServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/create-serverless-function-action-handler.service';
|
||||
import { DeleteServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/delete-serverless-function-action-handler.service';
|
||||
import { UpdateServerlessFunctionActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/serverless-function/services/update-serverless-function-action-handler.service';
|
||||
import { CreateViewFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-field/services/create-view-field-action-handler.service';
|
||||
import { DeleteViewFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-field/services/delete-view-field-action-handler.service';
|
||||
import { UpdateViewFieldActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-field/services/update-view-field-action-handler.service';
|
||||
import { CreateViewFilterActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-filter/services/create-view-filter-action-handler.service';
|
||||
import { DeleteViewFilterActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-filter/services/delete-view-filter-action-handler.service';
|
||||
import { UpdateViewFilterActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-filter/services/update-view-filter-action-handler.service';
|
||||
import { CreateViewFilterGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-filter-group/services/create-view-filter-group-action-handler.service';
|
||||
import { DeleteViewFilterGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-filter-group/services/delete-view-filter-group-action-handler.service';
|
||||
import { UpdateViewFilterGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-filter-group/services/update-view-filter-group-action-handler.service';
|
||||
import { CreateViewGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-group/services/create-view-group-action-handler.service';
|
||||
import { DeleteViewGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-group/services/delete-view-group-action-handler.service';
|
||||
import { UpdateViewGroupActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view-group/services/update-view-group-action-handler.service';
|
||||
import { CreateViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view/services/create-view-action-handler.service';
|
||||
import { DeleteViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view/services/delete-view-action-handler.service';
|
||||
import { UpdateViewActionHandlerService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/action-handlers/view/services/update-view-action-handler.service';
|
||||
|
||||
@Module({
|
||||
imports: [WorkspaceSchemaManagerModule],
|
||||
providers: [
|
||||
CreateFieldActionHandlerService,
|
||||
UpdateFieldActionHandlerService,
|
||||
DeleteFieldActionHandlerService,
|
||||
|
||||
CreateObjectActionHandlerService,
|
||||
UpdateObjectActionHandlerService,
|
||||
DeleteObjectActionHandlerService,
|
||||
|
||||
CreateIndexActionHandlerService,
|
||||
UpdateIndexActionHandlerService,
|
||||
DeleteIndexActionHandlerService,
|
||||
|
||||
CreateViewActionHandlerService,
|
||||
UpdateViewActionHandlerService,
|
||||
DeleteViewActionHandlerService,
|
||||
|
||||
CreateViewFieldActionHandlerService,
|
||||
UpdateViewFieldActionHandlerService,
|
||||
DeleteViewFieldActionHandlerService,
|
||||
|
||||
CreateViewFilterActionHandlerService,
|
||||
UpdateViewFilterActionHandlerService,
|
||||
DeleteViewFilterActionHandlerService,
|
||||
|
||||
CreateViewFilterGroupActionHandlerService,
|
||||
UpdateViewFilterGroupActionHandlerService,
|
||||
DeleteViewFilterGroupActionHandlerService,
|
||||
|
||||
CreateViewGroupActionHandlerService,
|
||||
UpdateViewGroupActionHandlerService,
|
||||
DeleteViewGroupActionHandlerService,
|
||||
|
||||
CreateServerlessFunctionActionHandlerService,
|
||||
DeleteServerlessFunctionActionHandlerService,
|
||||
UpdateServerlessFunctionActionHandlerService,
|
||||
|
||||
CreateDatabaseEventTriggerActionHandlerService,
|
||||
DeleteDatabaseEventTriggerActionHandlerService,
|
||||
UpdateDatabaseEventTriggerActionHandlerService,
|
||||
|
||||
CreateCronTriggerActionHandlerService,
|
||||
DeleteCronTriggerActionHandlerService,
|
||||
UpdateCronTriggerActionHandlerService,
|
||||
|
||||
CreateRouteTriggerActionHandlerService,
|
||||
DeleteRouteTriggerActionHandlerService,
|
||||
UpdateRouteTriggerActionHandlerService,
|
||||
|
||||
CreateRoleActionHandlerService,
|
||||
UpdateRoleActionHandlerService,
|
||||
DeleteRoleActionHandlerService,
|
||||
|
||||
CreateRoleTargetActionHandlerService,
|
||||
DeleteRoleTargetActionHandlerService,
|
||||
UpdateRoleTargetActionHandlerService,
|
||||
|
||||
CreateAgentActionHandlerService,
|
||||
UpdateAgentActionHandlerService,
|
||||
DeleteAgentActionHandlerService,
|
||||
|
||||
CreateSkillActionHandlerService,
|
||||
UpdateSkillActionHandlerService,
|
||||
DeleteSkillActionHandlerService,
|
||||
|
||||
CreatePageLayoutActionHandlerService,
|
||||
UpdatePageLayoutActionHandlerService,
|
||||
DeletePageLayoutActionHandlerService,
|
||||
|
||||
CreatePageLayoutWidgetActionHandlerService,
|
||||
UpdatePageLayoutWidgetActionHandlerService,
|
||||
DeletePageLayoutWidgetActionHandlerService,
|
||||
|
||||
CreatePageLayoutTabActionHandlerService,
|
||||
UpdatePageLayoutTabActionHandlerService,
|
||||
DeletePageLayoutTabActionHandlerService,
|
||||
|
||||
CreateRowLevelPermissionPredicateActionHandlerService,
|
||||
UpdateRowLevelPermissionPredicateActionHandlerService,
|
||||
DeleteRowLevelPermissionPredicateActionHandlerService,
|
||||
|
||||
CreateRowLevelPermissionPredicateGroupActionHandlerService,
|
||||
UpdateRowLevelPermissionPredicateGroupActionHandlerService,
|
||||
DeleteRowLevelPermissionPredicateGroupActionHandlerService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceSchemaMigrationRunnerActionHandlersModule {}
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
|
||||
import { WorkspaceCacheModule } from 'src/engine/workspace-cache/workspace-cache.module';
|
||||
import { WorkspaceMigrationBuildOrchestratorService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-validate-build-and-run-service';
|
||||
import { WorkspaceMigrationBuilderV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/workspace-migration-builder-v2.module';
|
||||
import { WorkspaceMigrationRunnerV2Module } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/workspace-migration-runner-v2.module';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
WorkspaceMigrationBuilderV2Module,
|
||||
WorkspaceMigrationRunnerV2Module,
|
||||
WorkspaceCacheModule,
|
||||
],
|
||||
providers: [
|
||||
WorkspaceMigrationValidateBuildAndRunService,
|
||||
WorkspaceMigrationBuildOrchestratorService,
|
||||
],
|
||||
exports: [
|
||||
WorkspaceMigrationValidateBuildAndRunService,
|
||||
WorkspaceMigrationBuildOrchestratorService,
|
||||
],
|
||||
})
|
||||
export class WorkspaceMigrationV2Module {}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
|
||||
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { getMetadataEmptyWorkspaceMigrationActionRecord } from 'src/engine/workspace-manager/workspace-migration-v2/utils/get-metadata-empty-workspace-migration-action-record.util';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
import { getMetadataEmptyWorkspaceMigrationActionRecord } from 'src/engine/workspace-manager/workspace-migration/utils/get-metadata-empty-workspace-migration-action-record.util';
|
||||
|
||||
export const createEmptyOrchestratorActionsReport =
|
||||
(): OrchestratorActionsReport =>
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
|
||||
|
||||
import { type OrchestratorFailureReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { type OrchestratorFailureReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
|
||||
export const EMPTY_ORCHESTRATOR_FAILURE_REPORT =
|
||||
(): OrchestratorFailureReport =>
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export const HELPER_AGENT = {
|
||||
standardId: '20202020-0002-0001-0001-000000000004',
|
||||
} as const;
|
||||
+3
-3
@@ -1,11 +1,11 @@
|
||||
import { type WorkspaceMigrationOrchestratorFailedResult } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { type WorkspaceMigrationOrchestratorFailedResult } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
|
||||
export class WorkspaceMigrationBuilderExceptionV2 extends Error {
|
||||
export class WorkspaceMigrationBuilderException extends Error {
|
||||
constructor(
|
||||
public readonly failedWorkspaceMigrationBuildResult: WorkspaceMigrationOrchestratorFailedResult,
|
||||
message = 'Workspace migration builder failed',
|
||||
) {
|
||||
super(message);
|
||||
this.name = 'WorkspaceMigrationBuilderExceptionV2';
|
||||
this.name = 'WorkspaceMigrationBuilderException';
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
import { type I18n } from '@lingui/core';
|
||||
import { type MetadataValidationErrorResponse } from 'twenty-shared/metadata';
|
||||
|
||||
import { type WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { translateOrchestratorFailureReportErrors } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/utils/translate-orchestrator-failure-report-errors.util';
|
||||
import { type WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { translateOrchestratorFailureReportErrors } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/translate-orchestrator-failure-report-errors.util';
|
||||
|
||||
export const fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError =
|
||||
(
|
||||
workspaceMigrationBuilderException: WorkspaceMigrationBuilderExceptionV2,
|
||||
workspaceMigrationBuilderException: WorkspaceMigrationBuilderException,
|
||||
i18n: I18n,
|
||||
): MetadataValidationErrorResponse => {
|
||||
const translatedReport = translateOrchestratorFailureReportErrors(
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
import { type I18n, type MessageDescriptor } from '@lingui/core';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type OrchestratorFailureReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { type FlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
import { type OrchestratorFailureReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
import { type FlatEntityValidationError } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
|
||||
|
||||
const isMessageDescriptor = (obj: unknown): obj is MessageDescriptor =>
|
||||
isDefined(obj) &&
|
||||
+5
-5
@@ -1,17 +1,17 @@
|
||||
import { type I18n } from '@lingui/core';
|
||||
import { msg } from '@lingui/core/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { ALL_METADATA_NAME } from 'twenty-shared/metadata';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import {
|
||||
BaseGraphQLError,
|
||||
ErrorCode,
|
||||
} from 'src/engine/core-modules/graphql/utils/graphql-errors.util';
|
||||
import { type WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/utils/from-workspace-migration-builder-exception-to-metadata-validation-response-error.util';
|
||||
import { type WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { fromWorkspaceMigrationBuilderExceptionToMetadataValidationResponseError } from 'src/engine/workspace-manager/workspace-migration/interceptors/utils/from-workspace-migration-builder-exception-to-metadata-validation-response-error.util';
|
||||
|
||||
export const workspaceMigrationBuilderExceptionV2Formatter = (
|
||||
error: WorkspaceMigrationBuilderExceptionV2,
|
||||
export const workspaceMigrationBuilderExceptionFormatter = (
|
||||
error: WorkspaceMigrationBuilderException,
|
||||
i18n: I18n,
|
||||
) => {
|
||||
const { errors, summary } =
|
||||
+4
-4
@@ -10,8 +10,8 @@ import { type Observable, catchError } from 'rxjs';
|
||||
import { SOURCE_LOCALE } from 'twenty-shared/translations';
|
||||
|
||||
import { I18nService } from 'src/engine/core-modules/i18n/i18n.service';
|
||||
import { WorkspaceMigrationBuilderExceptionV2 } from 'src/engine/workspace-manager/workspace-migration-v2/exceptions/workspace-migration-builder-exception-v2';
|
||||
import { workspaceMigrationBuilderExceptionV2Formatter } from 'src/engine/workspace-manager/workspace-migration-v2/interceptors/workspace-migration-builder-exception-v2-formatter';
|
||||
import { WorkspaceMigrationBuilderException } from 'src/engine/workspace-manager/workspace-migration/exceptions/workspace-migration-builder-exception';
|
||||
import { workspaceMigrationBuilderExceptionFormatter } from 'src/engine/workspace-manager/workspace-migration/interceptors/workspace-migration-builder-exception-formatter';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor
|
||||
@@ -27,8 +27,8 @@ export class WorkspaceMigrationBuilderGraphqlApiExceptionInterceptor
|
||||
|
||||
return next.handle().pipe(
|
||||
catchError((error) => {
|
||||
if (error instanceof WorkspaceMigrationBuilderExceptionV2) {
|
||||
workspaceMigrationBuilderExceptionV2Formatter(error, i18n);
|
||||
if (error instanceof WorkspaceMigrationBuilderException) {
|
||||
workspaceMigrationBuilderExceptionFormatter(error, i18n);
|
||||
}
|
||||
|
||||
throw error;
|
||||
+67
-67
@@ -6,60 +6,60 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
import { createEmptyAllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/constant/create-empty-all-flat-entity-maps.constant';
|
||||
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
|
||||
import { type MetadataFlatEntityAndRelatedFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/metadata-related-types.type';
|
||||
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
|
||||
import { EMPTY_ORCHESTRATOR_FAILURE_REPORT } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-failure-report.constant';
|
||||
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
|
||||
import { EMPTY_ORCHESTRATOR_FAILURE_REPORT } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-failure-report.constant';
|
||||
import {
|
||||
type WorkspaceMigrationOrchestratorBuildArgs,
|
||||
type WorkspaceMigrationOrchestratorFailedResult,
|
||||
type WorkspaceMigrationOrchestratorSuccessfulResult,
|
||||
} from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { aggregateOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/utils/aggregate-orchestrator-actions-report.util';
|
||||
import { WorkspaceMigrationV2AgentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/agent/workspace-migration-v2-agent-actions-builder.service';
|
||||
import { WorkspaceMigrationV2CronTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/cron-trigger/workspace-migration-v2-cron-trigger-action-builder.service';
|
||||
import { WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/database-event-trigger/workspace-migration-v2-database-event-trigger-actions-builder.service';
|
||||
import { WorkspaceMigrationV2FieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/workspace-migration-v2-field-actions-builder.service';
|
||||
import { WorkspaceMigrationV2IndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/index/workspace-migration-v2-index-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/workspace-migration-v2-object-actions-builder.service';
|
||||
import { WorkspaceMigrationV2PageLayoutTabActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/page-layout-tab/workspace-migration-v2-page-layout-tab-actions-builder.service';
|
||||
import { WorkspaceMigrationV2PageLayoutWidgetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/page-layout-widget/workspace-migration-v2-page-layout-widget-actions-builder.service';
|
||||
import { WorkspaceMigrationV2PageLayoutActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/page-layout/workspace-migration-v2-page-layout-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RoleTargetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role-target/workspace-migration-v2-role-target-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RoleActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/role/workspace-migration-v2-role-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/route-trigger/workspace-migration-v2-route-trigger-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RowLevelPermissionPredicateGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/row-level-permission-predicate-group/workspace-migration-v2-row-level-permission-predicate-group-actions-builder.service';
|
||||
import { WorkspaceMigrationV2RowLevelPermissionPredicateActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/row-level-permission-predicate/workspace-migration-v2-row-level-permission-predicate-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/serverless-function/workspace-migration-v2-serverless-function-actions-builder.service';
|
||||
import { WorkspaceMigrationV2SkillActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/skill/workspace-migration-v2-skill-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-field/workspace-migration-v2-view-field-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewFilterGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter-group/workspace-migration-v2-view-filter-group-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewFilterActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-filter/workspace-migration-v2-view-filter-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view-group/workspace-migration-v2-view-group-actions-builder.service';
|
||||
import { WorkspaceMigrationV2ViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/view/workspace-migration-v2-view-actions-builder.service';
|
||||
} from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
import { aggregateOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report.util';
|
||||
import { WorkspaceMigrationAgentActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/agent/workspace-migration-agent-actions-builder.service';
|
||||
import { WorkspaceMigrationCronTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/cron-trigger/workspace-migration-cron-trigger-action-builder.service';
|
||||
import { WorkspaceMigrationDatabaseEventTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/database-event-trigger/workspace-migration-database-event-trigger-actions-builder.service';
|
||||
import { WorkspaceMigrationFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/workspace-migration-field-actions-builder.service';
|
||||
import { WorkspaceMigrationIndexActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/index/workspace-migration-index-actions-builder.service';
|
||||
import { WorkspaceMigrationObjectActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/workspace-migration-object-actions-builder.service';
|
||||
import { WorkspaceMigrationPageLayoutTabActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-tab/workspace-migration-page-layout-tab-actions-builder.service';
|
||||
import { WorkspaceMigrationPageLayoutWidgetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout-widget/workspace-migration-page-layout-widget-actions-builder.service';
|
||||
import { WorkspaceMigrationPageLayoutActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/page-layout/workspace-migration-page-layout-actions-builder.service';
|
||||
import { WorkspaceMigrationRoleTargetActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role-target/workspace-migration-role-target-actions-builder.service';
|
||||
import { WorkspaceMigrationRoleActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/role/workspace-migration-role-actions-builder.service';
|
||||
import { WorkspaceMigrationRouteTriggerActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/route-trigger/workspace-migration-route-trigger-actions-builder.service';
|
||||
import { WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate-group/workspace-migration-row-level-permission-predicate-group-actions-builder.service';
|
||||
import { WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/row-level-permission-predicate/workspace-migration-row-level-permission-predicate-actions-builder.service';
|
||||
import { WorkspaceMigrationServerlessFunctionActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/serverless-function/workspace-migration-serverless-function-actions-builder.service';
|
||||
import { WorkspaceMigrationSkillActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/skill/workspace-migration-skill-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFieldActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-field/workspace-migration-view-field-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFilterGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter-group/workspace-migration-view-filter-group-actions-builder.service';
|
||||
import { WorkspaceMigrationViewFilterActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-filter/workspace-migration-view-filter-actions-builder.service';
|
||||
import { WorkspaceMigrationViewGroupActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view-group/workspace-migration-view-group-actions-builder.service';
|
||||
import { WorkspaceMigrationViewActionsBuilderService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/view/workspace-migration-view-actions-builder.service';
|
||||
|
||||
@Injectable()
|
||||
export class WorkspaceMigrationBuildOrchestratorService {
|
||||
constructor(
|
||||
private readonly workspaceMigrationV2ObjectActionsBuilderService: WorkspaceMigrationV2ObjectActionsBuilderService,
|
||||
private readonly workspaceMigrationV2IndexActionsBuilderService: WorkspaceMigrationV2IndexActionsBuilderService,
|
||||
private readonly workspaceMigrationV2ViewActionsBuilderService: WorkspaceMigrationV2ViewActionsBuilderService,
|
||||
private readonly workspaceMigrationV2ViewFieldActionsBuilderService: WorkspaceMigrationV2ViewFieldActionsBuilderService,
|
||||
private readonly workspaceMigrationV2ViewFilterActionsBuilderService: WorkspaceMigrationV2ViewFilterActionsBuilderService,
|
||||
private readonly workspaceMigrationV2ViewFilterGroupActionsBuilderService: WorkspaceMigrationV2ViewFilterGroupActionsBuilderService,
|
||||
private readonly workspaceMigrationV2ViewGroupActionsBuilderService: WorkspaceMigrationV2ViewGroupActionsBuilderService,
|
||||
private readonly workspaceMigrationV2ServerlessFunctionActionsBuilderService: WorkspaceMigrationV2ServerlessFunctionActionsBuilderService,
|
||||
private readonly workspaceMigrationV2DatabaseEventTriggerActionsBuilderService: WorkspaceMigrationV2DatabaseEventTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationV2CronTriggerActionsBuilderService: WorkspaceMigrationV2CronTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationV2RouteTriggerActionsBuilderService: WorkspaceMigrationV2RouteTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationV2RoleTargetActionsBuilderService: WorkspaceMigrationV2RoleTargetActionsBuilderService,
|
||||
private readonly workspaceMigrationV2FieldActionsBuilderService: WorkspaceMigrationV2FieldActionsBuilderService,
|
||||
private readonly workspaceMigrationV2RoleActionsBuilderService: WorkspaceMigrationV2RoleActionsBuilderService,
|
||||
private readonly workspaceMigrationV2AgentActionsBuilderService: WorkspaceMigrationV2AgentActionsBuilderService,
|
||||
private readonly workspaceMigrationV2SkillActionsBuilderService: WorkspaceMigrationV2SkillActionsBuilderService,
|
||||
private readonly workspaceMigrationV2PageLayoutActionsBuilderService: WorkspaceMigrationV2PageLayoutActionsBuilderService,
|
||||
private readonly workspaceMigrationV2PageLayoutWidgetActionsBuilderService: WorkspaceMigrationV2PageLayoutWidgetActionsBuilderService,
|
||||
private readonly workspaceMigrationV2PageLayoutTabActionsBuilderService: WorkspaceMigrationV2PageLayoutTabActionsBuilderService,
|
||||
private readonly workspaceMigrationV2RowLevelPermissionPredicateActionsBuilderService: WorkspaceMigrationV2RowLevelPermissionPredicateActionsBuilderService,
|
||||
private readonly workspaceMigrationV2RowLevelPermissionPredicateGroupActionsBuilderService: WorkspaceMigrationV2RowLevelPermissionPredicateGroupActionsBuilderService,
|
||||
private readonly workspaceMigrationObjectActionsBuilderService: WorkspaceMigrationObjectActionsBuilderService,
|
||||
private readonly workspaceMigrationIndexActionsBuilderService: WorkspaceMigrationIndexActionsBuilderService,
|
||||
private readonly workspaceMigrationViewActionsBuilderService: WorkspaceMigrationViewActionsBuilderService,
|
||||
private readonly workspaceMigrationViewFieldActionsBuilderService: WorkspaceMigrationViewFieldActionsBuilderService,
|
||||
private readonly workspaceMigrationViewFilterActionsBuilderService: WorkspaceMigrationViewFilterActionsBuilderService,
|
||||
private readonly workspaceMigrationViewFilterGroupActionsBuilderService: WorkspaceMigrationViewFilterGroupActionsBuilderService,
|
||||
private readonly workspaceMigrationViewGroupActionsBuilderService: WorkspaceMigrationViewGroupActionsBuilderService,
|
||||
private readonly workspaceMigrationServerlessFunctionActionsBuilderService: WorkspaceMigrationServerlessFunctionActionsBuilderService,
|
||||
private readonly workspaceMigrationDatabaseEventTriggerActionsBuilderService: WorkspaceMigrationDatabaseEventTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationCronTriggerActionsBuilderService: WorkspaceMigrationCronTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationRouteTriggerActionsBuilderService: WorkspaceMigrationRouteTriggerActionsBuilderService,
|
||||
private readonly workspaceMigrationRoleTargetActionsBuilderService: WorkspaceMigrationRoleTargetActionsBuilderService,
|
||||
private readonly workspaceMigrationFieldActionsBuilderService: WorkspaceMigrationFieldActionsBuilderService,
|
||||
private readonly workspaceMigrationRoleActionsBuilderService: WorkspaceMigrationRoleActionsBuilderService,
|
||||
private readonly workspaceMigrationAgentActionsBuilderService: WorkspaceMigrationAgentActionsBuilderService,
|
||||
private readonly workspaceMigrationSkillActionsBuilderService: WorkspaceMigrationSkillActionsBuilderService,
|
||||
private readonly workspaceMigrationPageLayoutActionsBuilderService: WorkspaceMigrationPageLayoutActionsBuilderService,
|
||||
private readonly workspaceMigrationPageLayoutWidgetActionsBuilderService: WorkspaceMigrationPageLayoutWidgetActionsBuilderService,
|
||||
private readonly workspaceMigrationPageLayoutTabActionsBuilderService: WorkspaceMigrationPageLayoutTabActionsBuilderService,
|
||||
private readonly workspaceMigrationRowLevelPermissionPredicateActionsBuilderService: WorkspaceMigrationRowLevelPermissionPredicateActionsBuilderService,
|
||||
private readonly workspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderService: WorkspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderService,
|
||||
) {}
|
||||
|
||||
private setupOptimisticCache({
|
||||
@@ -166,7 +166,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
flatObjectMetadataMaps;
|
||||
|
||||
const objectResult =
|
||||
await this.workspaceMigrationV2ObjectActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationObjectActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
buildOptions,
|
||||
@@ -220,7 +220,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
const { from: fromFlatFieldMetadataMaps, to: toFlatFieldMetadataMaps } =
|
||||
flatFieldMetadataMaps;
|
||||
const fieldResult =
|
||||
await this.workspaceMigrationV2FieldActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationFieldActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatFieldMetadataMaps,
|
||||
@@ -252,7 +252,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
if (isDefined(flatIndexMaps)) {
|
||||
const { from: fromFlatIndexMaps, to: toFlatIndexMaps } = flatIndexMaps;
|
||||
const indexResult =
|
||||
await this.workspaceMigrationV2IndexActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationIndexActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatIndexMaps,
|
||||
@@ -286,7 +286,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
if (isDefined(flatViewMaps)) {
|
||||
const { from: fromFlatViewMaps, to: toFlatViewMaps } = flatViewMaps;
|
||||
const viewResult =
|
||||
await this.workspaceMigrationV2ViewActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationViewActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
dependencyOptimisticFlatEntityMaps: {
|
||||
@@ -321,7 +321,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
const { from: fromFlatViewFieldMaps, to: toFlatViewFieldMaps } =
|
||||
flatViewFieldMaps;
|
||||
const viewFieldResult =
|
||||
await this.workspaceMigrationV2ViewFieldActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationViewFieldActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatViewFieldMaps,
|
||||
@@ -360,7 +360,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
} = flatViewFilterGroupMaps;
|
||||
|
||||
const viewFilterGroupResult =
|
||||
await this.workspaceMigrationV2ViewFilterGroupActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationViewFilterGroupActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatViewFilterGroupMaps,
|
||||
@@ -395,7 +395,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
const { from: fromFlatViewFilterMaps, to: toFlatViewFilterMaps } =
|
||||
flatViewFilterMaps;
|
||||
const viewFilterResult =
|
||||
await this.workspaceMigrationV2ViewFilterActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationViewFilterActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatViewFilterMaps,
|
||||
@@ -431,7 +431,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
const { from: fromFlatViewGroupMaps, to: toFlatViewGroupMaps } =
|
||||
flatViewGroupMaps;
|
||||
const viewGroupResult =
|
||||
await this.workspaceMigrationV2ViewGroupActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationViewGroupActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatViewGroupMaps,
|
||||
@@ -467,7 +467,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
to: toFlatRowLevelPermissionPredicateGroupMaps,
|
||||
} = flatRowLevelPermissionPredicateGroupMaps;
|
||||
const rowLevelPermissionPredicateGroupResult =
|
||||
await this.workspaceMigrationV2RowLevelPermissionPredicateGroupActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationRowLevelPermissionPredicateGroupActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatRowLevelPermissionPredicateGroupMaps,
|
||||
@@ -504,7 +504,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
to: toFlatRowLevelPermissionPredicateMaps,
|
||||
} = flatRowLevelPermissionPredicateMaps;
|
||||
const rowLevelPermissionPredicateResult =
|
||||
await this.workspaceMigrationV2RowLevelPermissionPredicateActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationRowLevelPermissionPredicateActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatRowLevelPermissionPredicateMaps,
|
||||
@@ -548,7 +548,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
} = flatServerlessFunctionMaps;
|
||||
|
||||
const serverlessFunctionResult =
|
||||
await this.workspaceMigrationV2ServerlessFunctionActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationServerlessFunctionActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatServerlessFunctionMaps,
|
||||
@@ -584,7 +584,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
} = flatDatabaseEventTriggerMaps;
|
||||
|
||||
const databaseEventTriggerResult =
|
||||
await this.workspaceMigrationV2DatabaseEventTriggerActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationDatabaseEventTriggerActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatDatabaseEventTriggerMaps,
|
||||
@@ -621,7 +621,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
flatCronTriggerMaps;
|
||||
|
||||
const cronTriggerResult =
|
||||
await this.workspaceMigrationV2CronTriggerActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationCronTriggerActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatCronTriggerMaps,
|
||||
@@ -655,7 +655,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
flatRouteTriggerMaps;
|
||||
|
||||
const routeTriggerResult =
|
||||
await this.workspaceMigrationV2RouteTriggerActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationRouteTriggerActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatRouteTriggerMaps,
|
||||
@@ -690,7 +690,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
const { from: fromFlatRoleMaps, to: toFlatRoleMaps } = flatRoleMaps;
|
||||
|
||||
const roleResult =
|
||||
await this.workspaceMigrationV2RoleActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationRoleActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatRoleMaps,
|
||||
@@ -721,7 +721,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
flatRoleTargetMaps;
|
||||
|
||||
const roleTargetResult =
|
||||
await this.workspaceMigrationV2RoleTargetActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationRoleTargetActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatRoleTargetMaps,
|
||||
@@ -754,7 +754,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
const { from: fromFlatAgentMaps, to: toFlatAgentMaps } = flatAgentMaps;
|
||||
|
||||
const agentResult =
|
||||
await this.workspaceMigrationV2AgentActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationAgentActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatAgentMaps,
|
||||
@@ -786,7 +786,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
const { from: fromFlatSkillMaps, to: toFlatSkillMaps } = flatSkillMaps;
|
||||
|
||||
const skillResult =
|
||||
await this.workspaceMigrationV2SkillActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationSkillActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatSkillMaps,
|
||||
@@ -817,7 +817,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
flatPageLayoutMaps;
|
||||
|
||||
const pageLayoutResult =
|
||||
await this.workspaceMigrationV2PageLayoutActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationPageLayoutActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatPageLayoutMaps,
|
||||
@@ -854,7 +854,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
flatPageLayoutTabMaps;
|
||||
|
||||
const pageLayoutTabResult =
|
||||
await this.workspaceMigrationV2PageLayoutTabActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationPageLayoutTabActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatPageLayoutTabMaps,
|
||||
@@ -892,7 +892,7 @@ export class WorkspaceMigrationBuildOrchestratorService {
|
||||
} = flatPageLayoutWidgetMaps;
|
||||
|
||||
const pageLayoutWidgetResult =
|
||||
await this.workspaceMigrationV2PageLayoutWidgetActionsBuilderService.validateAndBuild(
|
||||
await this.workspaceMigrationPageLayoutWidgetActionsBuilderService.validateAndBuild(
|
||||
{
|
||||
additionalCacheDataMaps,
|
||||
from: fromFlatPageLayoutWidgetMaps,
|
||||
+9
-9
@@ -13,17 +13,17 @@ import { FlatEntityToCreateDeleteUpdate } from 'src/engine/metadata-modules/flat
|
||||
import { computeFlatEntityMapsFromTo } from 'src/engine/metadata-modules/flat-entity/utils/compute-flat-entity-maps-from-to.util';
|
||||
import { getMetadataFlatEntityMapsKey } from 'src/engine/metadata-modules/flat-entity/utils/get-metadata-flat-entity-maps-key.util';
|
||||
import { WorkspaceCacheService } from 'src/engine/workspace-cache/services/workspace-cache.service';
|
||||
import { WORKSPACE_MIGRATION_ADDITIONAL_CACHE_DATA_MAPS_KEY } from 'src/engine/workspace-manager/workspace-migration-v2/constant/workspace-migration-additional-cache-data-maps-key.constant';
|
||||
import { WorkspaceMigrationBuildOrchestratorService } from 'src/engine/workspace-manager/workspace-migration-v2/services/workspace-migration-build-orchestrator.service';
|
||||
import { WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-builder-additional-cache-data-maps.type';
|
||||
import { WorkspaceMigrationV2Exception } from 'src/engine/workspace-manager/workspace-migration.exception';
|
||||
import { WORKSPACE_MIGRATION_ADDITIONAL_CACHE_DATA_MAPS_KEY } from 'src/engine/workspace-manager/workspace-migration/constant/workspace-migration-additional-cache-data-maps-key.constant';
|
||||
import { WorkspaceMigrationBuildOrchestratorService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-build-orchestrator.service';
|
||||
import { WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-builder-additional-cache-data-maps.type';
|
||||
import {
|
||||
FromToAllFlatEntityMaps,
|
||||
WorkspaceMigrationOrchestratorBuildArgs,
|
||||
WorkspaceMigrationOrchestratorFailedResult,
|
||||
} from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { InferDeletionFromMissingEntities } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/infer-deletion-from-missing-entities.type';
|
||||
import { WorkspaceMigrationRunnerV2Service } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-runner-v2/services/workspace-migration-runner-v2.service';
|
||||
import { WorkspaceMigrationV2Exception } from 'src/engine/workspace-manager/workspace-migration.exception';
|
||||
} from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
import { InferDeletionFromMissingEntities } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/infer-deletion-from-missing-entities.type';
|
||||
import { WorkspaceMigrationRunnerService } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-runner/services/workspace-migration-runner.service';
|
||||
|
||||
type ValidateBuildAndRunWorkspaceMigrationFromMatriceArgs = {
|
||||
workspaceId: string;
|
||||
@@ -40,7 +40,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
|
||||
);
|
||||
|
||||
constructor(
|
||||
private readonly workspaceMigrationRunnerV2Service: WorkspaceMigrationRunnerV2Service,
|
||||
private readonly workspaceMigrationRunnerService: WorkspaceMigrationRunnerService,
|
||||
private readonly workspaceMigrationBuildOrchestratorService: WorkspaceMigrationBuildOrchestratorService,
|
||||
private readonly workspaceCacheService: WorkspaceCacheService,
|
||||
) {}
|
||||
@@ -196,7 +196,7 @@ export class WorkspaceMigrationValidateBuildAndRunService {
|
||||
return;
|
||||
}
|
||||
|
||||
await this.workspaceMigrationRunnerV2Service
|
||||
await this.workspaceMigrationRunnerService
|
||||
.run(validateAndBuildResult.workspaceMigration)
|
||||
.catch((error) => {
|
||||
this.logger.error(error);
|
||||
+1
-1
@@ -2,4 +2,4 @@
|
||||
* Wrapper type used to circumvent ESM modules circular dependency issue
|
||||
* caused by reflection metadata saving the type of the property.
|
||||
*/
|
||||
export type Relation<T> = T;
|
||||
export type EntityRelation<T> = T;
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { type FlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/flat-entity-maps.type';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
|
||||
export type AggregateOrchestratorActionsReportArgs = {
|
||||
orchestratorActionsReport: OrchestratorActionsReport;
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type AdditionalCacheDataMaps } from 'src/engine/workspace-cache/types/workspace-cache-key.type';
|
||||
import { type WORKSPACE_MIGRATION_ADDITIONAL_CACHE_DATA_MAPS_KEY } from 'src/engine/workspace-manager/workspace-migration-v2/constant/workspace-migration-additional-cache-data-maps-key.constant';
|
||||
import { type WORKSPACE_MIGRATION_ADDITIONAL_CACHE_DATA_MAPS_KEY } from 'src/engine/workspace-manager/workspace-migration/constant/workspace-migration-additional-cache-data-maps-key.constant';
|
||||
|
||||
export type WorkspaceMigrationBuilderAdditionalCacheDataMaps = Pick<
|
||||
AdditionalCacheDataMaps,
|
||||
+6
-6
@@ -3,13 +3,13 @@ import { type FromTo } from 'twenty-shared/types';
|
||||
|
||||
import { type AllFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/types/all-flat-entity-maps.type';
|
||||
import {
|
||||
type WorkspaceMigrationActionType,
|
||||
type MetadataWorkspaceMigrationActionsRecord,
|
||||
type WorkspaceMigrationActionType,
|
||||
} from 'src/engine/metadata-modules/flat-entity/types/metadata-workspace-migration-action.type';
|
||||
import { type WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-builder-additional-cache-data-maps.type';
|
||||
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/types/failed-flat-entity-validation.type';
|
||||
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-builder-options.type';
|
||||
import { type WorkspaceMigrationV2 } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-v2';
|
||||
import { type WorkspaceMigrationBuilderAdditionalCacheDataMaps } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-builder-additional-cache-data-maps.type';
|
||||
import { type FailedFlatEntityValidation } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/types/failed-flat-entity-validation.type';
|
||||
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
|
||||
import { type WorkspaceMigration } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration';
|
||||
|
||||
export type FromToAllFlatEntityMaps = {
|
||||
[P in keyof AllFlatEntityMaps]?: FromTo<AllFlatEntityMaps[P]>;
|
||||
@@ -41,5 +41,5 @@ export type WorkspaceMigrationOrchestratorFailedResult = {
|
||||
|
||||
export type WorkspaceMigrationOrchestratorSuccessfulResult = {
|
||||
status: 'success';
|
||||
workspaceMigration: WorkspaceMigrationV2;
|
||||
workspaceMigration: WorkspaceMigration;
|
||||
};
|
||||
+5
-5
@@ -6,11 +6,11 @@ import { FieldMetadataType } from 'twenty-shared/types';
|
||||
|
||||
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
|
||||
import { getFlatObjectMetadataMock } from 'src/engine/metadata-modules/flat-object-metadata/__mocks__/get-flat-object-metadata.mock';
|
||||
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions } from 'src/engine/workspace-manager/workspace-migration-v2/utils/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util';
|
||||
import { type CreateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
|
||||
import { type CreateObjectAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/types/workspace-migration-object-action-v2';
|
||||
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
import { aggregateOrchestratorActionsReportCreateObjectAndCreateFieldActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report-create-object-and-create-field-actions.util';
|
||||
import { type CreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
|
||||
import { type CreateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
|
||||
|
||||
type CreateAggregationTestCase = EachTestingContext<{
|
||||
input: OrchestratorActionsReport;
|
||||
+5
-5
@@ -3,11 +3,11 @@ import {
|
||||
type EachTestingContext,
|
||||
} from 'twenty-shared/testing';
|
||||
|
||||
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { aggregateOrchestratorActionsReportDeleteObjectAndDeleteFieldActions } from 'src/engine/workspace-manager/workspace-migration-v2/utils/aggregate-orchestrator-actions-report-delete-object-and-delete-field.util';
|
||||
import { type DeleteFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
|
||||
import { type DeleteObjectAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/types/workspace-migration-object-action-v2';
|
||||
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
import { aggregateOrchestratorActionsReportDeleteObjectAndDeleteFieldActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report-delete-object-and-delete-field.util';
|
||||
import { type DeleteFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
|
||||
import { type DeleteObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
|
||||
|
||||
type DeleteAggregationTestCase = EachTestingContext<{
|
||||
input: OrchestratorActionsReport;
|
||||
+3
-3
@@ -6,9 +6,9 @@ import { addFlatEntityToFlatEntityMapsOrThrow } from 'src/engine/metadata-module
|
||||
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { SEARCH_VECTOR_FIELD } from 'src/engine/metadata-modules/search-field-metadata/constants/search-vector-field.constants';
|
||||
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/constant/empty-orchestrator-actions-report.constant';
|
||||
import { aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldActions } from 'src/engine/workspace-manager/workspace-migration-v2/utils/aggregate-orchestrator-actions-report-deprioritize-search-vector-update-field-actions.util';
|
||||
import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
|
||||
import { createEmptyOrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/constant/empty-orchestrator-actions-report.constant';
|
||||
import { aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldActions } from 'src/engine/workspace-manager/workspace-migration/utils/aggregate-orchestrator-actions-report-deprioritize-search-vector-update-field-actions.util';
|
||||
import { type UpdateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
|
||||
|
||||
describe('aggregateOrchestratorActionsReportDeprioritizeSearchVectorUpdateFieldActions', () => {
|
||||
it('should move searchVector update actions to the end of the update list', () => {
|
||||
+2
-2
@@ -6,8 +6,8 @@ import { FieldMetadataType, type FromTo } from 'twenty-shared/types';
|
||||
|
||||
import { type MetadataFlatEntity } from 'src/engine/metadata-modules/flat-entity/types/metadata-flat-entity.type';
|
||||
import { getFlatFieldMetadataMock } from 'src/engine/metadata-modules/flat-field-metadata/__mocks__/get-flat-field-metadata.mock';
|
||||
import { flatEntityDeletedCreatedUpdatedMatrixDispatcher } from 'src/engine/workspace-manager/workspace-migration-v2/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util';
|
||||
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/types/workspace-migration-builder-options.type';
|
||||
import { flatEntityDeletedCreatedUpdatedMatrixDispatcher } from 'src/engine/workspace-manager/workspace-migration/utils/flat-entity-deleted-created-updated-matrix-dispatcher.util';
|
||||
import { type WorkspaceMigrationBuilderOptions } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/types/workspace-migration-builder-options.type';
|
||||
|
||||
type TestContext = FromTo<MetadataFlatEntity<'fieldMetadata'>[]> & {
|
||||
metadataName: 'fieldMetadata';
|
||||
+1
-1
@@ -5,7 +5,7 @@ import { type SyncableFlatEntity } from 'src/engine/metadata-modules/flat-entity
|
||||
import {
|
||||
type CircularDependencyValidationResult,
|
||||
validateFlatEntityCircularDependency,
|
||||
} from 'src/engine/workspace-manager/workspace-migration-v2/utils/validate-flat-entity-circular-dependency.util';
|
||||
} from 'src/engine/workspace-manager/workspace-migration/utils/validate-flat-entity-circular-dependency.util';
|
||||
|
||||
type TestFlatEntity = SyncableFlatEntity & {
|
||||
parentId: string | null;
|
||||
+4
-4
@@ -2,10 +2,10 @@ import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type FlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/types/flat-field-metadata.type';
|
||||
import { isMorphOrRelationFlatFieldMetadata } from 'src/engine/metadata-modules/flat-field-metadata/utils/is-morph-or-relation-flat-field-metadata.util';
|
||||
import { type AggregateOrchestratorActionsReportArgs } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-aggregate-orchestrator-actions-report-args.type';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration-v2/types/workspace-migration-orchestrator.type';
|
||||
import { type CreateFieldAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/field/types/workspace-migration-field-action-v2';
|
||||
import { type CreateObjectAction } from 'src/engine/workspace-manager/workspace-migration-v2/workspace-migration-builder-v2/builders/object/types/workspace-migration-object-action-v2';
|
||||
import { type AggregateOrchestratorActionsReportArgs } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-aggregate-orchestrator-actions-report-args.type';
|
||||
import { type OrchestratorActionsReport } from 'src/engine/workspace-manager/workspace-migration/types/workspace-migration-orchestrator.type';
|
||||
import { type CreateFieldAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/field/types/workspace-migration-field-action';
|
||||
import { type CreateObjectAction } from 'src/engine/workspace-manager/workspace-migration/workspace-migration-builder/builders/object/types/workspace-migration-object-action';
|
||||
|
||||
type AggregatedActions = {
|
||||
createdFieldActionByObjectMetadataId: Record<string, CreateFieldAction>;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user