Skip to content

Commit d8746a8

Browse files
authored
Merge pull request #402 from snehaljha-sf/expSite_report_update
feat: add bundle grouping for exp site reports
2 parents 8707926 + 5019453 commit d8746a8

File tree

15 files changed

+310
-148
lines changed

15 files changed

+310
-148
lines changed

messages/assess.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
"generatedDiffForFile": "Generated difference for the file: %s",
134134
"errorProcessingFlexiPage": "Error processing FlexiPage: %s, %s",
135135
"flexipagesWithChanges": "Found %s FlexiPages with changes",
136+
"expSitesWithChanges": "Found %s Experience Cloud Sites with changes",
136137
"migratingFlexiPages": "Migrating FlexiPages",
137138
"experienceSiteMetadataConsent": "Your consent for migrating Experience Cloud sites is %s",
138139
"experienceSiteConsentNotProvidedWarning": "You’ve not provided consent and your Experience Cloud sites won’t be processed.",

messages/migrate.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
"errorEvaluatingExpression": "Error evaluating expression: %s, %s",
102102
"migrationConsentNotGiven": "Couldn't confirm whether assessment errors are resolved",
103103
"foundFlexiPages": "Found %s FlexiPages to migrate",
104+
"expSitesWithChanges": "Found %s Experience Cloud Sites with changes",
104105
"migratingFlexiPages": "Migrating FlexiPages",
105106
"completedProcessingAllFlexiPages": "Completed processing all flexipages. Total processed: %s",
106107
"completedProcessingFlexiPage": "Completed processing %s. Errors: %s",

src/javascripts/reportGeneratorUtility.js

