diff --git a/apps/web/src/app/dirt/reports/pages/cipher-report.component.ts b/apps/web/src/app/dirt/reports/pages/cipher-report.component.ts index d098be56663..2524b49dff1 100644 --- a/apps/web/src/app/dirt/reports/pages/cipher-report.component.ts +++ b/apps/web/src/app/dirt/reports/pages/cipher-report.component.ts @@ -48,6 +48,8 @@ export abstract class CipherReportComponent implements OnDestroy { filterStatus: any = [0]; showFilterToggle: boolean = false; + selectedFilterChip: string = "0"; + chipSelectOptions: { label: string; value: string; icon: string }[]; vaultMsg: string = "vault"; currentFilterStatus: number | string = 0; protected filterOrgStatus$ = new BehaviorSubject(0); @@ -288,6 +290,15 @@ export abstract class CipherReportComponent implements OnDestroy { return await this.cipherService.getAllDecrypted(activeUserId); } + protected canDisplayToggleGroup(): boolean { + return this.filterStatus.length <= 4; + } + + async filterOrgToggleChipSelect(filterId: string | null) { + const selectedFilterId = filterId ?? 0; + await this.filterOrgToggle(selectedFilterId); + } + protected filterCiphersByOrg(ciphersList: CipherView[]) { this.allCiphers = [...ciphersList]; @@ -309,5 +320,27 @@ export abstract class CipherReportComponent implements OnDestroy { this.showFilterToggle = false; this.vaultMsg = "vault"; } + + this.chipSelectOptions = this.setupChipSelectOptions(this.filterStatus); + } + + private setupChipSelectOptions(filters: string[]) { + const options = filters.map((filterId: string, index: number) => { + let icon: string = "bwi-business"; + icon = index === 0 ? "bwi-folder" : icon; + icon = index === 1 ? "bwi-user" : icon; + + const name = this.getName(filterId); + const count = this.getCount(filterId); + const labelSuffix = count != null ? ` (${count})` : ""; + + return { + label: name + labelSuffix, + value: filterId, + icon, + }; + }); + + return options; } } diff --git a/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.html b/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.html index fcdb3f6ca64..3766074b514 100644 --- a/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.html +++ b/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.html @@ -13,19 +13,36 @@ {{ "exposedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }} - - - - {{ getName(status) }} - {{ getCount(status) }} - - - + + @if (!isAdminConsoleActive && canDisplayToggleGroup()) { + + + + {{ getName(status) }} + {{ getCount(status) }} + + + + } + + + @if (!isAdminConsoleActive && !canDisplayToggleGroup()) { + + } + + diff --git a/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.ts b/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.ts index 51bdde3eda8..1f043328389 100644 --- a/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.ts +++ b/apps/web/src/app/dirt/reports/pages/exposed-passwords-report.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from "@angular/core"; +import { ChangeDetectionStrategy, Component, OnInit } from "@angular/core"; import { AuditService } from "@bitwarden/common/abstractions/audit.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; @@ -18,9 +18,8 @@ import { CipherReportComponent } from "./cipher-report.component"; type ReportResult = CipherView & { exposedXTimes: number }; -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ + changeDetection: ChangeDetectionStrategy.OnPush, selector: "app-exposed-passwords-report", templateUrl: "exposed-passwords-report.component.html", standalone: false, @@ -113,4 +112,9 @@ export class ExposedPasswordsReportComponent extends CipherReportComponent imple ): Promise { return await this.isPasswordExposed(updatedCipherView); } + + async filterOrgToggleChipSelect(filterId: string | null) { + const selectedFilterId = filterId ?? 0; + await this.filterOrgToggle(selectedFilterId); + } } diff --git a/apps/web/src/app/dirt/reports/pages/organizations/exposed-passwords-report.component.ts b/apps/web/src/app/dirt/reports/pages/organizations/exposed-passwords-report.component.ts index f83614557bd..2797df669a5 100644 --- a/apps/web/src/app/dirt/reports/pages/organizations/exposed-passwords-report.component.ts +++ b/apps/web/src/app/dirt/reports/pages/organizations/exposed-passwords-report.component.ts @@ -16,7 +16,7 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { DialogService } from "@bitwarden/components"; +import { ChipSelectComponent, DialogService } from "@bitwarden/components"; import { PasswordRepromptService, CipherFormConfigService } from "@bitwarden/vault"; import { HeaderModule } from "../../../../layouts/header/header.module"; @@ -42,7 +42,7 @@ import { ExposedPasswordsReportComponent as BaseExposedPasswordsReportComponent RoutedVaultFilterService, RoutedVaultFilterBridgeService, ], - imports: [SharedModule, HeaderModule, OrganizationBadgeModule, PipesModule], + imports: [SharedModule, HeaderModule, OrganizationBadgeModule, PipesModule, ChipSelectComponent], }) export class ExposedPasswordsReportComponent extends BaseExposedPasswordsReportComponent diff --git a/apps/web/src/app/dirt/reports/pages/organizations/reused-passwords-report.component.ts b/apps/web/src/app/dirt/reports/pages/organizations/reused-passwords-report.component.ts index 3944e2edfcb..2e727e114c2 100644 --- a/apps/web/src/app/dirt/reports/pages/organizations/reused-passwords-report.component.ts +++ b/apps/web/src/app/dirt/reports/pages/organizations/reused-passwords-report.component.ts @@ -15,7 +15,7 @@ import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.servi import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction"; import { Cipher } from "@bitwarden/common/vault/models/domain/cipher"; import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view"; -import { DialogService } from "@bitwarden/components"; +import { ChipSelectComponent, DialogService } from "@bitwarden/components"; import { CipherFormConfigService, PasswordRepromptService } from "@bitwarden/vault"; import { HeaderModule } from "../../../../layouts/header/header.module"; @@ -41,7 +41,7 @@ import { ReusedPasswordsReportComponent as BaseReusedPasswordsReportComponent } RoutedVaultFilterService, RoutedVaultFilterBridgeService, ], - imports: [SharedModule, HeaderModule, OrganizationBadgeModule, PipesModule], + imports: [SharedModule, HeaderModule, OrganizationBadgeModule, PipesModule, ChipSelectComponent], }) export class ReusedPasswordsReportComponent extends BaseReusedPasswordsReportComponent diff --git a/apps/web/src/app/dirt/reports/pages/reused-passwords-report.component.html b/apps/web/src/app/dirt/reports/pages/reused-passwords-report.component.html index d09dfa81fd4..61e3df3afee 100644 --- a/apps/web/src/app/dirt/reports/pages/reused-passwords-report.component.html +++ b/apps/web/src/app/dirt/reports/pages/reused-passwords-report.component.html @@ -19,19 +19,34 @@ {{ "reusedPasswordsFoundReportDesc" | i18n: (ciphers.length | number) : vaultMsg }} - - - - {{ getName(status) }} - {{ getCount(status) }} - - - + @if (!isAdminConsoleActive && canDisplayToggleGroup()) { + + + + {{ getName(status) }} + {{ getCount(status) }} + + + + } + + + @if (!isAdminConsoleActive && !canDisplayToggleGroup()) { + + } + diff --git a/apps/web/src/app/dirt/reports/reports.module.ts b/apps/web/src/app/dirt/reports/reports.module.ts index 358768e71ee..841f76b3b0f 100644 --- a/apps/web/src/app/dirt/reports/reports.module.ts +++ b/apps/web/src/app/dirt/reports/reports.module.ts @@ -1,6 +1,7 @@ import { CommonModule } from "@angular/common"; import { NgModule } from "@angular/core"; +import { ChipSelectComponent } from "@bitwarden/components"; import { CipherFormConfigService, DefaultCipherFormConfigService } from "@bitwarden/vault"; import { HeaderModule } from "../../layouts/header/header.module"; @@ -31,6 +32,7 @@ import { ReportsSharedModule } from "./shared"; OrganizationBadgeModule, PipesModule, HeaderModule, + ChipSelectComponent, ], declarations: [ BreachReportComponent,