diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/all-applications.component.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/all-applications.component.ts index d3461490b7c..21373b46eaf 100644 --- a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/all-applications.component.ts +++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/all-applications.component.ts @@ -25,6 +25,7 @@ import { SearchModule, TableDataSource, ToastService, + DialogService, } from "@bitwarden/components"; import { CardComponent } from "@bitwarden/dirt-card"; import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module"; @@ -32,6 +33,7 @@ import { SharedModule } from "@bitwarden/web-vault/app/shared"; import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module"; import { AppTableRowScrollableComponent } from "./app-table-row-scrollable.component"; +import { NoDataModalComponent } from "./no-data-modal.component"; import { ApplicationsLoadingComponent } from "./risk-insights-loading.component"; @Component({ @@ -62,6 +64,7 @@ export class AllApplicationsComponent implements OnInit { totalAtRiskApplicationCount: 0, }; + private hasShownNoDataModal = false; // Flag to prevent multiple modals destroyRef = inject(DestroyRef); constructor( @@ -75,6 +78,7 @@ export class AllApplicationsComponent implements OnInit { protected reportService: RiskInsightsReportService, protected criticalAppsService: CriticalAppsService, protected riskInsightsEncryptionService: RiskInsightsEncryptionService, + protected dialogService: DialogService, ) { this.searchControl.valueChanges .pipe(debounceTime(200), takeUntilDestroyed()) @@ -88,14 +92,44 @@ export class AllApplicationsComponent implements OnInit { this.dataService.reportResults$ .pipe(takeUntilDestroyed(this.destroyRef)) .subscribe((report) => { - if (report) { + if (report && report.data && report.data.length > 0) { this.dataSource.data = report.data; // this.applicationSummary = this.reportService.generateApplicationsSummary(report.data); + this.hasShownNoDataModal = false; // Reset flag when data is available + } else if (!this.hasShownNoDataModal) { + // Show modal only once when no report data is available + void this.showNoDataModal(); } }); } } + /** + * Shows a modal prompting users to run a report when no data is available + */ + private async showNoDataModal(): Promise { + // Set flag to prevent multiple modals + this.hasShownNoDataModal = true; + + const result = this.dialogService.open(NoDataModalComponent, { + data: {}, + disableClose: false, + }); + + if (result) { + // User clicked "Run Report" - you can implement the report running logic here + // TODO: Implement report running functionality + // For example: this.dataService.runReport() or navigate to report page + } + } + + /** + * Checks if the modal should be shown based on current data state + */ + private shouldShowNoDataModal(): boolean { + return !this.dataSource.data || this.dataSource.data.length === 0; + } + goToCreateNewLoginItem = async () => { // TODO: implement this.toastService.showToast({ diff --git a/bitwarden_license/bit-web/src/app/dirt/access-intelligence/no-data-modal.component.ts b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/no-data-modal.component.ts new file mode 100644 index 00000000000..ee5c703b43c --- /dev/null +++ b/bitwarden_license/bit-web/src/app/dirt/access-intelligence/no-data-modal.component.ts @@ -0,0 +1,117 @@ +import { DialogRef, DIALOG_DATA } from "@angular/cdk/dialog"; +import { Component, Inject } from "@angular/core"; + +import { ButtonModule } from "@bitwarden/components"; + +@Component({ + selector: "tools-no-data-modal", + template: ` +
+
+ +
+ +
+

+ Welcome to Risk insights +

+
+ + +
+
+ +

+ To get started, follow these steps to find potential security risks. +

+ + +
+ +
+
+
+ 1 +
+
+

+ Remove individual vaults + (recommended) +

+

+ Turn on the + + Remove individual vault policy + + to get complete visibility of all organization vault data. This setting can be + enabled at any time. +

+
+
+
+ + +
+
+
+ 2 +
+
+

Run the report

+

+ Run the report to see a detailed view of potential at-risk passwords across your + most critical applications. +

+
+
+
+
+
+
+ + +
+ +
+
+ `, + standalone: true, + imports: [ButtonModule], +}) +export class NoDataModalComponent { + constructor( + public dialogRef: DialogRef, + @Inject(DIALOG_DATA) public data: any, + ) {} + + navigateToPolicy(): void { + // TODO: Navigate to the policy page + // Navigate to policy page when implemented + } + + runReport(): void { + this.dialogRef.close(true); + } +}