mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
add CSV download buttons to at risk members and applications drawers (#17172)
* add CSV download buttons to at risk members and applications drawers --------- Co-authored-by: Alex <55413326+AlexRubik@users.noreply.github.com>
This commit is contained in:
@@ -118,6 +118,15 @@
|
||||
) | i18n
|
||||
}}</span>
|
||||
<ng-container *ngIf="drawerDetails.atRiskMemberDetails.length > 0">
|
||||
<button
|
||||
bitLink
|
||||
type="button"
|
||||
class="tw-my-4 tw-font-bold tw-block"
|
||||
(click)="downloadAtRiskMembers()"
|
||||
>
|
||||
<i class="bwi bwi-download tw-mr-1"></i>
|
||||
{{ "downloadCSV" | i18n }}
|
||||
</button>
|
||||
<div class="tw-flex tw-justify-between tw-mt-2 tw-text-muted">
|
||||
<div bitTypography="body2" class="tw-text-sm tw-font-bold">
|
||||
{{ "email" | i18n }}
|
||||
@@ -173,6 +182,15 @@
|
||||
) | i18n
|
||||
}}</span>
|
||||
<ng-container *ngIf="drawerDetails.atRiskAppDetails.length > 0">
|
||||
<button
|
||||
bitLink
|
||||
type="button"
|
||||
class="tw-my-4 tw-font-bold tw-block"
|
||||
(click)="downloadAtRiskApplications()"
|
||||
>
|
||||
<i class="bwi bwi-download tw-mr-1"></i>
|
||||
{{ "downloadCSV" | i18n }}
|
||||
</button>
|
||||
<div class="tw-flex tw-justify-between tw-mt-2 tw-text-muted">
|
||||
<div bitTypography="body2" class="tw-text-sm tw-font-bold">
|
||||
{{ "application" | i18n }}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common";
|
||||
import { Component, DestroyRef, OnDestroy, OnInit, inject } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { ActivatedRoute, Router } from "@angular/router";
|
||||
import { combineLatest, EMPTY } from "rxjs";
|
||||
import { combineLatest, EMPTY, firstValueFrom } from "rxjs";
|
||||
import { map, tap } from "rxjs/operators";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
@@ -13,7 +13,9 @@ import {
|
||||
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import {
|
||||
AsyncActionsModule,
|
||||
@@ -23,6 +25,8 @@ import {
|
||||
DrawerHeaderComponent,
|
||||
TabsModule,
|
||||
} from "@bitwarden/components";
|
||||
import { ExportHelper } from "@bitwarden/vault-export-core";
|
||||
import { exportToCSV } from "@bitwarden/web-vault/app/dirt/reports/report-utils";
|
||||
import { HeaderModule } from "@bitwarden/web-vault/app/layouts/header/header.module";
|
||||
|
||||
import { AllActivityComponent } from "./activity/all-activity.component";
|
||||
@@ -88,6 +92,8 @@ export class RiskInsightsComponent implements OnInit, OnDestroy {
|
||||
private configService: ConfigService,
|
||||
protected dataService: RiskInsightsDataService,
|
||||
protected i18nService: I18nService,
|
||||
private fileDownloadService: FileDownloadService,
|
||||
private logService: LogService,
|
||||
) {
|
||||
this.route.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(({ tabIndex }) => {
|
||||
this.tabIndex = !isNaN(Number(tabIndex)) ? Number(tabIndex) : RiskInsightsTabType.AllApps;
|
||||
@@ -207,4 +213,66 @@ export class RiskInsightsComponent implements OnInit, OnDestroy {
|
||||
"import",
|
||||
]);
|
||||
};
|
||||
|
||||
/**
|
||||
* downloads at risk members as CSV
|
||||
*/
|
||||
downloadAtRiskMembers = async () => {
|
||||
try {
|
||||
const drawerDetails = await firstValueFrom(this.dataService.drawerDetails$);
|
||||
|
||||
// Validate drawer is open and showing the correct drawer type
|
||||
if (
|
||||
!drawerDetails.open ||
|
||||
drawerDetails.activeDrawerType !== DrawerType.OrgAtRiskMembers ||
|
||||
!drawerDetails.atRiskMemberDetails ||
|
||||
drawerDetails.atRiskMemberDetails.length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.fileDownloadService.download({
|
||||
fileName: ExportHelper.getFileName("at-risk-members"),
|
||||
blobData: exportToCSV(drawerDetails.atRiskMemberDetails, {
|
||||
email: this.i18nService.t("email"),
|
||||
atRiskPasswordCount: this.i18nService.t("atRiskPasswords"),
|
||||
}),
|
||||
blobOptions: { type: "text/plain" },
|
||||
});
|
||||
} catch (error) {
|
||||
// Log error for debugging
|
||||
this.logService.error("Failed to download at-risk members", error);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* downloads at risk applications as CSV
|
||||
*/
|
||||
downloadAtRiskApplications = async () => {
|
||||
try {
|
||||
const drawerDetails = await firstValueFrom(this.dataService.drawerDetails$);
|
||||
|
||||
// Validate drawer is open and showing the correct drawer type
|
||||
if (
|
||||
!drawerDetails.open ||
|
||||
drawerDetails.activeDrawerType !== DrawerType.OrgAtRiskApps ||
|
||||
!drawerDetails.atRiskAppDetails ||
|
||||
drawerDetails.atRiskAppDetails.length === 0
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.fileDownloadService.download({
|
||||
fileName: ExportHelper.getFileName("at-risk-applications"),
|
||||
blobData: exportToCSV(drawerDetails.atRiskAppDetails, {
|
||||
applicationName: this.i18nService.t("application"),
|
||||
atRiskPasswordCount: this.i18nService.t("atRiskPasswords"),
|
||||
}),
|
||||
blobOptions: { type: "text/plain" },
|
||||
});
|
||||
} catch (error) {
|
||||
// Log error for debugging
|
||||
this.logService.error("Failed to download at-risk applications", error);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user