Lines changed: 50 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
let props = {};
2+
let classToHide = 'no-display';
3+
14
function toggleFilterDropdown(tableId) {
25
const reportTable = document.getElementById(tableId);
36
const dropdown = reportTable.querySelector('#filter-dropdown');
@@ -87,6 +90,8 @@ function filterAndSearchTable(tableId) {
8790

8891
// Otherwise, apply filters and search
8992
let processedClasses = new Set();
93+
94+
let classRowMap = new Map();
9095
rows.forEach((row) => {
9196
if (row.id === 'no-rows-message') return;
9297

@@ -112,10 +117,18 @@ function filterAndSearchTable(tableId) {
112117
}
113118
}
114119

115-
// row.style.display = show ? '' : 'none';
116-
if (!processedClasses.has(row.classList[0])) {
117-
hideOrShowData(reportTable, row.classList[0], show);
118-
processedClasses.add(row.classList[0]);
120+
if (props?.rowBased) {
121+
if (show && !classRowMap.has(row.classList[0])) {
122+
classRowMap.set(row.classList[0], { row, cnt: 1 });
123+
} else if (show) {
124+
classRowMap.get(row.classList[0]).cnt++;
125+
}
126+
row.style.display = show ? '' : 'none';
127+
} else {
128+
if (!processedClasses.has(row.classList[0])) {
129+
hideOrShowData(reportTable, row.classList[0], show);
130+
processedClasses.add(row.classList[0]);
131+
}
119132
}
120133
if (show) visibleRowCount++;
121134
});
@@ -129,11 +142,24 @@ function filterAndSearchTable(tableId) {
129142
(row) => row.style.display !== 'none' && row.id !== 'no-rows-message'
130143
);
131144

145+
if (props?.rowBased) {
146+
rows.forEach((row) => {
147+
row.cells[0].classList.add(classToHide);
148+
});
149+
150+
classRowMap.forEach((value) => {
151+
value.row.cells[0].classList.remove(classToHide);
152+
value.row.cells[0].rowSpan = value.cnt;
153+
});
154+
}
155+
132156
// filter only distinct classes from visibleRows
133-
const distinctClasses = [...new Set(visibleRows.map((row) => row.classList[0]))];
134-
reportTable.querySelector('#row-count').textContent = `Showing ${distinctClasses.length} record${
135-
distinctClasses.length !== 1 ? 's' : ''
136-
}`;
157+
let recordLabel = props?.recordName || 'records';
158+
let cnt = visibleRows.length;
159+
if (!props?.rowCount) {
160+
cnt = [...new Set(visibleRows.map((row) => row.classList[0]))].length;
161+
}
162+
reportTable.querySelector('#row-count').textContent = `Total ${recordLabel}: ${cnt}`;
137163
}
138164

139165
function toggleCtaSummaryPanel() {
@@ -160,6 +186,7 @@ function hideOrShowData(reportTable, rowClass, show) {
160186
}
161187

162188
document.addEventListener('DOMContentLoaded', () => {
189+
loadProps();
163190
document.querySelectorAll('.collapsible-content').forEach((collapsibleContent) => {
164191
collapsibleContent.style.display = 'none';
165192
});
@@ -266,6 +293,21 @@ function closeCtaPanel() {
266293
}
267294
}
268295

296+
function loadProps() {
297+
const propElement = document.querySelector('#props');
298+
if (!propElement) {
299+
return;
300+
}
301+
302+
try {
303+
props = JSON.parse(propElement.textContent);
304+
} catch (error) {
305+
console.error('error parsing props', error);
306+
return;
307+
}
308+
console.log('parsed props', props);
309+
}
310+
269311
// Expose globally so HTML inline event handlers can access them
270312
window.toggleFilterDropdown = toggleFilterDropdown;
271313
window.closeFilterDropdown = closeFilterDropdown;

src/migration/related/ApexMigration.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export class ApexMigration extends BaseRelatedObjectMigration {
5858
shell.cd(this.projectPath);
5959
Logger.info(migrateMessages.getMessage('processingApexFilesForMigration'));
6060
const apexAssessmentInfos = this.processApexFiles(this.projectPath, 'migration');
61-
Logger.info(migrateMessages.getMessage('successfullyProcessedApexFilesForMigration', [apexAssessmentInfos.length]));
61+
Logger.log(migrateMessages.getMessage('successfullyProcessedApexFilesForMigration', [apexAssessmentInfos.length]));
6262
Logger.logVerbose(
6363
migrateMessages.getMessage('apexMigrationResults', [JSON.stringify(apexAssessmentInfos, null, 2)])
6464
);
@@ -72,7 +72,7 @@ export class ApexMigration extends BaseRelatedObjectMigration {
7272
shell.cd(this.projectPath);
7373
Logger.info(assessMessages.getMessage('processingApexFilesForAssessment'));
7474
const apexAssessmentInfos = this.processApexFiles(this.projectPath, 'assessment');
75-
Logger.info(assessMessages.getMessage('successfullyProcessedApexFilesForAssessment', [apexAssessmentInfos.length]));
75+
Logger.log(assessMessages.getMessage('successfullyProcessedApexFilesForAssessment', [apexAssessmentInfos.length]));
7676
Logger.logVerbose(
7777
assessMessages.getMessage('apexAssessmentResults', [JSON.stringify(apexAssessmentInfos, null, 2)])
7878
);

src/migration/related/ExperienceSiteMigration.ts

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
FlexcardStorage,
1717
} from '../interfaces';
1818
import { FileDiffUtil } from '../../utils/lwcparser/fileutils/FileDiffUtil';
19-
import { ExperienceSiteAssessmentInfo } from '../../utils';
19+
import { ExperienceSiteAssessmentInfo, ExperienceSiteAssessmentPageInfo } from '../../utils';
2020
import { StorageUtil } from '../../utils/storageUtil';
2121
import { createProgressBar } from '../base';
2222
import { BaseRelatedObjectMigration } from './BaseRealtedObjectMigration';
@@ -60,6 +60,11 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
6060
const experienceSiteInfo = this.processExperienceSites(this.EXPERIENCE_SITES_PATH, type);
6161
Logger.info(this.messages.getMessage('experienceSiteSuccessfullyProcessed', [type]));
6262
shell.cd(pwd);
63+
Logger.log(
64+
this.messages.getMessage('expSitesWithChanges', [
65+
experienceSiteInfo.flatMap((info) => info.experienceSiteAssessmentPageInfos).length,
66+
])
67+
);
6368
return experienceSiteInfo;
6469
}
6570

@@ -78,6 +83,10 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
7883
const experienceSitesAssessmentInfo: ExperienceSiteAssessmentInfo[] = [];
7984
Logger.logVerbose('The namespace for expsites processing is ' + this.namespace);
8085
for (const directory of directoryMap.keys()) {
86+
const experienceSiteAssessmentInfo: ExperienceSiteAssessmentInfo = {
87+
experienceBundleName: path.basename(path.dirname(directory)),
88+
experienceSiteAssessmentPageInfos: [],
89+
};
8190
const fileArray = directoryMap.get(directory);
8291
if (!fileArray) {
8392
continue;
@@ -89,30 +98,34 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
8998
continue;
9099
}
91100
try {
92-
const experienceSiteInfo = this.processExperienceSite(file, type);
93-
if (experienceSiteInfo?.hasOmnistudioContent === true) {
101+
const experienceSitePageInfo = this.processExperienceSite(file, type);
102+
if (experienceSitePageInfo?.hasOmnistudioContent === true) {
94103
Logger.logVerbose(this.messages.getMessage('experienceSiteWithOmniWrapperSuccessfullyProcessed'));
95-
experienceSitesAssessmentInfo.push(experienceSiteInfo);
104+
experienceSiteAssessmentInfo.experienceSiteAssessmentPageInfos.push(experienceSitePageInfo);
96105
} else {
97106
Logger.logVerbose(this.messages.getMessage('fileNotHavingWrapper'));
98107
}
99108
} catch (err) {
100-
this.populateExceptionInfo(file, experienceSitesAssessmentInfo);
109+
this.populateExceptionInfo(file, experienceSiteAssessmentInfo.experienceSiteAssessmentPageInfos);
101110
Logger.error(this.messages.getMessage('errorProcessingExperienceSite', [file.name]));
102111
Logger.error(JSON.stringify(err));
103112
}
104113
}
114+
115+
if (experienceSiteAssessmentInfo.experienceSiteAssessmentPageInfos.length > 0) {
116+
experienceSitesAssessmentInfo.push(experienceSiteAssessmentInfo);
117+
}
105118
}
106119

107120
Logger.logVerbose(this.messages.getMessage('experienceSiteReportingDetails'));
108121
progressBar.stop();
109122
return experienceSitesAssessmentInfo;
110123
}
111124

112-
public processExperienceSite(file: File, type: string): ExperienceSiteAssessmentInfo {
125+
public processExperienceSite(file: File, type: string): ExperienceSiteAssessmentPageInfo {
113126
Logger.logVerbose(this.messages.getMessage('processingFile', [file.name]));
114127

115-
const experienceSiteAssessmentInfo: ExperienceSiteAssessmentInfo = {
128+
const experienceSiteAssessmentInfo: ExperienceSiteAssessmentPageInfo = {
116129
name: file.name,
117130
warnings: [],
118131
errors: [],
@@ -170,9 +183,9 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
170183
return experienceSiteAssessmentInfo;
171184
}
172185

173-
private populateExceptionInfo(file: File, experienceSiteAssessmentInfos: ExperienceSiteAssessmentInfo[]): void {
186+
private populateExceptionInfo(file: File, experienceSiteAssessmentInfos: ExperienceSiteAssessmentPageInfo[]): void {
174187
try {
175-
const experienceSiteAssessmentInfo: ExperienceSiteAssessmentInfo = {
188+
const experienceSiteAssessmentInfo: ExperienceSiteAssessmentPageInfo = {
176189
name: file.name,
177190
warnings: ['Unknown error occurred'],
178191
errors: [''],
@@ -191,7 +204,7 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
191204

192205
private processRegion(
193206
region: ExpSiteRegion,
194-
experienceSiteAssessmentInfo: ExperienceSiteAssessmentInfo,
207+
experienceSiteAssessmentInfo: ExperienceSiteAssessmentPageInfo,
195208
storage: MigrationStorage,
196209
lookupComponentName: string,
197210
type: string
@@ -213,7 +226,7 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
213226

214227
private processComponent(
215228
component: ExpSiteComponent,
216-
experienceSiteAssessmentInfo: ExperienceSiteAssessmentInfo,
229+
experienceSiteAssessmentInfo: ExperienceSiteAssessmentPageInfo,
217230
storage: MigrationStorage,
218231
lookupComponentName: string,
219232
type: string
@@ -249,7 +262,7 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
249262
private updateComponentAndItsAttributes(
250263
component: ExpSiteComponent,
251264
currentAttribute: ExpSiteComponentAttributes,
252-
experienceSiteAssessmentInfo: ExperienceSiteAssessmentInfo,
265+
experienceSiteAssessmentInfo: ExperienceSiteAssessmentPageInfo,
253266
storage: MigrationStorage,
254267
type: string
255268
): void {
@@ -277,7 +290,7 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
277290
targetName: string,
278291
component: ExpSiteComponent,
279292
currentAttribute: ExpSiteComponentAttributes,
280-
experienceSiteAssessmentInfo: ExperienceSiteAssessmentInfo,
293+
experienceSiteAssessmentInfo: ExperienceSiteAssessmentPageInfo,
281294
storage: MigrationStorage,
282295
type: string
283296
): void {
@@ -309,7 +322,7 @@ export class ExperienceSiteMigration extends BaseRelatedObjectMigration {
309322
targetName: string,
310323
component: ExpSiteComponent,
311324
currentAttribute: ExpSiteComponentAttributes,
312-
experienceSiteAssessmentInfo: ExperienceSiteAssessmentInfo,
325+
experienceSiteAssessmentInfo: ExperienceSiteAssessmentPageInfo,
313326
storage: MigrationStorage,
314327
type: string
315328
): void {

src/migration/related/LwcMigration.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class LwcMigration extends BaseRelatedObjectMigration {
3434
shell.cd(this.projectPath);
3535
Logger.info(assessMessages.getMessage('processingLwcsForAssessment'));
3636
const filesMap = this.processLwcFiles(this.projectPath);
37-
Logger.info(assessMessages.getMessage('successfullyProcessedLwcsForAssessment', [filesMap.size]));
37+
Logger.log(assessMessages.getMessage('successfullyProcessedLwcsForAssessment', [filesMap.size]));
3838
Logger.logVerbose(assessMessages.getMessage('lwcAssessmentResults', [JSON.stringify(filesMap, null, 2)]));
3939
shell.cd(pwd);
4040
return this.processFiles(filesMap, type);
@@ -47,7 +47,7 @@ export class LwcMigration extends BaseRelatedObjectMigration {
4747
Logger.info(migrateMessages.getMessage('processingLwcsForMigration'));
4848
const filesMap = this.processLwcFiles(this.projectPath);
4949
const LWCAssessmentInfos = this.processFiles(filesMap, 'migration');
50-
Logger.info(migrateMessages.getMessage('successfullyProcessedLwcsForMigration', [LWCAssessmentInfos.length]));
50+
Logger.log(migrateMessages.getMessage('successfullyProcessedLwcsForMigration', [LWCAssessmentInfos.length]));
5151
Logger.logVerbose(migrateMessages.getMessage('lwcMigrationResults', [JSON.stringify(LWCAssessmentInfos, null, 2)]));
5252
shell.cd(pwd);
5353
return LWCAssessmentInfos;

src/styles/reportGenerator.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -576,6 +576,10 @@ td {
576576
padding-left: 0.5rem !important;
577577
}
578578

579+
.no-display {
580+
display: none;
581+
}
582+
579583
.diff-cell {
580584
min-width: 30rem;
581585
}

src/templates/assessmentReport.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
</head>
1010

1111
<body>
12+
<div id="props" class="no-display">{{props}}</div>
1213
<div style="margin: 20px">
1314
<div class="report-wrapper">
1415
<div id="scrollable-wrapper" class="scrollable-wrapper">

src/templates/migrationReport.template

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
</head>
1010

1111
<body>
12+
<div id="props" class="no-display">{{props}}</div>
1213
<div class="slds-m-around_medium">
1314
<div class="slds-text-heading_large">
1415
<span>{{heading}}</span>

src/utils/interfaces.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,14 +187,19 @@ export interface FileParser {
187187
// saveToFile(filePath: string, content: string | undefined): void;
188188
}
189189

190-
export interface ExperienceSiteAssessmentInfo extends FileChangeInfo {
190+
export interface ExperienceSiteAssessmentPageInfo extends FileChangeInfo {
191191
warnings: string[];
192192
infos: string[];
193193
hasOmnistudioContent: boolean;
194194
errors: string[];
195195
status: 'Ready for migration' | 'Failed' | 'Successfully migrated' | 'Needs Manual Intervention' | 'Skipped';
196196
}
197197

198+
export interface ExperienceSiteAssessmentInfo {
199+
experienceBundleName: string;
200+
experienceSiteAssessmentPageInfos: ExperienceSiteAssessmentPageInfo[];
201+
}
202+
198203
export interface FileProcessor {
199204
process(file: File, type: string, namespace: string): string;
200205
}

0 commit comments

Comments
 (0)