@@ -11,7 +11,13 @@ export default class lightningFlowScannerApp extends LightningElement {
1111 @track selectedFlowRecord = null ;
1212 @track flowMetadata = null ;
1313 @track flowName ;
14+ @track scanResult ;
15+ @track numberOfRules ;
16+ @track rules = [ ] ;
17+ @track rulesConfig = null ;
18+ @track isLoading = false ;
1419 conn ;
20+ scriptLoaded = false ;
1521
1622 get isTab1Active ( ) {
1723 return this . activeTab === 1 ;
@@ -21,6 +27,10 @@ export default class lightningFlowScannerApp extends LightningElement {
2127 return this . activeTab === 2 ;
2228 }
2329
30+ get isTab3Active ( ) {
31+ return this . activeTab === 3 ;
32+ }
33+
2434 get FlowsClass ( ) {
2535 return this . activeTab === 1 ? 'active' : '' ;
2636 }
@@ -29,9 +39,37 @@ export default class lightningFlowScannerApp extends LightningElement {
2939 return this . activeTab === 2 ? 'active' : '' ;
3040 }
3141
42+ get ConfigClass ( ) {
43+ return this . activeTab === 3 ? 'active' : '' ;
44+ }
45+
3246 async connectedCallback ( ) {
3347 try {
34- await loadScript ( this , LFSStaticRessource + '/js/jsforce.js' ) ;
48+ await Promise . all ( [
49+ loadScript ( this , LFSStaticRessource + '/jsforce.js' ) ,
50+ loadScript ( this , LFSStaticRessource + '/LFS.js' )
51+ ] ) ;
52+ this . scriptLoaded = true ;
53+
54+ // Fetch rules for Configuration tab, default all to active
55+ this . rules = lightningflowscanner . getRules ( ) . map ( ( rule , index ) => ( {
56+ id : `rule-${ index } ` ,
57+ name : rule . name ,
58+ description : rule . description ,
59+ severity : rule . severity ,
60+ category : rule . category ,
61+ isActive : true // Default all rules to active
62+ } ) ) ;
63+
64+ // Initialize rulesConfig with all rules (correct format: { rules: { [name]: { severity } } })
65+ this . rulesConfig = {
66+ rules : this . rules . reduce ( ( acc , rule ) => {
67+ acc [ rule . name ] = { severity : rule . severity } ; // Include default severity
68+ return acc ;
69+ } , { } )
70+ } ;
71+ console . log ( 'Initial rulesConfig:' , JSON . stringify ( this . rulesConfig ) ) ;
72+
3573 let SF_API_VERSION = '60.0' ;
3674 this . conn = new jsforce . Connection ( {
3775 accessToken : this . accessToken ,
@@ -48,7 +86,7 @@ export default class lightningFlowScannerApp extends LightningElement {
4886 isActive : ! ! record . ActiveVersionId ,
4987 masterLabel : record . ActiveVersionId ? record . ActiveVersion . MasterLabel : record . LatestVersion . MasterLabel ,
5088 processType : record . ActiveVersionId ? record . ActiveVersion . ProcessType : record . LatestVersion . ProcessType ,
51- versionId : record . ActiveVersionId ? record . ActiveVersionId : record . LatestVersionId
89+ versionId : record . ActiveVersionId ? record . ActiveVersionId : record . LatestVersionId // Fixed typo
5290 } ) ) ;
5391
5492 if ( this . records . length > 0 ) {
@@ -58,42 +96,123 @@ export default class lightningFlowScannerApp extends LightningElement {
5896 }
5997 } catch ( error ) {
6098 this . err = error . message ;
61- console . error ( error . message ) ;
99+ console . error ( 'Error in connectedCallback:' , error ) ;
62100 }
63101 }
64102
65103 async loadFlowMetadata ( record ) {
66104 try {
67- let id = record . versionId ;
68- const metadataRes = await this . conn . tooling . query ( `SELECT Id, Fullname, Metadata FROM Flow WHERE Id = '${ id } ' LIMIT 1` ) ;
69- let fullname = metadataRes . records [ 0 ] . FullName ;
70- console . log ( 'fn' , fullname ) ;
71- let fmd = metadataRes . records [ 0 ] . Metadata ;
72- if ( metadataRes && metadataRes . records ) {
73- this . flowName = fullname ;
74- this . flowMetadata = fmd ;
105+ this . isLoading = true ;
106+ const id = record . versionId ;
107+ const metadataRes = await this . conn . tooling . query (
108+ `SELECT Id, FullName, Metadata FROM Flow WHERE Id = '${ id } ' LIMIT 1`
109+ ) ;
110+
111+ if ( metadataRes && metadataRes . records . length ) {
112+ const flow = metadataRes . records [ 0 ] ;
113+ this . flowName = flow . FullName ;
114+ this . flowMetadata = flow . Metadata ;
115+ await this . scanFlow ( this . rulesConfig ) ; // Pass rulesConfig to scan
75116 }
76117 } catch ( error ) {
77118 this . err = error . message ;
78- console . error ( error . message ) ;
119+ console . error ( 'Error in loadFlowMetadata:' , error ) ;
120+ } finally {
121+ this . isLoading = false ;
79122 }
80123 }
81124
82- handleTabClick ( event ) {
83- this . activeTab = parseInt ( event . currentTarget . dataset . tab , 10 ) ;
125+ async scanFlow ( ruleOptions ) {
126+ if ( ! this . scriptLoaded || ! this . flowName || ! this . flowMetadata ) {
127+ return ;
128+ }
129+ try {
130+ this . isLoading = true ;
131+ // Log ruleOptions for debugging
132+ console . log ( 'Scanning with ruleOptions:' , JSON . stringify ( ruleOptions ) ) ;
133+ // Use only active rules for numberOfRules
134+ this . numberOfRules = ruleOptions && ruleOptions . rules ? Object . keys ( ruleOptions . rules ) . length : lightningflowscanner . getRules ( ) . length ;
135+ const flow = new lightningflowscanner . Flow ( this . flowName , this . flowMetadata ) ;
136+
137+ let uri = '/services/data/v60.0/tooling/sobjects/Flow/' + this . selectedFlowRecord . versionId ;
138+ let parsedFlow = { uri, flow } ;
139+
140+ try {
141+ let scanResults = lightningflowscanner . scan ( [ parsedFlow ] , ruleOptions ) ;
142+ this . scanResult = scanResults [ 0 ] ;
143+ console . log ( 'Raw scan results ruleResults count:' , this . scanResult . ruleResults . length ) ;
144+ console . log ( 'Sample raw ruleResult structure:' , JSON . stringify ( this . scanResult . ruleResults [ 0 ] || { } ) ) ;
84145
146+ // Fallback: Filter scan results to include only active rules
147+ const activeRuleNames = ruleOptions && ruleOptions . rules ? Object . keys ( ruleOptions . rules ) : [ ] ;
148+ if ( this . scanResult && this . scanResult . ruleResults && activeRuleNames . length > 0 ) {
149+ this . scanResult . ruleResults = this . scanResult . ruleResults . filter ( ruleResult => {
150+ if ( ! ruleResult . ruleName ) {
151+ console . warn ( 'Skipping ruleResult due to missing ruleName:' , JSON . stringify ( ruleResult ) ) ;
152+ return false ;
153+ }
154+ return activeRuleNames . includes ( ruleResult . ruleName ) ;
155+ } ) ;
156+ console . log ( 'Filtered scan results ruleResults count:' , this . scanResult . ruleResults . length ) ;
157+ }
158+
159+ // Add unique keys to each rule result and its details
160+ this . scanResult . ruleResults = this . scanResult . ruleResults . map ( ( ruleResult , ruleIndex ) => {
161+ return {
162+ ...ruleResult ,
163+ id : `rule-${ ruleIndex } ` ,
164+ details : ruleResult . details . map ( ( detail , detailIndex ) => {
165+ return { ...detail , id : `rule-${ ruleIndex } -detail-${ detailIndex } ` } ;
166+ } )
167+ } ;
168+ } ) ;
169+ } catch ( e ) {
170+ this . err = e . message ;
171+ console . error ( 'Error scanning flow:' , e ) ;
172+ }
173+ } catch ( error ) {
174+ this . err = error . message ;
175+ console . error ( 'Error parsing flow:' , error ) ;
176+ } finally {
177+ this . isLoading = false ;
178+ }
179+ }
85180
181+ handleTabClick ( event ) {
182+ this . activeTab = parseInt ( event . currentTarget . dataset . tab , 10 ) ;
86183 }
87184
88- handleScanFlow ( event ) {
89- console . log ( 'scan' ) ;
185+ async handleScanFlow ( event ) {
90186 const flowId = event . detail . flowId ;
91187 const record = this . records . find ( rec => rec . id === flowId ) ;
92-
188+
93189 if ( record ) {
94- this . loadFlowMetadata ( record , this . conn ) ;
190+ this . isLoading = true ;
95191 this . selectedFlowRecord = record ;
192+ try {
193+ await this . loadFlowMetadata ( record ) ;
194+ this . activeTab = 2 ;
195+ } catch ( error ) {
196+ this . err = error . message ;
197+ console . error ( 'Error in handleScanFlow:' , error ) ;
198+ }
199+ }
200+ }
201+
202+ async handleRuleChange ( event ) {
203+ const updatedRules = event . detail . rules ;
204+ this . rules = updatedRules ;
205+ this . rulesConfig = {
206+ rules : updatedRules . filter ( rule => rule . isActive ) . reduce ( ( acc , rule ) => {
207+ acc [ rule . name ] = { severity : rule . severity } ; // Include user-selected severity
208+ return acc ;
209+ } , { } )
210+ } ;
211+ console . log ( 'Updated rulesConfig:' , JSON . stringify ( this . rulesConfig ) ) ;
212+
213+ // Re-run scan if a flow is already selected
214+ if ( this . flowName && this . flowMetadata && this . selectedFlowRecord ) {
215+ await this . scanFlow ( this . rulesConfig ) ;
96216 }
97- this . activeTab = 2 ;
98217 }
99- }
218+ }
0 commit comments