mirror of
https://github.com/bitwarden/browser
synced 2026-02-05 03:03:26 +00:00
refactor: replace first report prompt in all-apps files with a dedicated dialog component
This commit is contained in:
@@ -1,68 +1,3 @@
|
||||
<!-- Risk Insights First Report Prompt -->
|
||||
@if (showFirstReportPromptDialog) {
|
||||
<!-- Modal backdrop -->
|
||||
<div
|
||||
class="tw-fixed tw-bg-black tw-bg-opacity-30 tw-inset-0 tw-z-50 tw-flex tw-items-center tw-justify-center tw-p-4"
|
||||
(click)="closePrompt()"
|
||||
cdkTrapFocus
|
||||
cdkTrapFocusAutoCapture
|
||||
>
|
||||
<!-- Modal container - prevent click propagation -->
|
||||
<div
|
||||
(click)="$event.stopPropagation()"
|
||||
class="tw-flex tw-justify-center tw-max-h-[90vh] tw-overflow-y-auto"
|
||||
>
|
||||
<bit-simple-dialog class="!tw-w-auto !tw-max-w-4xl" hideIcon="true">
|
||||
<span bitDialogTitle>Welcome to Risk insights</span>
|
||||
<span bitDialogContent>
|
||||
<div class="tw-text-left">
|
||||
<p class="tw-text-muted tw-mb-6 tw-text-center">
|
||||
To get started, follow these steps to find potential security risks.
|
||||
</p>
|
||||
|
||||
<div class="tw-space-y-4">
|
||||
<div
|
||||
class="tw-bg-background-alt tw-p-4 tw-rounded-lg tw-border tw-border-solid tw-border-secondary-100"
|
||||
>
|
||||
<h3 class="tw-font-semibold tw-text-main tw-mb-2">
|
||||
1. Enforce organization data ownership
|
||||
<span class="tw-text-muted tw-font-normal">(recommended)</span>
|
||||
</h3>
|
||||
<p class="tw-text-muted tw-leading-relaxed">
|
||||
Turn on the
|
||||
<a
|
||||
href="https://bitwarden.com/help/policies/#enforce-organization-data-ownership"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="tw-text-primary-600 tw-underline hover:tw-text-primary-700 tw-cursor-pointer"
|
||||
>enforce organization data ownership policy</a
|
||||
>
|
||||
to get complete visibility of all organization vault data. This setting can be
|
||||
enabled at any time.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="tw-bg-background-alt tw-p-4 tw-rounded-lg tw-border tw-border-solid tw-border-secondary-100"
|
||||
>
|
||||
<h3 class="tw-font-semibold tw-text-main tw-mb-2">2. Run the report</h3>
|
||||
<p class="tw-text-muted tw-leading-relaxed">
|
||||
Run the report to see a detailed view of potential at-risk passwords across your
|
||||
most critical applications.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton buttonType="primary" type="button" (click)="runReport()">
|
||||
Run Report
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-simple-dialog>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (dataService.isLoading$ | async) {
|
||||
<tools-risk-insights-loading></tools-risk-insights-loading>
|
||||
} @else {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { CdkTrapFocus } from "@angular/cdk/a11y";
|
||||
import { Component, DestroyRef, inject, OnInit } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { FormControl } from "@angular/forms";
|
||||
@@ -27,8 +26,6 @@ import {
|
||||
TableDataSource,
|
||||
ToastService,
|
||||
DialogService,
|
||||
ButtonModule,
|
||||
DialogModule,
|
||||
} from "@bitwarden/components";
|
||||
import { CardComponent } from "@bitwarden/dirt-card";
|
||||
import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module";
|
||||
@@ -36,14 +33,12 @@ 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 { FirstReportPromptDialogComponent } from "./first-report-prompt-dialog.component";
|
||||
import { ApplicationsLoadingComponent } from "./risk-insights-loading.component";
|
||||
|
||||
@Component({
|
||||
selector: "tools-all-applications",
|
||||
templateUrl: "./all-applications.component.html",
|
||||
host: {
|
||||
"(keydown.escape)": "handleEscape($event)", // escape dialog with keyboard
|
||||
},
|
||||
imports: [
|
||||
ApplicationsLoadingComponent,
|
||||
HeaderModule,
|
||||
@@ -54,9 +49,6 @@ import { ApplicationsLoadingComponent } from "./risk-insights-loading.component"
|
||||
SharedModule,
|
||||
AppTableRowScrollableComponent,
|
||||
IconButtonModule,
|
||||
ButtonModule,
|
||||
DialogModule,
|
||||
CdkTrapFocus,
|
||||
],
|
||||
})
|
||||
export class AllApplicationsComponent implements OnInit {
|
||||
@@ -74,7 +66,6 @@ export class AllApplicationsComponent implements OnInit {
|
||||
|
||||
private hasShownFirstReportPrompt = false; // Flag to prevent multiple prompts
|
||||
private organizationId: string | null = null;
|
||||
protected showFirstReportPromptDialog = false; // Controls visibility of the simple dialog
|
||||
destroyRef = inject(DestroyRef);
|
||||
|
||||
constructor(
|
||||
@@ -112,9 +103,6 @@ export class AllApplicationsComponent implements OnInit {
|
||||
this.dataSource.data = report.data;
|
||||
// this.applicationSummary = this.reportService.generateApplicationsSummary(report.data);
|
||||
this.hasShownFirstReportPrompt = false; // Reset flag when data is available
|
||||
if (this.showFirstReportPromptDialog) {
|
||||
this.closePrompt(); // Use closePrompt method to properly restore scroll
|
||||
}
|
||||
} else if (!this.hasShownFirstReportPrompt) {
|
||||
// Show prompt only once when no report data is available
|
||||
void this.showFirstReportPrompt();
|
||||
@@ -130,44 +118,8 @@ export class AllApplicationsComponent implements OnInit {
|
||||
// Set flag to prevent multiple prompts
|
||||
this.hasShownFirstReportPrompt = true;
|
||||
|
||||
// Show the simple dialog and prevent body scroll
|
||||
this.showFirstReportPromptDialog = true;
|
||||
document.body.classList.add("tw-overflow-hidden");
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the report and closes the prompt
|
||||
*/
|
||||
async runReport(): Promise<void> {
|
||||
// Close the prompt first
|
||||
this.closePrompt();
|
||||
|
||||
// Add a small delay to ensure prompt closes before triggering the report
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// Trigger the report generation
|
||||
if (this.dataService) {
|
||||
this.dataService.triggerReport();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the prompt (called when clicking backdrop or pressing Escape)
|
||||
*/
|
||||
closePrompt(): void {
|
||||
this.showFirstReportPromptDialog = false;
|
||||
// Restore body scroll
|
||||
document.body.classList.remove("tw-overflow-hidden");
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles Escape key press to close prompt
|
||||
*/
|
||||
handleEscape(event: KeyboardEvent): void {
|
||||
if (this.showFirstReportPromptDialog) {
|
||||
this.closePrompt();
|
||||
event.stopPropagation();
|
||||
}
|
||||
// Open the dialog using the dialog service
|
||||
FirstReportPromptDialogComponent.open(this.dialogService);
|
||||
}
|
||||
|
||||
goToCreateNewLoginItem = async () => {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<bit-simple-dialog hideIcon="true">
|
||||
<span bitDialogTitle>Welcome to Risk insights</span>
|
||||
<span bitDialogContent>
|
||||
<div class="tw-text-left">
|
||||
<p class="tw-text-muted tw-mb-6 tw-text-center">
|
||||
To get started, follow these steps to find potential security risks.
|
||||
</p>
|
||||
|
||||
<div class="tw-space-y-4">
|
||||
<div
|
||||
class="tw-bg-background-alt tw-p-4 tw-rounded-lg tw-border tw-border-solid tw-border-secondary-100"
|
||||
>
|
||||
<h3 class="tw-font-semibold tw-text-main tw-mb-2">
|
||||
1. Enforce organization data ownership
|
||||
<span class="tw-text-muted tw-font-normal">(recommended)</span>
|
||||
</h3>
|
||||
<p class="tw-text-muted tw-leading-relaxed">
|
||||
Turn on the
|
||||
<a
|
||||
href="https://bitwarden.com/help/policies/#enforce-organization-data-ownership"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="tw-text-primary-600 tw-underline hover:tw-text-primary-700 tw-cursor-pointer"
|
||||
>enforce organization data ownership policy</a
|
||||
>
|
||||
to get complete visibility of all organization vault data. This setting can be enabled
|
||||
at any time.
|
||||
</p>
|
||||
</div>
|
||||
<div
|
||||
class="tw-bg-background-alt tw-p-4 tw-rounded-lg tw-border tw-border-solid tw-border-secondary-100"
|
||||
>
|
||||
<h3 class="tw-font-semibold tw-text-main tw-mb-2">2. Run the report</h3>
|
||||
<p class="tw-text-muted tw-leading-relaxed">
|
||||
Run the report to see a detailed view of potential at-risk passwords across your most
|
||||
critical applications.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton buttonType="primary" type="button" (click)="runReport()">Run Report</button>
|
||||
</ng-container>
|
||||
</bit-simple-dialog>
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Component, inject } from "@angular/core";
|
||||
|
||||
import { RiskInsightsDataService } from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||
import { ButtonModule, DialogModule, DialogRef, DialogService } from "@bitwarden/components";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./first-report-prompt-dialog.component.html",
|
||||
imports: [ButtonModule, DialogModule],
|
||||
})
|
||||
export class FirstReportPromptDialogComponent {
|
||||
private dialogRef = inject(DialogRef);
|
||||
private dataService = inject(RiskInsightsDataService);
|
||||
|
||||
static open(dialogService: DialogService) {
|
||||
return dialogService.open<boolean>(FirstReportPromptDialogComponent);
|
||||
}
|
||||
|
||||
async runReport(): Promise<void> {
|
||||
// Close the dialog first
|
||||
this.dialogRef.close(true);
|
||||
|
||||
// Add a small delay to ensure dialog closes before triggering the report
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
|
||||
// Trigger the report generation
|
||||
if (this.dataService) {
|
||||
this.dataService.triggerReport();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user