Skip to content
17 changes: 15 additions & 2 deletions messages/assess.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"allVersionsDescription": "Migrate all versions of a component",
"changeMessage": " %s will be changed from %s to %s",
"angularOSWarning": " Angular OmniScript will not be migrated, please convert this to LWC based Omniscript",
"apexLwcGA": "Please select the type of component to assess: 'apex' for Apex classes, 'lwc' for Lightning Web Components, or 'apex,lwc' if you want to include both types.",
"relatedObjectGA": "Please select the type of component to assess: 'apex' for Apex classes, 'lwc' for Lightning Web Components, 'flexipage' for FlexiPages, or 'apex,lwc,flexipage' if you want to include all types.",
"apexLwc": "Please select the type of component to assess: 'apex' for Apex classes.",
"invalidNamespace": "The namespace you have passed is not valid namespace, the valid namespace of your org is ",
"noPackageInstalled": "No package installed on given org.",
Expand Down Expand Up @@ -124,5 +124,18 @@
"errorParsingData": "Error while parsing data for template",
"errorGeneratingHTML": "Error while generating HTML from template for {} with properties {}",
"unexpectedError": "Unexpected Assessment error",
"errorEvaluatingExpression": "Error evaluating expression: {0}, {1}"
"errorEvaluatingExpression": "Error evaluating expression: {0}, {1}",
"retrievingFlexiPages": "Retrieving FlexiPages",
"successfullyRetrievedFlexiPages": "Successfully retrieved %s FlexiPages",
"assessingFlexiPages": "Assessing FlexiPages",
"completedProcessingAllFlexiPages": "Completed processing all flexipage files. Total processed: %s",
"completedProcessingFlexiPage": "Completed processing %s - Errors: %s",
"processingFlexiPage": "Processing flexipage file: %s",
"startingFlexiPageProcessing": "Starting to process flexipage: %s",
"readFlexiPageContent": "Read file content, size: %s characters",
"updatedModifiedContent": "updated content in file: %s",
"generatedDiffForFile": "Generated diff for file: %s",
"errorProcessingFlexiPage": "Error processing flexipage file: %s, %s",
"flexipagesWithChanges": "Found %s flexipage files with changes",
"migratingFlexiPages": "Migrating FlexiPages"
}
14 changes: 13 additions & 1 deletion messages/migrate.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"errorWhileUploadingCard": "An error ocurred while uploading Card: ",
"errorWhileCreatingElements": "An error ocurred while saving OmniScript elements: ",
"allVersionsDescription": "Migrate all versions of a component",
"apexLwcGA": "Please select the type of components to migrate: 'apex' for Apex classes, 'lwc' for Lightning Web Components, or 'apex,lwc' if you want to include both types.",
"relatedObjectGA": "Please select the type of components to migrate: 'apex' for Apex classes, 'lwc' for Lightning Web Components, 'flexipage' for FlexiPages, 'expsites' for Experience Sites, or 'apex,lwc,flexipage,expsites' if you want to include all types.",
"apexLwc": "Please select the type of components to migrate: 'apex' for Apex classes.",
"invalidNamespace": "The namespace you have passed is not valid namespace, the valid namespace of your org is ",
"noPackageInstalled": "No package installed on given org.",
Expand Down Expand Up @@ -113,6 +113,18 @@
"errorGeneratingHTML": "Error while generating HTML from template for {} with properties {}",
"errorEvaluatingExpression": "Error evaluating expression: {0}, {1}",
"manuallySwitchDesignerToStandardDataModel": "To complete the setup, please manually run the required Apex code to configure OmniStudio Designers to use the Standard Data Model <br> https://help.salesforce.com/s/articleView?id=xcloud.os_migrate_change_the_sobject_data_model_after_migration.htm&type=5",
"retrievingFlexiPages": "Retrieving FlexiPages",
"successfullyRetrievedFlexiPages": "Successfully retrieved %s FlexiPages",
"migratingFlexiPages": "Migrating FlexiPages",
"completedProcessingAllFlexiPages": "Completed processing all flexipage files. Total processed: %s",
"completedProcessingFlexiPage": "Completed processing %s - Errors: %s",
"processingFlexiPage": "Processing flexipage file: %s",
"startingFlexiPageProcessing": "Starting to process flexipage: %s",
"readFlexiPageContent": "Read file content, size: %s characters",
"updatedModifiedContent": "updated content in file: %s",
"generatedDiffForFile": "Generated diff for file: %s",
"errorProcessingFlexiPage": "Error processing flexipage file: %s, %s",
"flexipagesWithChanges": "Found %s flexipage files with changes",
"omniGlobalAutoNumberPrefEnabled": "Successfully enabled OmniGlobalAutoNumberPref org preference",
"errorEnablingOmniGlobalAutoNumberPref": "Error enabling OmniGlobalAutoNumberPref org preference",
"performingPreMigrationChecks": "Performing pre-migration checks for Global Auto Number...",
Expand Down
6 changes: 4 additions & 2 deletions src/commands/omnistudio/migration/assess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export default class Assess extends OmniStudioBaseCommand {
}),
relatedobjects: flags.string({
char: 'r',
description: messages.getMessage('apexLwc'),
description: messages.getMessage('relatedObjectGA'),
}),
verbose: flags.builtin({
type: 'builtin',
Expand Down Expand Up @@ -108,6 +108,7 @@ export default class Assess extends OmniStudioBaseCommand {
osAssessmentInfos: [],
ipAssessmentInfos: [],
},
flexipageAssessmentInfos: [],
};

Logger.log(messages.getMessage('assessmentInitialization', [String(namespace)]));
Expand All @@ -122,7 +123,7 @@ export default class Assess extends OmniStudioBaseCommand {
// Assess related objects if specified
if (relatedObjects) {
// To-Do: Add LWC to valid options when GA is released
const validOptions = [Constants.Apex];
const validOptions = [Constants.Apex, Constants.FlexiPage];
objectsToProcess = relatedObjects.split(',').map((obj) => obj.trim());

// Validate input
Expand All @@ -143,6 +144,7 @@ export default class Assess extends OmniStudioBaseCommand {
const relatedObjectAssessmentResult = omnistudioRelatedObjectsMigration.assessAll(objectsToProcess);
assesmentInfo.lwcAssessmentInfos = relatedObjectAssessmentResult.lwcAssessmentInfos;
assesmentInfo.apexAssessmentInfos = relatedObjectAssessmentResult.apexAssessmentInfos;
assesmentInfo.flexipageAssessmentInfos = relatedObjectAssessmentResult.flexipageAssessmentInfos;
}
try {
orgs.rollbackFlags = await OrgPreferences.checkRollbackFlags(conn);
Expand Down
7 changes: 4 additions & 3 deletions src/commands/omnistudio/migration/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export default class Migrate extends OmniStudioBaseCommand {
}),
relatedobjects: flags.string({
char: 'r',
description: messages.getMessage('apexLwc'),
description: messages.getMessage('relatedObjectGA'),
}),
verbose: flags.builtin({
type: 'builtin',
Expand Down Expand Up @@ -126,7 +126,7 @@ export default class Migrate extends OmniStudioBaseCommand {
const isExperienceBundleMetadataAPIProgramaticallyEnabled: { value: boolean } = { value: false };
if (relatedObjects) {
// To-Do: Add LWC to valid options when GA is released
const validOptions = [Constants.Apex, Constants.ExpSites];
const validOptions = [Constants.Apex, Constants.ExpSites, Constants.FlexiPage];
objectsToProcess = relatedObjects.split(',').map((obj) => obj.trim());
// Validate input
for (const obj of objectsToProcess) {
Expand Down Expand Up @@ -186,7 +186,8 @@ export default class Migrate extends OmniStudioBaseCommand {
const relatedObjectMigrationResult = omnistudioRelatedObjectsMigration.migrateAll(objectsToProcess);
generatePackageXml.createChangeList(
relatedObjectMigrationResult.apexAssessmentInfos,
relatedObjectMigrationResult.lwcAssessmentInfos
relatedObjectMigrationResult.lwcAssessmentInfos,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe lwc is not supported in this version

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's alright, as it'll be blank with LWC enabled change is already in progress

relatedObjectMigrationResult.flexipageAssessmentInfos
);

// POST MIGRATION
Expand Down
30 changes: 30 additions & 0 deletions src/error/errorInterfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export class KeyNotFoundInStorageError extends Error {
public componentType: string;
public key: string;

public constructor(key: string, componentType: string) {
super(`Key ${key} not found in storage`);
this.key = key;
this.componentType = componentType;
}
}

export class DuplicateKeyError extends Error {
public componentType: string;
public key: string;

public constructor(key: string, componentType: string) {
super(`Key ${key} is duplicate in storage`);
this.key = key;
this.componentType = componentType;
}
}

export class TargetPropertyNotFoundError extends Error {
public componentName: string;

public constructor(componentName: string) {
super(`Target property not found for component ${componentName}`);
this.componentName = componentName;
}
}
11 changes: 6 additions & 5 deletions src/migration/base.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
import { UX } from '@salesforce/command';
import { Connection, Messages } from '@salesforce/core';
import cliProgress from 'cli-progress';
import * as cliProgress from 'cli-progress';
import { DebugTimer, QueryTools } from '../utils';
import { NetUtils } from '../utils/net';
import { Stringutil } from '../utils/StringValue/stringutil';
import { Logger } from '../utils/logger';
import { TransformData, UploadRecordResult } from './interfaces';

export type ComponentType = 'Data Mapper' | 'Flexcard' | 'Omniscript and Integration Procedure' | 'GlobalAutoNumber';
export type RelatedObjectType = 'Flexipage';

/**
* Creates a progress bar for migration/assessment operations
*
* @param action - The action being performed (e.g., 'Migrating', 'Assessing')
* @param componentType - The type of component being processed
* @param type - The type of component being processed
* @returns A configured cliProgress.SingleBar instance
*/
export const createProgressBar = (action: string, componentType: ComponentType): cliProgress.SingleBar => {
export const createProgressBar = (action: string, type: ComponentType | RelatedObjectType): cliProgress.SingleBar => {
return new cliProgress.SingleBar({
format: `${action} ${componentType} |${
componentType === 'Omniscript and Integration Procedure' ? '' : '\t\t\t\t'
format: `${action} ${type} |${
type === 'Omniscript and Integration Procedure' ? '' : '\t\t\t\t'
} {bar} | {percentage}% || {value}/{total} Tasks`,
barCompleteChar: '\u2588',
barIncompleteChar: '\u2591',
Expand Down
14 changes: 14 additions & 0 deletions src/migration/flexcard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo
}
uniqueNames.add(cleanedName);

this.addToAssessmentStorage(originalName, cleanedName);

// Check for author name changes
const originalAuthor = flexCard[this.namespacePrefix + 'Author__c'];
if (originalAuthor) {
Expand Down Expand Up @@ -584,6 +586,18 @@ export class CardMigrationTool extends BaseMigrationTool implements MigrationToo
}
}

private addToAssessmentStorage(originalName: string, cleanedName: string) {
let storage: MigrationStorage = StorageUtil.getOmnistudioAssessmentStorage();
if (storage.fcStorage.has(originalName)) {
storage.fcStorage.get(originalName).isDuplicate = true;
} else {
storage.fcStorage.set(originalName, {
name: cleanedName,
isDuplicate: false,
});
}
}

private prepareStorageForFlexcards(
cardsUploadInfo: Map<string, UploadRecordResult>,
originalRecords: Map<string, any>
Expand Down
27 changes: 27 additions & 0 deletions src/migration/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,33 @@ export interface RelatedObjectMigrationResult {
lwcComponents: string[];
}

export interface Flexipage {
[key: string]: string | FlexiPageRegion[];
flexiPageRegions: FlexiPageRegion[];
}

export interface FlexiPageRegion {
[key: string]: string | FlexiItemInstance[];
itemInstances?: FlexiItemInstance[];
}

export interface FlexiItemInstance {
[key: string]: string | FlexiComponentInstance;
componentInstance: FlexiComponentInstance;
}

export interface FlexiComponentInstance {
[key: string]: string | FlexiComponentInstanceProperty[];
componentInstanceProperties: FlexiComponentInstanceProperty[];
componentName: string;
identifier?: string;
}

export interface FlexiComponentInstanceProperty {
name: string;
value?: string;
}

export interface ExpSitePageJson {
// Index signature to allow any additional properties
[key: string]: any;
Expand Down
22 changes: 22 additions & 0 deletions src/migration/omniscript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,13 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat

const warnings: string[] = [];

if (omniProcessType === 'OmniScript') {
this.addToAssessmentStorage(
existingTypeVal,
existingSubTypeVal,
omniscript[this.namespacePrefix + 'Language__c']
);
}
const recordName =
`${existingTypeVal.cleanName()}_` +
`${existingSubTypeVal.cleanName()}` +
Expand Down Expand Up @@ -774,6 +781,21 @@ export class OmniScriptMigrationTool extends BaseMigrationTool implements Migrat
};
}

private addToAssessmentStorage(type: StringVal, subtype: StringVal, language: string) {
let storage: MigrationStorage = StorageUtil.getOmnistudioAssessmentStorage();
const key = `${type.val}${subtype.val}${language}`;
if (storage.osStorage.has(key)) {
storage.osStorage.get(key).isDuplicate = true;
} else {
storage.osStorage.set(key, {
type: type.cleanName(),
subtype: subtype.cleanName(),
language: language || 'English',
isDuplicate: false,
});
}
}

private updateStorageForOmniscript(
osUploadInfo: Map<string, UploadRecordResult>,
originalOsRecords: Map<string, any>
Expand Down
Loading