@@ -7,6 +7,7 @@ export class ResultsProvider implements vscode.TreeDataProvider<ResultItem> {
77
88 private results : ScanResult [ ] = [ ] ;
99 private diagnosticCollection : vscode . DiagnosticCollection ;
10+ private hasBeenScanned : boolean = false ;
1011
1112 constructor ( ) {
1213 // Create a diagnostic collection for CodeQL security issues
@@ -19,6 +20,7 @@ export class ResultsProvider implements vscode.TreeDataProvider<ResultItem> {
1920
2021 setResults ( results : ScanResult [ ] ) : void {
2122 this . results = results ;
23+ this . hasBeenScanned = true ;
2224 this . updateDiagnostics ( results ) ;
2325 this . refresh ( ) ;
2426 }
@@ -29,6 +31,7 @@ export class ResultsProvider implements vscode.TreeDataProvider<ResultItem> {
2931
3032 clearResults ( ) : void {
3133 this . results = [ ] ;
34+ this . hasBeenScanned = false ;
3235 this . diagnosticCollection . clear ( ) ;
3336 this . refresh ( ) ;
3437 }
@@ -40,6 +43,30 @@ export class ResultsProvider implements vscode.TreeDataProvider<ResultItem> {
4043 getChildren ( element ?: ResultItem ) : Thenable < ResultItem [ ] > {
4144 if ( ! element ) {
4245 // Root level - group by language
46+ if ( ! this . results || this . results . length === 0 ) {
47+ // Show different messages based on whether a scan has been run
48+ const message = this . hasBeenScanned
49+ ? '✅ No security alerts found'
50+ : '🔍 Run a CodeQL scan to see security alerts' ;
51+ const tooltip = this . hasBeenScanned
52+ ? 'No security vulnerabilities were found in the scanned code'
53+ : 'Click "CodeQL: Run Scan" to analyze your code for security vulnerabilities' ;
54+
55+ return Promise . resolve ( [
56+ new ResultItem (
57+ message ,
58+ vscode . TreeItemCollapsibleState . None ,
59+ 'noResults' ,
60+ undefined ,
61+ undefined ,
62+ undefined ,
63+ undefined ,
64+ undefined ,
65+ tooltip
66+ )
67+ ] ) ;
68+ }
69+
4370 const groups = this . groupByLanguage ( this . results ) ;
4471 return Promise . resolve (
4572 Object . entries ( groups ) . map ( ( [ language , results ] ) =>
@@ -293,12 +320,13 @@ export class ResultItem extends vscode.TreeItem {
293320 constructor (
294321 public readonly label : string ,
295322 public readonly collapsibleState : vscode . TreeItemCollapsibleState ,
296- public readonly type : 'language' | 'severity' | 'result' | 'flowStep' ,
323+ public readonly type : 'language' | 'severity' | 'result' | 'flowStep' | 'noResults' ,
297324 public readonly language ?: string ,
298325 public readonly results ?: ScanResult [ ] ,
299326 public readonly result ?: ScanResult ,
300327 public readonly severity ?: string ,
301- public readonly flowStep ?: FlowStep
328+ public readonly flowStep ?: FlowStep ,
329+ private readonly customTooltip ?: string
302330 ) {
303331 super ( label , collapsibleState ) ;
304332
@@ -310,6 +338,9 @@ export class ResultItem extends vscode.TreeItem {
310338 }
311339
312340 private getTooltip ( ) : string {
341+ if ( this . customTooltip ) {
342+ return this . customTooltip ;
343+ }
313344 if ( this . type === 'language' ) {
314345 return `${ this . results ?. length || 0 } ${ this . language } language issues` ;
315346 } else if ( this . type === 'severity' ) {
@@ -321,6 +352,8 @@ export class ResultItem extends vscode.TreeItem {
321352 return `${ this . result . ruleId } : ${ this . result . message } \\nFile: ${ this . result . location . file } \\nLine: ${ this . result . location . startLine } ${ flowInfo } ` ;
322353 } else if ( this . type === 'flowStep' && this . flowStep ) {
323354 return `Flow step ${ this . flowStep . stepIndex + 1 } \\nFile: ${ this . flowStep . file } \\nLine: ${ this . flowStep . startLine } ${ this . flowStep . message ? `\\nMessage: ${ this . flowStep . message } ` : '' } ` ;
355+ } else if ( this . type === 'noResults' ) {
356+ return 'No security vulnerabilities were found in the scanned code' ;
324357 }
325358 return this . label ;
326359 }
@@ -393,6 +426,13 @@ export class ResultItem extends vscode.TreeItem {
393426 } else {
394427 return new vscode . ThemeIcon ( 'arrow-right' , new vscode . ThemeColor ( 'charts.blue' ) ) ; // Intermediate step
395428 }
429+ } else if ( this . type === 'noResults' ) {
430+ // Use different icons based on whether scan has been run
431+ if ( this . label . includes ( 'No security alerts found' ) ) {
432+ return new vscode . ThemeIcon ( 'check-all' , new vscode . ThemeColor ( 'charts.green' ) ) ;
433+ } else {
434+ return new vscode . ThemeIcon ( 'search' , new vscode . ThemeColor ( 'charts.blue' ) ) ;
435+ }
396436 }
397437 return new vscode . ThemeIcon ( 'circle-outline' ) ;
398438 }
0 commit comments