1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-13 06:54:07 +00:00
Files
browser/apps/web/src/app/tools/access-intelligence/all-applications.component.ts
2024-11-15 09:30:07 -08:00

135 lines
4.8 KiB
TypeScript

import { Component, DestroyRef, inject, OnInit } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { FormControl } from "@angular/forms";
import { ActivatedRoute } from "@angular/router";
import { debounceTime, firstValueFrom, map } from "rxjs";
// eslint-disable-next-line no-restricted-imports
import {
PasswordHealthService,
MemberCipherDetailsApiService,
ApplicationHealthReport,
} from "@bitwarden/bit-common/tools/reports/risk-insights";
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import {
Icons,
NoItemsModule,
SearchModule,
TableDataSource,
ToastService,
} from "@bitwarden/components";
import { CardComponent } from "@bitwarden/tools-card";
import { HeaderModule } from "../../layouts/header/header.module";
import { SharedModule } from "../../shared";
import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module";
@Component({
standalone: true,
selector: "tools-all-applications",
templateUrl: "./all-applications.component.html",
imports: [HeaderModule, CardComponent, SearchModule, PipesModule, NoItemsModule, SharedModule],
providers: [MemberCipherDetailsApiService],
})
export class AllApplicationsComponent implements OnInit {
protected dataSource = new TableDataSource<any>();
protected selectedIds: Set<number> = new Set<number>();
protected searchControl = new FormControl("", { nonNullable: true });
private destroyRef = inject(DestroyRef);
protected loading = true;
protected organization: Organization;
noItemsIcon = Icons.Security;
protected markingAsCritical = false;
protected applicationHealthReport: ApplicationHealthReport;
isCritialAppsFeatureEnabled = false;
passwordHealthService = new PasswordHealthService(
this.passwordStrengthService,
this.auditService,
this.cipherService,
this.memberCipherDetailsApiService,
);
async ngOnInit() {
this.activatedRoute.paramMap
.pipe(
takeUntilDestroyed(this.destroyRef),
map(async (params) => {
const organizationId = params.get("organizationId");
this.organization = await firstValueFrom(this.organizationService.get$(organizationId));
this.applicationHealthReport =
await this.passwordHealthService.generateReportDetails(organizationId);
this.dataSource.data = this.applicationHealthReport.details;
this.loading = false;
}),
)
.subscribe();
this.isCritialAppsFeatureEnabled = await this.configService.getFeatureFlag(
FeatureFlag.CriticalApps,
);
}
constructor(
protected cipherService: CipherService,
protected passwordStrengthService: PasswordStrengthServiceAbstraction,
protected auditService: AuditService,
protected i18nService: I18nService,
protected activatedRoute: ActivatedRoute,
protected toastService: ToastService,
protected organizationService: OrganizationService,
protected configService: ConfigService,
protected memberCipherDetailsApiService: MemberCipherDetailsApiService,
) {
this.searchControl.valueChanges
.pipe(debounceTime(200), takeUntilDestroyed())
.subscribe((v) => (this.dataSource.filter = v));
}
goToCreateNewLoginItem = async () => {
// TODO: implement
this.toastService.showToast({
variant: "warning",
title: null,
message: "Not yet implemented",
});
};
markAppsAsCritical = async () => {
// TODO: Send to API once implemented
this.markingAsCritical = true;
return new Promise((resolve) => {
setTimeout(() => {
this.selectedIds.clear();
this.toastService.showToast({
variant: "success",
title: null,
message: this.i18nService.t("appsMarkedAsCritical"),
});
resolve(true);
this.markingAsCritical = false;
}, 1000);
});
};
trackByFunction(_: number, item: CipherView) {
return item.id;
}
onCheckboxChange(id: number, event: Event) {
const isChecked = (event.target as HTMLInputElement).checked;
if (isChecked) {
this.selectedIds.add(id);
} else {
this.selectedIds.delete(id);
}
}
}