Skip to content

Commit f5d0274

Browse files
authored
Merge pull request #117 from VinceFINET/release-1.9
v1.9.5
2 parents 20b4fa9 + 179a830 commit f5d0274

10 files changed

+924
-538
lines changed

force-app/main/default/pages/OrgCheck_ApexComponents_VFP.page

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,19 @@
3838
<li class="slds-tabs_default__item" title="Triggers" role="presentation">
3939
<a class="slds-tabs_default__link" href="javascript:void(0);" role="tab" tabindex="-1" aria-selected="false" aria-controls="tab-default-triggers" id="tab-default-triggers__item">Triggers</a>
4040
</li>
41+
<li class="slds-tabs_default__item" title="Object's triggers count" role="presentation">
42+
<a class="slds-tabs_default__link" href="javascript:void(0);" role="tab" tabindex="-1" aria-selected="false" aria-controls="tab-default-objtriggercounts" id="tab-default-objtriggercounts__item">Object's triggers count</a>
43+
</li>
4144
</ul>
4245
<div id="tab-default-classes" class="slds-tabs_default__content slds-show" role="tabpanel" aria-labelledby="tab-default-classes__item">
4346
<div id="datatable-classes" />
4447
</div>
4548
<div id="tab-default-triggers" class="slds-tabs_default__content slds-hide" role="tabpanel" aria-labelledby="tab-default-triggers__item">
4649
<div id="datatable-triggers" />
4750
</div>
51+
<div id="tab-default-objtriggercounts" class="slds-tabs_default__content slds-hide" role="tabpanel" aria-labelledby="tab-default-objtriggercounts__item">
52+
<div id="datatable-objtriggercounts" />
53+
</div>
4854
</div>
4955
</apex:define>
5056
<apex:define name="html_start_definition_script">
@@ -111,12 +117,21 @@
111117
if (r.isSharingMissing === true) return 1;
112118
}
113119
},
114-
{ name: 'Coverage', type: 'numeric', property: 'fastCoverage',
120+
{ name: 'Coverage', type: 'numeric', property: 'coverage',
115121
formula: (r) => {
116-
return helper.html.render.percentage(r.fastCoverage);
122+
return helper.html.render.percentage(r.coverage);
117123
},
118124
scoreFormula: (r) => {
119-
if (!r.fastCoverage || r.fastCoverage < 0.85) return 1;
125+
if (!r.coverage || r.coverage < 0.85) return 1;
126+
}
127+
},
128+
{ name: 'Related Tests',
129+
formula: (r) => {
130+
let html = '';
131+
if (r.relatedTestClasses) { r.relatedTestClasses.forEach(e => {
132+
html += helper.html.render.link('/'+e, map.apexClasses[e]?.name) + '<br />';
133+
}); }
134+
return html;
120135
}
121136
},
122137
{ name: 'Dependencies',
@@ -147,6 +162,8 @@
147162
helper.html.modal.show('Action needed on Apex classes in the Org!', html);
148163
}
149164

165+
const objectTriggersCountMap = {};
166+
150167
// Render the Apex Triggers data in a table
151168
helper.html.datatable.create({
152169
element: 'datatable-triggers',
@@ -172,9 +189,37 @@
172189
if (r.length > 5000) return 1;
173190
}
174191
},
192+
{ name: 'Contains SOQL', property: 'hasSOQL',
193+
formula: (r) => {
194+
return helper.html.render.checkbox(r.hasSOQL);
195+
},
196+
scoreFormula: (r) => {
197+
if (r.hasSOQL === true) return 1;
198+
}
199+
},
200+
{ name: 'Contains DML', property: 'hasDML',
201+
formula: (r) => {
202+
return helper.html.render.checkbox(r.hasDML);
203+
},
204+
scoreFormula: (r) => {
205+
if (r.hasDML === true) return 1;
206+
}
207+
},
175208
{ name: 'SObject', formula: (r) => {
176-
const objName = map.customObjects[r.sobject];
177-
return objName ? objName.developerName : r.sobject;
209+
const objId = r.sobject;
210+
const objName = map.customObjects[objId]?.developerName || objId;
211+
// ---
212+
// let's calculate (on the fly) the number of active triggers per object!!
213+
const otc = objectTriggersCountMap[objName] || {
214+
object: objName,
215+
activeTriggerCount: 0,
216+
deactiveTriggerCount: 0
217+
};
218+
if (r.isActive === true) otc.activeTriggerCount++;
219+
else if (r.isActive === false) otc.deactiveTriggerCount++;
220+
objectTriggersCountMap[objName] = otc;
221+
// ---
222+
return objName;
178223
}},
179224
{ name : '*Insert', property: 'beforeInsert', formula: (r) => { return helper.html.render.checkbox(r.beforeInsert); }},
180225
{ name : 'Insert*', property: 'afterInsert', formula: (r) => { return helper.html.render.checkbox(r.afterInsert); }},
@@ -203,6 +248,25 @@
203248
sorting: { name: 'Score', order: 'desc' },
204249
showSearch: true
205250
});
251+
252+
// Render the Apex Triggers data in a table
253+
helper.html.datatable.create({
254+
element: 'datatable-objtriggercounts',
255+
columns: [
256+
{ name: 'Name', property: 'object' },
257+
{ name: 'Score', type: 'numeric', property: '##score##' },
258+
{ name: 'Active triggers', type: 'numeric', property: 'activeTriggerCount',
259+
scoreFormula: (r) => {
260+
if (r.activeTriggerCount > 1) return 1;
261+
}
262+
},
263+
{ name: 'Deactive triggers', type: 'numeric', property: 'deactiveTriggerCount' }
264+
],
265+
data: objectTriggersCountMap,
266+
sorting: { name: 'Score', order: 'desc' },
267+
showSearch: true
268+
});
269+
206270
},
207271
actions: {
208272
exportTable: [{
@@ -213,6 +277,10 @@
213277
table: 'datatable-triggers',
214278
visibleTab: 'tab-default-triggers__item',
215279
filename: 'ApexTriggers'
280+
}, {
281+
table: 'datatable-objtriggercounts',
282+
visibleTab: 'tab-default-objtriggercounts__item',
283+
filename: 'ObjectTriggersCount'
216284
}],
217285
clearCache: {
218286
show: true
@@ -231,7 +299,9 @@
231299
'<li><code>+1</code> if the API version of the trigger is too old (3 years old),</li>'+
232300
'<li><code>+1</code> if the trigger needs recompilation,</li>'+
233301
'<li><code>+1</code> if the trigger is inactive (what is the use of an inactive trigger, why not delete it?).</li>'+
234-
'<li><code>+1</code> if the trigger has more than 5000 characters without comments (in that case we suspect logic!).</ul>',
302+
'<li><code>+1</code> if the trigger has more than 5000 characters without comments (in that case we suspect logic!).</li>'+
303+
'<li><code>+1</code> if the trigger contains a direct SOQL or DML statement (we do not consider indirect SOQL or DML included in the call of other classes!!).</li>'+
304+
'</ul>',
235305
'The <b>DEPENDENCIES</b> is showing where the classes or triggers is used and '+
236306
'what it is using. You can click on each diagram to have it shown in '+
237307
'a dialog box.'

force-app/main/default/pages/OrgCheck_Batches_VFP.page

Lines changed: 81 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,27 +11,101 @@
1111
</apex:define>
1212
<apex:define name="html_content_core">
1313
<div id="datatable" />
14+
15+
<div class="slds-tabs_default">
16+
<ul class="slds-tabs_default__nav" role="tablist">
17+
<li class="slds-tabs_default__item slds-is-active" title="Apex Jobs" role="presentation">
18+
<a class="slds-tabs_default__link" href="javascript:void(0);" role="tab" tabindex="0" aria-selected="true" aria-controls="tab-default-apexjobs" id="tab-default-apexjobs__item">Apex Jobs</a>
19+
</li>
20+
<li class="slds-tabs_default__item" title="Scheduled Jobs" role="presentation">
21+
<a class="slds-tabs_default__link" href="javascript:void(0);" role="tab" tabindex="-1" aria-selected="false" aria-controls="tab-default-scheduledjobs" id="tab-default-scheduledjobs__item">Scheduled Jobs</a>
22+
</li>
23+
<li class="slds-tabs_default__item" title="Schedulable classes not yet scheduled" role="presentation">
24+
<a class="slds-tabs_default__link" href="javascript:void(0);" role="tab" tabindex="-1" aria-selected="false" aria-controls="tab-default-notscheduledjobs" id="tab-default-notscheduledjobs__item">Schedulable classes not yet scheduled</a>
25+
</li>
26+
</ul>
27+
<div id="tab-default-apexjobs" class="slds-tabs_default__content slds-show" role="tabpanel" aria-labelledby="tab-default-apexjobs__item">
28+
<div id="datatable-apexjobs" />
29+
</div>
30+
<div id="tab-default-scheduledjobs" class="slds-tabs_default__content slds-hide" role="tabpanel" aria-labelledby="tab-default-scheduledjobs__item">
31+
<div id="datatable-scheduledjobs" />
32+
</div>
33+
<div id="tab-default-notscheduledjobs" class="slds-tabs_default__content slds-hide" role="tabpanel" aria-labelledby="tab-default-notscheduledjobs__item">
34+
<div id="datatable-notscheduledjobs" />
35+
</div>
36+
</div>
1437
</apex:define>
1538
<apex:define name="html_start_definition_script">
1639
<script>
1740
function start2(controller, helper) {
41+
42+
// Initialize TABS bindings
43+
helper.html.tabs.initialize('slds-tabs_default__item', 'slds-tabs_default__content', 'slds-button');
44+
45+
// RUN CONTROLLER
1846
controller.run({
19-
datasets: [ 'batches' ],
47+
datasets: [ 'batchesApexJobs', 'batchesScheduledJobs', 'users', 'apexClasses' ],
2048
onRecords: function(map) {
2149

22-
// Render the data in a table
50+
// Render the data in a table for failed Apex Jobs
2351
helper.html.datatable.create({
24-
element: 'datatable',
52+
element: 'datatable-apexjobs',
2553
columns: [
26-
{ name: 'Context', property: 'context' },
2754
{ name: 'Type', property: 'type' },
28-
{ name: 'Status', property: 'status' },
29-
{ name: 'Message', property: 'message' }
55+
{ name: 'Apex Context', property: 'context' },
56+
{ name: 'Score', type: 'numeric', property: '##score##' },
57+
{ name: 'Status', property: 'status',
58+
scoreFormula: (r) => {
59+
if (r.status === 'Failed') return 1;
60+
}
61+
},
62+
{ name: 'Message', property: 'message' },
63+
{ name: 'Count', type: 'numeric', property: 'numIds' },
64+
{ name: 'Errors', type: 'numeric', property: 'numErrors' }
3065
],
31-
data: map.apexTriggers,
66+
data: map.batchesApexJobs,
3267
sorting: { name: 'Context', order: 'asc' },
3368
showSearch: true
3469
});
70+
71+
// Render the data in a table for Scheduled Jobs
72+
helper.html.datatable.create({
73+
element: 'datatable-scheduledjobs',
74+
columns: [
75+
{ name: 'Name', property: 'name' },
76+
{ name: 'Type', property: 'type' },
77+
{ name: 'Status', property: 'status',
78+
scoreFormula: (r) => {
79+
if (r.status !== 'WAITING') return 1;
80+
}
81+
},
82+
{ name: 'user', formula: (r) => { return helper.html.render.link('/'+r.userid, (map.users[r.userid]?.name || r.userid)); }},
83+
{ name: 'start', property: 'start' },
84+
{ name: 'end', property: 'end' },
85+
{ name: 'timezone', property: 'timezone' }
86+
],
87+
data: map.batchesScheduledJobs,
88+
sorting: { name: 'Context', order: 'asc' },
89+
showSearch: true
90+
});
91+
92+
// Render the data in a table for Not Scheduled Jobs
93+
helper.html.datatable.create({
94+
element: 'datatable-notscheduledjobs',
95+
columns: [
96+
{ name: 'Name', formula: (r) => { return helper.html.render.link('/'+r.id, r.name); }},
97+
{ name: 'Score', type: 'numeric', property: '##score##' },
98+
{ name: 'Is Scheduled?',
99+
formula: (r) => { return helper.html.render.checkbox(r.isScheduled === true); },
100+
scoreFormula: (r) => { if (r.isScheduled !== true) return 1; }
101+
},
102+
{ name: 'Package', property: 'namespace' }
103+
],
104+
data: map.apexClasses,
105+
sorting: { name: 'Score', order: 'desc' },
106+
filtering: { formula: (r) => { return (r.interfaces && r.interfaces.includes('System.Schedulable')); }},
107+
showSearch: true
108+
});
35109
},
36110
actions: {
37111
clearCache: {

force-app/main/default/pages/OrgCheck_Home_VFP.page

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,12 @@
379379
options: [
380380
{ label: 'Hide external roles (from Community).', id: 'filter.HideExternalRoles' }
381381
]
382+
},
383+
{
384+
label: 'Profiles and Permission Sets',
385+
options: [
386+
{ label: 'Do not fetch the CRUDs on profiles and permission sets.', id: 'filter.HideCRUDsProfilesPermSets' }
387+
]
382388
}
383389
].forEach(p => {
384390
const fieldset1 = helper.html.element.create('fieldset');

0 commit comments

Comments
 (0)