1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-18 10:23:52 +00:00

no crit items

This commit is contained in:
Alex
2025-11-04 12:21:30 -05:00
parent 329c8afb7f
commit 0c2431d663
2 changed files with 108 additions and 76 deletions

View File

@@ -1,75 +1,97 @@
<div class="tw-mt-4 tw-flex tw-flex-col">
<div class="tw-flex tw-justify-between tw-mb-4">
<h2 bitTypography="h2">{{ "criticalApplications" | i18n }}</h2>
<button
bitButton
buttonType="primary"
type="button"
[disabled]="!enableRequestPasswordChange"
(click)="requestPasswordChange()"
>
<i class="bwi bwi-envelope tw-mr-2"></i>
{{
enableRequestPasswordChange
? ("requestPasswordChange" | i18n)
: ("noCriticalAppsAtRisk" | i18n)
}}
</button>
@if (!dataSource.data.length) {
<div class="tw-mt-4">
<bit-no-items [icon]="noItemsIcon" class="tw-text-main">
<ng-container slot="title">
<h2 class="tw-font-semibold tw-mt-4">
{{ "noCriticalApplicationsTitle" | i18n }}
</h2>
</ng-container>
<ng-container slot="description">
<p class="tw-text-muted">
{{ "noCriticalApplicationsDescription" | i18n }}
</p>
</ng-container>
<ng-container slot="button">
<button (click)="goToAllAppsTab()" bitButton buttonType="primary" type="button">
{{ "markCriticalApplications" | i18n }}
</button>
</ng-container>
</bit-no-items>
</div>
@if (dataService.drawerDetails$ | async; as drawerDetails) {
<div class="tw-flex tw-gap-6">
} @else {
<div class="tw-mt-4 tw-flex tw-flex-col">
<div class="tw-flex tw-justify-between tw-mb-4">
<h2 bitTypography="h2">{{ "criticalApplications" | i18n }}</h2>
<button
bitButton
buttonType="primary"
type="button"
class="tw-flex-1"
tabindex="0"
(click)="dataService.setDrawerForOrgAtRiskMembers('criticalAppsAtRiskMembers')"
[disabled]="!enableRequestPasswordChange"
(click)="requestPasswordChange()"
>
<dirt-card
#criticalAppsAtRiskMembers
class="tw-w-full"
[ngClass]="{
'tw-bg-primary-100': drawerDetails.invokerId === 'criticalAppsAtRiskMembers',
}"
[title]="'atRiskMembers' | i18n"
[value]="applicationSummary.totalAtRiskMemberCount"
[maxValue]="applicationSummary.totalMemberCount"
>
</dirt-card>
</button>
<button
type="button"
class="tw-flex-1"
tabindex="0"
(click)="dataService.setDrawerForOrgAtRiskApps('criticalAppsAtRiskApplications')"
>
<dirt-card
#criticalAppsAtRiskApplications
class="tw-w-full"
[ngClass]="{
'tw-bg-primary-100': drawerDetails.invokerId === 'criticalAppsAtRiskApplications',
}"
[title]="'atRiskApplications' | i18n"
[value]="applicationSummary.totalAtRiskApplicationCount"
[maxValue]="applicationSummary.totalApplicationCount"
>
</dirt-card>
<i class="bwi bwi-envelope tw-mr-2"></i>
{{
enableRequestPasswordChange
? ("requestPasswordChange" | i18n)
: ("noCriticalAppsAtRisk" | i18n)
}}
</button>
</div>
<div class="tw-flex tw-mt-8 tw-mb-4 tw-gap-4">
<bit-search
[placeholder]="'searchApps' | i18n"
class="tw-grow"
[formControl]="searchControl"
></bit-search>
</div>
@if (dataService.drawerDetails$ | async; as drawerDetails) {
<div class="tw-flex tw-gap-6">
<button
type="button"
class="tw-flex-1"
tabindex="0"
(click)="dataService.setDrawerForOrgAtRiskMembers('criticalAppsAtRiskMembers')"
>
<dirt-card
#criticalAppsAtRiskMembers
class="tw-w-full"
[ngClass]="{
'tw-bg-primary-100': drawerDetails.invokerId === 'criticalAppsAtRiskMembers',
}"
[title]="'atRiskMembers' | i18n"
[value]="applicationSummary.totalAtRiskMemberCount"
[maxValue]="applicationSummary.totalMemberCount"
>
</dirt-card>
</button>
<button
type="button"
class="tw-flex-1"
tabindex="0"
(click)="dataService.setDrawerForOrgAtRiskApps('criticalAppsAtRiskApplications')"
>
<dirt-card
#criticalAppsAtRiskApplications
class="tw-w-full"
[ngClass]="{
'tw-bg-primary-100': drawerDetails.invokerId === 'criticalAppsAtRiskApplications',
}"
[title]="'atRiskApplications' | i18n"
[value]="applicationSummary.totalAtRiskApplicationCount"
[maxValue]="applicationSummary.totalApplicationCount"
>
</dirt-card>
</button>
</div>
<div class="tw-flex tw-mt-8 tw-mb-4 tw-gap-4">
<bit-search
[placeholder]="'searchApps' | i18n"
class="tw-grow"
[formControl]="searchControl"
></bit-search>
</div>
<app-table-row-scrollable
[dataSource]="dataSource"
[showRowCheckBox]="false"
[showRowMenuForCriticalApps]="true"
[openApplication]="drawerDetails.invokerId || ''"
[showAppAtRiskMembers]="showAppAtRiskMembers"
[unmarkAsCritical]="removeCriticalApplication"
></app-table-row-scrollable>
}
</div>
<app-table-row-scrollable
[dataSource]="dataSource"
[showRowCheckBox]="false"
[showRowMenuForCriticalApps]="true"
[openApplication]="drawerDetails.invokerId || ''"
[showAppAtRiskMembers]="showAppAtRiskMembers"
[unmarkAsCritical]="removeCriticalApplication"
></app-table-row-scrollable>
}
</div>
}

