1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-18 18:33:50 +00:00

check tasks completed after report generation

This commit is contained in:
Brad Deibert
2026-01-21 15:07:29 -08:00
parent cb162c12dc
commit 5c37e9318f

View File

@@ -3,7 +3,6 @@ import {
ChangeDetectionStrategy,
Component,
DestroyRef,
Injector,
OnInit,
Signal,
computed,
@@ -12,7 +11,7 @@ import {
input,
signal,
} from "@angular/core";
import { takeUntilDestroyed, toSignal } from "@angular/core/rxjs-interop";
import { toSignal } from "@angular/core/rxjs-interop";
import { map } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
@@ -60,6 +59,7 @@ export class PasswordChangeMetricComponent implements OnInit {
private readonly _tasks: Signal<SecurityTask[]> = signal<SecurityTask[]>([]);
private readonly _atRiskCipherIds: Signal<CipherId[]> = signal<CipherId[]>([]);
private readonly _hasCriticalApplications: Signal<boolean> = signal<boolean>(false);
private readonly _reportGeneratedAt: Signal<Date> = signal<Date>(null);
// Computed properties
readonly tasksCount = computed(() => this._tasks().length);
@@ -81,8 +81,21 @@ export class PasswordChangeMetricComponent implements OnInit {
}
const inProgressTasks = tasks.filter((task) => task.status === SecurityTaskStatus.Pending);
const assignedIdSet = new Set(inProgressTasks.map((task) => task.cipherId));
const unassignedIds = atRiskIds.filter((id) => !assignedIdSet.has(id));
const inProgressTaskIds = new Set(inProgressTasks.map((task) => task.cipherId));
const completedTasksAfterReportGeneration = tasks.filter(
(task) =>
task.status === SecurityTaskStatus.Completed &&
new Date(task.revisionDate) >= this._reportGeneratedAt(),
);
const completedTaskIds = new Set(
completedTasksAfterReportGeneration.map((task) => task.cipherId),
);
// find cipher ids from last report that do not have a corresponding in progress task (awaiting password reset) OR completed task
const unassignedIds = atRiskIds.filter(
(id) => !inProgressTaskIds.has(id) && !completedTaskIds.has(id),
);
return unassignedIds.length;
});
@@ -110,36 +123,26 @@ export class PasswordChangeMetricComponent implements OnInit {
constructor(
private allActivitiesService: AllActivitiesService,
private i18nService: I18nService,
private injector: Injector,
private riskInsightsDataService: RiskInsightsDataService,
protected securityTasksService: AccessIntelligenceSecurityTasksService,
private toastService: ToastService,
) {
// Setup the _tasks signal by manually passing in the injector
this._tasks = toSignal(this.securityTasksService.tasks$, {
initialValue: [],
injector: this.injector,
});
// Setup the _atRiskCipherIds signal by manually passing in the injector
this._tasks = toSignal(this.securityTasksService.tasks$, { initialValue: [] });
this._atRiskCipherIds = toSignal(
this.riskInsightsDataService.criticalApplicationAtRiskCipherIds$,
{
initialValue: [],
injector: this.injector,
},
{ initialValue: [] },
);
this._hasCriticalApplications = toSignal(
this.riskInsightsDataService.criticalReportResults$.pipe(
takeUntilDestroyed(this.destroyRef),
map((report) => {
return report != null && (report.reportData?.length ?? 0) > 0;
}),
),
{
initialValue: false,
injector: this.injector,
},
{ initialValue: false },
);
this._reportGeneratedAt = toSignal(
this.riskInsightsDataService.enrichedReportData$.pipe(map((report) => report.creationDate)),
{ initialValue: undefined },
);
effect(() => {