Fix Quick Lead command menu item not appearing (#19635)
- Refactored prefillWorkflowCommandMenuItems and prefillFrontComponentCommandMenuItems to use validateBuildAndRunWorkspaceMigration instead of raw TypeORM createQueryBuilder inserts - This ensures the flat entity cache is properly updated when seeding command menu items, fixing the Quick Lead item not appearing after workspace creation - Moved command menu item prefill calls outside the transaction since they now go through the migration pipeline
This commit is contained in:
+4
@@ -37,6 +37,8 @@ import { CoreEntityCacheService } from 'src/engine/core-entity-cache/services/co
|
||||
import { WorkspaceCacheStorageService } from 'src/engine/workspace-cache-storage/workspace-cache-storage.service';
|
||||
import { WorkspaceDataSourceService } from 'src/engine/workspace-datasource/workspace-datasource.service';
|
||||
import { PrefillLogicFunctionService } from 'src/engine/workspace-manager/standard-objects-prefill-data/services/prefill-logic-function.service';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
|
||||
|
||||
describe('WorkspaceService', () => {
|
||||
@@ -123,7 +125,9 @@ describe('WorkspaceService', () => {
|
||||
PermissionsService,
|
||||
FileCorePictureService,
|
||||
AiModelRegistryService,
|
||||
ApplicationService,
|
||||
PrefillLogicFunctionService,
|
||||
WorkspaceMigrationValidateBuildAndRunService,
|
||||
UpgradeMigrationService,
|
||||
UpgradeSequenceReaderService,
|
||||
].map((service) => ({
|
||||
|
||||
+21
-9
@@ -12,6 +12,7 @@ import { DataSource, QueryRunner, Repository } from 'typeorm';
|
||||
|
||||
import { CoreEntityCacheService } from 'src/engine/core-entity-cache/services/core-entity-cache.service';
|
||||
import { ApiKeyEntity } from 'src/engine/core-modules/api-key/api-key.entity';
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { type AuthContextUser } from 'src/engine/core-modules/auth/types/auth-context.type';
|
||||
import { BillingSubscriptionService } from 'src/engine/core-modules/billing/services/billing-subscription.service';
|
||||
import { BillingService } from 'src/engine/core-modules/billing/services/billing.service';
|
||||
@@ -66,6 +67,7 @@ import { prefillWorkflowCommandMenuItems } from 'src/engine/workspace-manager/st
|
||||
import { prefillWorkflows } from 'src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-workflows.util';
|
||||
import { WorkspaceManagerService } from 'src/engine/workspace-manager/workspace-manager.service';
|
||||
import { DEFAULT_FEATURE_FLAGS } from 'src/engine/workspace-manager/workspace-migration/constant/default-feature-flags';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
@Injectable()
|
||||
// oxlint-disable-next-line twenty/inject-workspace-repository
|
||||
@@ -116,6 +118,8 @@ export class WorkspaceService extends TypeOrmQueryService<WorkspaceEntity> {
|
||||
private readonly dnsManagerService: DnsManagerService,
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly prefillLogicFunctionService: PrefillLogicFunctionService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
private readonly workspaceCacheStorageService: WorkspaceCacheStorageService,
|
||||
private readonly subdomainManagerService: SubdomainManagerService,
|
||||
private readonly workspaceDataSourceService: WorkspaceDataSourceService,
|
||||
@@ -775,8 +779,6 @@ export class WorkspaceService extends TypeOrmQueryService<WorkspaceEntity> {
|
||||
flatFieldMetadataMaps,
|
||||
);
|
||||
|
||||
await prefillWorkflowCommandMenuItems(queryRunner.manager, workspaceId);
|
||||
|
||||
await prefillOpportunities(queryRunner.manager, schemaName);
|
||||
|
||||
await prefillDashboards(
|
||||
@@ -788,18 +790,28 @@ export class WorkspaceService extends TypeOrmQueryService<WorkspaceEntity> {
|
||||
await queryRunner.commitTransaction();
|
||||
} catch (error) {
|
||||
if (queryRunner.isTransactionActive) {
|
||||
try {
|
||||
await queryRunner.rollbackTransaction();
|
||||
} catch (rollbackError) {
|
||||
this.logger.error(
|
||||
`Failed to rollback prefill transaction: ${rollbackError.message}`,
|
||||
);
|
||||
}
|
||||
await queryRunner.rollbackTransaction();
|
||||
}
|
||||
|
||||
throw error;
|
||||
} finally {
|
||||
await queryRunner.release();
|
||||
}
|
||||
|
||||
try {
|
||||
await prefillWorkflowCommandMenuItems({
|
||||
workspaceId,
|
||||
applicationService: this.applicationService,
|
||||
flatEntityMapsCacheService: this.flatEntityMapsCacheService,
|
||||
workspaceMigrationValidateBuildAndRunService:
|
||||
this.workspaceMigrationValidateBuildAndRunService,
|
||||
});
|
||||
} catch (error) {
|
||||
this.logger.error(
|
||||
`Non-critical: failed to prefill workflow command menu items for workspace ${workspaceId}`,
|
||||
error,
|
||||
);
|
||||
this.exceptionHandlerService.captureExceptions([error as Error]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ import { ViewModule } from 'src/engine/metadata-modules/view/view.module';
|
||||
import { WorkspaceCacheStorageModule } from 'src/engine/workspace-cache-storage/workspace-cache-storage.module';
|
||||
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';
|
||||
import { WorkspaceManagerModule } from 'src/engine/workspace-manager/workspace-manager.module';
|
||||
import { WorkspaceMigrationModule } from 'src/engine/workspace-manager/workspace-migration/workspace-migration.module';
|
||||
import { StandardObjectsPrefillModule } from 'src/engine/workspace-manager/standard-objects-prefill-data/standard-objects-prefill.module';
|
||||
|
||||
@Module({
|
||||
@@ -83,6 +84,7 @@ import { StandardObjectsPrefillModule } from 'src/engine/workspace-manager/stand
|
||||
ApplicationModule,
|
||||
EnterpriseModule,
|
||||
StandardObjectsPrefillModule,
|
||||
WorkspaceMigrationModule,
|
||||
CoreEntityCacheModule,
|
||||
UpgradeModule,
|
||||
],
|
||||
|
||||
+24
-8
@@ -8,6 +8,7 @@ import { STANDARD_OBJECTS } from 'twenty-shared/metadata';
|
||||
import { FeatureFlagKey, FileFolder } from 'twenty-shared/types';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
import { ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { FileStorageService } from 'src/engine/core-modules/file-storage/file-storage.service';
|
||||
import { WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { FlatObjectMetadata } from 'src/engine/metadata-modules/flat-object-metadata/types/flat-object-metadata.type';
|
||||
@@ -36,6 +37,10 @@ import {
|
||||
COMPANY_DATA_SEED_COLUMNS,
|
||||
COMPANY_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/company-data-seeds.constant';
|
||||
import {
|
||||
CONNECTED_ACCOUNT_DATA_SEED_COLUMNS,
|
||||
CONNECTED_ACCOUNT_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/connected-account-data-seeds.constant';
|
||||
import {
|
||||
DASHBOARD_DATA_SEED_COLUMNS,
|
||||
getDashboardDataSeeds,
|
||||
@@ -44,10 +49,6 @@ import {
|
||||
EMPLOYMENT_HISTORY_DATA_SEED_COLUMNS,
|
||||
EMPLOYMENT_HISTORY_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/employment-history-data-seeds.constant';
|
||||
import {
|
||||
CONNECTED_ACCOUNT_DATA_SEED_COLUMNS,
|
||||
CONNECTED_ACCOUNT_DATA_SEEDS,
|
||||
} from 'src/engine/workspace-manager/dev-seeder/data/constants/connected-account-data-seeds.constant';
|
||||
import {
|
||||
MESSAGE_CHANNEL_DATA_SEED_COLUMNS,
|
||||
MESSAGE_CHANNEL_DATA_SEEDS,
|
||||
@@ -121,6 +122,7 @@ import { getCreateCompanyWhenAddingNewPersonCodeStepLogicFunctionDefinitions } f
|
||||
import { prefillWorkflowCommandMenuItems } from 'src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-workflow-command-menu-items.util';
|
||||
import { prefillWorkflows } from 'src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-workflows.util';
|
||||
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
|
||||
import { WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
type RecordSeedConfig = {
|
||||
tableName: string;
|
||||
@@ -293,6 +295,8 @@ export class DevSeederDataService {
|
||||
private readonly flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService,
|
||||
private readonly prefillLogicFunctionService: PrefillLogicFunctionService,
|
||||
private readonly prefillFrontComponentService: PrefillFrontComponentService,
|
||||
private readonly applicationService: ApplicationService,
|
||||
private readonly workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService,
|
||||
) {}
|
||||
|
||||
public async seed({
|
||||
@@ -366,12 +370,24 @@ export class DevSeederDataService {
|
||||
flatObjectMetadataMaps,
|
||||
flatFieldMetadataMaps,
|
||||
);
|
||||
|
||||
await prefillWorkflowCommandMenuItems(entityManager, workspaceId);
|
||||
|
||||
await prefillFrontComponentCommandMenuItems(entityManager, workspaceId);
|
||||
},
|
||||
);
|
||||
|
||||
await prefillWorkflowCommandMenuItems({
|
||||
workspaceId,
|
||||
applicationService: this.applicationService,
|
||||
flatEntityMapsCacheService: this.flatEntityMapsCacheService,
|
||||
workspaceMigrationValidateBuildAndRunService:
|
||||
this.workspaceMigrationValidateBuildAndRunService,
|
||||
});
|
||||
|
||||
await prefillFrontComponentCommandMenuItems({
|
||||
workspaceId,
|
||||
applicationService: this.applicationService,
|
||||
flatEntityMapsCacheService: this.flatEntityMapsCacheService,
|
||||
workspaceMigrationValidateBuildAndRunService:
|
||||
this.workspaceMigrationValidateBuildAndRunService,
|
||||
});
|
||||
}
|
||||
|
||||
private async seedRecordsInBatches({
|
||||
|
||||
+91
-41
@@ -1,60 +1,82 @@
|
||||
import { type EntityManager } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { CommandMenuItemAvailabilityType } from 'src/engine/metadata-modules/command-menu-item/enums/command-menu-item-availability-type.enum';
|
||||
import { EngineComponentKey } from 'src/engine/metadata-modules/command-menu-item/enums/engine-component-key.enum';
|
||||
import { type FlatCommandMenuItem } from 'src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type';
|
||||
import { type WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { findFlatEntityByIdInFlatEntityMaps } from 'src/engine/metadata-modules/flat-entity/utils/find-flat-entity-by-id-in-flat-entity-maps.util';
|
||||
import {
|
||||
getSeedFrontComponentCommandMenuItemDefinitions,
|
||||
getSeedFrontComponentIds,
|
||||
} from 'src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-front-component-definitions.util';
|
||||
import { type WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
export const prefillFrontComponentCommandMenuItems = async (
|
||||
entityManager: EntityManager,
|
||||
workspaceId: string,
|
||||
) => {
|
||||
export const prefillFrontComponentCommandMenuItems = async ({
|
||||
workspaceId,
|
||||
applicationService,
|
||||
flatEntityMapsCacheService,
|
||||
workspaceMigrationValidateBuildAndRunService,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
applicationService: ApplicationService;
|
||||
flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService;
|
||||
workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService;
|
||||
}): Promise<void> => {
|
||||
const { helloWorldId } = getSeedFrontComponentIds(workspaceId);
|
||||
|
||||
const frontComponentRow = await entityManager
|
||||
.createQueryBuilder()
|
||||
.select('fc.applicationId', 'applicationId')
|
||||
.from('core.frontComponent', 'fc')
|
||||
.where('fc.id = :id', { id: helloWorldId })
|
||||
.andWhere('fc.workspaceId = :workspaceId', { workspaceId })
|
||||
.getRawOne();
|
||||
const { flatCommandMenuItemMaps, flatFrontComponentMaps } =
|
||||
await flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps({
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatCommandMenuItemMaps', 'flatFrontComponentMaps'],
|
||||
});
|
||||
|
||||
if (!frontComponentRow) {
|
||||
const frontComponent = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: helloWorldId,
|
||||
flatEntityMaps: flatFrontComponentMaps,
|
||||
});
|
||||
|
||||
if (!isDefined(frontComponent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{ workspaceId },
|
||||
);
|
||||
|
||||
const definitions =
|
||||
getSeedFrontComponentCommandMenuItemDefinitions(workspaceId);
|
||||
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into('core.commandMenuItem', [
|
||||
'workspaceId',
|
||||
'universalIdentifier',
|
||||
'applicationId',
|
||||
'workflowVersionId',
|
||||
'frontComponentId',
|
||||
'engineComponentKey',
|
||||
'label',
|
||||
'icon',
|
||||
'shortLabel',
|
||||
'position',
|
||||
'isPinned',
|
||||
'availabilityType',
|
||||
'conditionalAvailabilityExpression',
|
||||
'availabilityObjectMetadataId',
|
||||
'hotKeys',
|
||||
])
|
||||
.values(
|
||||
definitions.map((definition) => ({
|
||||
workspaceId,
|
||||
const now = new Date().toISOString();
|
||||
|
||||
const flatCommandMenuItemsToCreate: FlatCommandMenuItem[] = definitions
|
||||
.filter(
|
||||
(definition) =>
|
||||
!isDefined(
|
||||
flatCommandMenuItemMaps.byUniversalIdentifier[
|
||||
definition.universalIdentifier
|
||||
],
|
||||
),
|
||||
)
|
||||
.map((definition) => {
|
||||
const definitionFrontComponent = findFlatEntityByIdInFlatEntityMaps({
|
||||
flatEntityId: definition.frontComponentId,
|
||||
flatEntityMaps: flatFrontComponentMaps,
|
||||
});
|
||||
|
||||
return {
|
||||
id: v4(),
|
||||
universalIdentifier: definition.universalIdentifier,
|
||||
applicationId: frontComponentRow.applicationId,
|
||||
applicationId: frontComponent.applicationId,
|
||||
applicationUniversalIdentifier:
|
||||
frontComponent.applicationUniversalIdentifier,
|
||||
workspaceId,
|
||||
workflowVersionId: null,
|
||||
frontComponentId: definition.frontComponentId,
|
||||
frontComponentUniversalIdentifier:
|
||||
definitionFrontComponent?.universalIdentifier ?? null,
|
||||
engineComponentKey: EngineComponentKey.FRONT_COMPONENT_RENDERER,
|
||||
label: definition.label,
|
||||
icon: definition.icon,
|
||||
@@ -64,9 +86,37 @@ export const prefillFrontComponentCommandMenuItems = async (
|
||||
availabilityType: CommandMenuItemAvailabilityType.GLOBAL,
|
||||
conditionalAvailabilityExpression: null,
|
||||
availabilityObjectMetadataId: null,
|
||||
availabilityObjectMetadataUniversalIdentifier: null,
|
||||
payload: null,
|
||||
hotKeys: null,
|
||||
})),
|
||||
)
|
||||
.orIgnore()
|
||||
.execute();
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
});
|
||||
|
||||
if (flatCommandMenuItemsToCreate.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result =
|
||||
await workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
allFlatEntityOperationByMetadataName: {
|
||||
commandMenuItem: {
|
||||
flatEntityToCreate: flatCommandMenuItemsToCreate,
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [],
|
||||
},
|
||||
},
|
||||
workspaceId,
|
||||
applicationUniversalIdentifier:
|
||||
workspaceCustomFlatApplication.universalIdentifier,
|
||||
},
|
||||
);
|
||||
|
||||
if (result.status === 'fail') {
|
||||
throw new Error(
|
||||
`Failed to create front component command menu items for workspace ${workspaceId}: ${JSON.stringify(result, null, 2)}`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
+81
-55
@@ -1,70 +1,96 @@
|
||||
import { type EntityManager } from 'typeorm';
|
||||
import { v4 } from 'uuid';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
import { type ApplicationService } from 'src/engine/core-modules/application/application.service';
|
||||
import { CommandMenuItemAvailabilityType } from 'src/engine/metadata-modules/command-menu-item/enums/command-menu-item-availability-type.enum';
|
||||
import { EngineComponentKey } from 'src/engine/metadata-modules/command-menu-item/enums/engine-component-key.enum';
|
||||
import { type FlatCommandMenuItem } from 'src/engine/metadata-modules/flat-command-menu-item/types/flat-command-menu-item.type';
|
||||
import { type WorkspaceManyOrAllFlatEntityMapsCacheService } from 'src/engine/metadata-modules/flat-entity/services/workspace-many-or-all-flat-entity-maps-cache.service';
|
||||
import { QUICK_LEAD_WORKFLOW_VERSION_ID } from 'src/engine/workspace-manager/standard-objects-prefill-data/utils/prefill-workflows.util';
|
||||
import { TWENTY_STANDARD_APPLICATION } from 'src/engine/workspace-manager/twenty-standard-application/constants/twenty-standard-applications';
|
||||
import { type WorkspaceMigrationValidateBuildAndRunService } from 'src/engine/workspace-manager/workspace-migration/services/workspace-migration-validate-build-and-run-service';
|
||||
|
||||
const QUICK_LEAD_COMMAND_MENU_ITEM_UNIVERSAL_IDENTIFIER =
|
||||
'a1b2c3d4-e5f6-7890-abcd-1234567890ab';
|
||||
'5b389a80-345f-42b5-83fa-2e6b6ad95f01';
|
||||
|
||||
export const prefillWorkflowCommandMenuItems = async (
|
||||
entityManager: EntityManager,
|
||||
workspaceId: string,
|
||||
) => {
|
||||
const applicationRow = await entityManager
|
||||
.createQueryBuilder()
|
||||
.select('app.id')
|
||||
.from('core.application', 'app')
|
||||
.where('app.universalIdentifier = :universalIdentifier', {
|
||||
universalIdentifier: TWENTY_STANDARD_APPLICATION.universalIdentifier,
|
||||
})
|
||||
.andWhere('app.workspaceId = :workspaceId', { workspaceId })
|
||||
.getRawOne();
|
||||
export const prefillWorkflowCommandMenuItems = async ({
|
||||
workspaceId,
|
||||
applicationService,
|
||||
flatEntityMapsCacheService,
|
||||
workspaceMigrationValidateBuildAndRunService,
|
||||
}: {
|
||||
workspaceId: string;
|
||||
applicationService: ApplicationService;
|
||||
flatEntityMapsCacheService: WorkspaceManyOrAllFlatEntityMapsCacheService;
|
||||
workspaceMigrationValidateBuildAndRunService: WorkspaceMigrationValidateBuildAndRunService;
|
||||
}): Promise<void> => {
|
||||
const { workspaceCustomFlatApplication } =
|
||||
await applicationService.findWorkspaceTwentyStandardAndCustomApplicationOrThrow(
|
||||
{ workspaceId },
|
||||
);
|
||||
|
||||
if (!applicationRow) {
|
||||
const { flatCommandMenuItemMaps } =
|
||||
await flatEntityMapsCacheService.getOrRecomputeManyOrAllFlatEntityMaps({
|
||||
workspaceId,
|
||||
flatMapsKeys: ['flatCommandMenuItemMaps'],
|
||||
});
|
||||
|
||||
const alreadyExists = isDefined(
|
||||
flatCommandMenuItemMaps.byUniversalIdentifier[
|
||||
QUICK_LEAD_COMMAND_MENU_ITEM_UNIVERSAL_IDENTIFIER
|
||||
],
|
||||
);
|
||||
|
||||
if (alreadyExists) {
|
||||
return;
|
||||
}
|
||||
|
||||
await entityManager
|
||||
.createQueryBuilder()
|
||||
.insert()
|
||||
.into('core.commandMenuItem', [
|
||||
'workspaceId',
|
||||
'universalIdentifier',
|
||||
'applicationId',
|
||||
'workflowVersionId',
|
||||
'frontComponentId',
|
||||
'engineComponentKey',
|
||||
'label',
|
||||
'icon',
|
||||
'shortLabel',
|
||||
'position',
|
||||
'isPinned',
|
||||
'availabilityType',
|
||||
'conditionalAvailabilityExpression',
|
||||
'availabilityObjectMetadataId',
|
||||
'hotKeys',
|
||||
])
|
||||
.values([
|
||||
const now = new Date().toISOString();
|
||||
|
||||
const quickLeadFlatCommandMenuItem: FlatCommandMenuItem = {
|
||||
id: v4(),
|
||||
universalIdentifier: QUICK_LEAD_COMMAND_MENU_ITEM_UNIVERSAL_IDENTIFIER,
|
||||
applicationId: workspaceCustomFlatApplication.id,
|
||||
applicationUniversalIdentifier:
|
||||
workspaceCustomFlatApplication.universalIdentifier,
|
||||
workspaceId,
|
||||
workflowVersionId: QUICK_LEAD_WORKFLOW_VERSION_ID,
|
||||
frontComponentId: null,
|
||||
frontComponentUniversalIdentifier: null,
|
||||
engineComponentKey: EngineComponentKey.TRIGGER_WORKFLOW_VERSION,
|
||||
label: 'Quick Lead',
|
||||
icon: 'IconUserPlus',
|
||||
shortLabel: 'Quick Lead',
|
||||
position: 100,
|
||||
isPinned: false,
|
||||
availabilityType: CommandMenuItemAvailabilityType.GLOBAL,
|
||||
conditionalAvailabilityExpression: null,
|
||||
availabilityObjectMetadataId: null,
|
||||
availabilityObjectMetadataUniversalIdentifier: null,
|
||||
payload: null,
|
||||
hotKeys: null,
|
||||
createdAt: now,
|
||||
updatedAt: now,
|
||||
};
|
||||
|
||||
const result =
|
||||
await workspaceMigrationValidateBuildAndRunService.validateBuildAndRunWorkspaceMigration(
|
||||
{
|
||||
allFlatEntityOperationByMetadataName: {
|
||||
commandMenuItem: {
|
||||
flatEntityToCreate: [quickLeadFlatCommandMenuItem],
|
||||
flatEntityToDelete: [],
|
||||
flatEntityToUpdate: [],
|
||||
},
|
||||
},
|
||||
workspaceId,
|
||||
universalIdentifier: QUICK_LEAD_COMMAND_MENU_ITEM_UNIVERSAL_IDENTIFIER,
|
||||
applicationId: applicationRow.app_id,
|
||||
workflowVersionId: QUICK_LEAD_WORKFLOW_VERSION_ID,
|
||||
frontComponentId: null,
|
||||
engineComponentKey: EngineComponentKey.TRIGGER_WORKFLOW_VERSION,
|
||||
label: 'Quick Lead',
|
||||
icon: 'IconUserPlus',
|
||||
shortLabel: 'Quick Lead',
|
||||
position: 100,
|
||||
isPinned: false,
|
||||
availabilityType: CommandMenuItemAvailabilityType.GLOBAL,
|
||||
conditionalAvailabilityExpression: null,
|
||||
availabilityObjectMetadataId: null,
|
||||
hotKeys: null,
|
||||
applicationUniversalIdentifier:
|
||||
workspaceCustomFlatApplication.universalIdentifier,
|
||||
},
|
||||
])
|
||||
.orIgnore()
|
||||
.execute();
|
||||
);
|
||||
|
||||
if (result.status === 'fail') {
|
||||
throw new Error(
|
||||
`Failed to create Quick Lead command menu item for workspace ${workspaceId}: ${JSON.stringify(result, null, 2)}`,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user