View File

@@ -15,6 +15,8 @@ import {
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
import { createNewSummaryData } from "@bitwarden/bit-common/dirt/reports/risk-insights/helpers";
import { OrganizationReportSummary } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/report-models";
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 { OrganizationId } from "@bitwarden/common/types/guid";
import { NoItemsModule, SearchModule, TableDataSource, ToastService } from "@bitwarden/components";
@@ -24,7 +26,6 @@ import { SharedModule } from "@bitwarden/web-vault/app/shared";
import { PipesModule } from "@bitwarden/web-vault/app/vault/individual-vault/pipes/pipes.module";
import { DefaultAdminTaskService } from "../../../vault/services/default-admin-task.service";
import { RiskInsightsTabType } from "../models/risk-insights.models";
import { AppTableRowScrollableComponent } from "../shared/app-table-row-scrollable.component";
import { AccessIntelligenceSecurityTasksService } from "../shared/security-tasks.service";
@@ -49,6 +50,7 @@ export class CriticalApplicationsComponent implements OnInit {
protected enableRequestPasswordChange = false;
protected organizationId: OrganizationId;
noItemsIcon = Security;
private isRiskInsightsActivityTabFeatureEnabled = false;
protected dataSource = new TableDataSource<ApplicationHealthReportDetailEnriched>();
protected applicationSummary = {} as OrganizationReportSummary;
@@ -65,6 +67,7 @@ export class CriticalApplicationsComponent implements OnInit {
protected reportService: RiskInsightsReportService,
protected i18nService: I18nService,
private accessIntelligenceSecurityTasksService: AccessIntelligenceSecurityTasksService,
private configService: ConfigService,
) {
this.searchControl.valueChanges
.pipe(debounceTime(200), takeUntilDestroyed())
@@ -72,6 +75,14 @@ export class CriticalApplicationsComponent implements OnInit {
}
async ngOnInit() {
// Subscribe to feature flag
this.configService
.getFeatureFlag$(FeatureFlag.PM22887_RiskInsightsActivityTab)
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe((isEnabled) => {
this.isRiskInsightsActivityTabFeatureEnabled = isEnabled; // TODO: Remove this hard coded value
});
this.dataService.criticalReportResults$.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
next: (criticalReport) => {
this.dataSource.data = criticalReport?.reportData ?? [];
@@ -100,13 +111,12 @@ export class CriticalApplicationsComponent implements OnInit {
}
goToAllAppsTab = async () => {
await this.router.navigate(
[`organizations/${this.organizationId}/access-intelligence/risk-insights`],
{
queryParams: { tabIndex: RiskInsightsTabType.AllApps },
queryParamsHandling: "merge",
},
);
// If activity tab is enabled, All Apps is tab 1, otherwise it's tab 0
const allAppsTabIndex = this.isRiskInsightsActivityTabFeatureEnabled ? 1 : 0; //TODO: change this logic when feature flag is implemented?
await this.router.navigate([], {
relativeTo: this.activatedRoute.parent,
queryParams: { tabIndex: allAppsTabIndex },
});
};
removeCriticalApplication = async (hostname: string) => {