1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-17 00:33:44 +00:00

PM-17065 Display critical apps (#12867)

This commit is contained in:
Vijay Oommen
2025-01-17 16:05:37 -06:00
committed by GitHub
parent ce2ec07f74
commit 8674fb51db
5 changed files with 101 additions and 99 deletions

View File

@@ -4,16 +4,32 @@ import { Component, DestroyRef, inject, OnInit } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { FormControl } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { debounceTime, map } from "rxjs";
import { combineLatest, debounceTime, map } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SearchModule, TableDataSource, NoItemsModule, Icons } from "@bitwarden/components";
import {
CriticalAppsService,
RiskInsightsDataService,
RiskInsightsReportService,
} from "@bitwarden/bit-common/tools/reports/risk-insights";
import {
ApplicationHealthReportDetailWithCriticalFlag,
ApplicationHealthReportSummary,
} from "@bitwarden/bit-common/tools/reports/risk-insights/models/password-health";
import {
DialogService,
Icons,
NoItemsModule,
SearchModule,
TableDataSource,
} from "@bitwarden/components";
import { CardComponent } from "@bitwarden/tools-card";
import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module";
import { SharedModule } from "@bitwarden/web-vault/app/shared";
import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module";
import { applicationTableMockData } from "./application-table.mock";
import { openAppAtRiskMembersDialog } from "./app-at-risk-members-dialog.component";
import { OrgAtRiskAppsDialogComponent } from "./org-at-risk-apps-dialog.component";
import { OrgAtRiskMembersDialogComponent } from "./org-at-risk-members-dialog.component";
import { RiskInsightsTabType } from "./risk-insights.component";
@Component({
@@ -23,30 +39,38 @@ import { RiskInsightsTabType } from "./risk-insights.component";
imports: [CardComponent, HeaderModule, SearchModule, NoItemsModule, PipesModule, SharedModule],
})
export class CriticalApplicationsComponent implements OnInit {
protected dataSource = new TableDataSource<any>();
protected dataSource = new TableDataSource<ApplicationHealthReportDetailWithCriticalFlag>();
protected selectedIds: Set<number> = new Set<number>();
protected searchControl = new FormControl("", { nonNullable: true });
private destroyRef = inject(DestroyRef);
protected loading = false;
protected organizationId: string;
protected applicationSummary = {} as ApplicationHealthReportSummary;
noItemsIcon = Icons.Security;
// MOCK DATA
protected mockData = applicationTableMockData;
protected mockAtRiskMembersCount = 0;
protected mockAtRiskAppsCount = 0;
protected mockTotalMembersCount = 0;
protected mockTotalAppsCount = 0;
ngOnInit() {
this.activatedRoute.paramMap
this.organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId") ?? "";
combineLatest([
this.dataService.applications$,
this.criticalAppsService.getAppsListForOrg(this.organizationId),
])
.pipe(
takeUntilDestroyed(this.destroyRef),
map(async (params) => {
this.organizationId = params.get("organizationId");
// TODO: use organizationId to fetch data
map(([applications, criticalApps]) => {
const criticalUrls = criticalApps.map((ca) => ca.uri);
const data = applications?.map((app) => ({
...app,
isMarkedAsCritical: criticalUrls.includes(app.applicationName),
})) as ApplicationHealthReportDetailWithCriticalFlag[];
return data?.filter((app) => app.isMarkedAsCritical);
}),
)
.subscribe();
.subscribe((applications) => {
if (applications) {
this.dataSource.data = applications;
this.applicationSummary = this.reportService.generateApplicationsSummary(applications);
}
});
}
goToAllAppsTab = async () => {
@@ -57,13 +81,40 @@ export class CriticalApplicationsComponent implements OnInit {
};
constructor(
protected i18nService: I18nService,
protected activatedRoute: ActivatedRoute,
protected router: Router,
protected dataService: RiskInsightsDataService,
protected criticalAppsService: CriticalAppsService,
protected reportService: RiskInsightsReportService,
protected dialogService: DialogService,
) {
this.dataSource.data = []; //applicationTableMockData;
this.searchControl.valueChanges
.pipe(debounceTime(200), takeUntilDestroyed())
.subscribe((v) => (this.dataSource.filter = v));
}
showAppAtRiskMembers = async (applicationName: string) => {
openAppAtRiskMembersDialog(this.dialogService, {
members:
this.dataSource.data.find((app) => app.applicationName === applicationName)
?.atRiskMemberDetails ?? [],
applicationName,
});
};
showOrgAtRiskMembers = async () => {
this.dialogService.open(OrgAtRiskMembersDialogComponent, {
data: this.reportService.generateAtRiskMemberList(this.dataSource.data),
});
};
showOrgAtRiskApps = async () => {
this.dialogService.open(OrgAtRiskAppsDialogComponent, {
data: this.reportService.generateAtRiskApplicationList(this.dataSource.data),
});
};
trackByFunction(_: number, item: ApplicationHealthReportDetailWithCriticalFlag) {
return item.applicationName;
}
}