mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-26352] drawers for activity cards (#16895)
* new drawer functions for crit apps * logic for triggering the drawer functions in components * cleanup unused logic and rename "navigation" to "action" - ... since the click is now triggering the drawer instead of navigating to another tab/page * null check for reportData in drawer methods * use criticalReportResults$ to avoid duplicating logic * use criticalReportResults$ to avoid dupe logic * remove unused code
This commit is contained in:
@@ -175,6 +175,65 @@ export class RiskInsightsDataService {
|
||||
}
|
||||
};
|
||||
|
||||
setDrawerForCriticalAtRiskMembers = async (invokerId: string = ""): Promise<void> => {
|
||||
const { open, activeDrawerType, invokerId: currentInvokerId } = this.drawerDetailsSubject.value;
|
||||
const shouldClose =
|
||||
open && activeDrawerType === DrawerType.OrgAtRiskMembers && currentInvokerId === invokerId;
|
||||
|
||||
if (shouldClose) {
|
||||
this.closeDrawer();
|
||||
} else {
|
||||
const reportResults = await firstValueFrom(this.criticalReportResults$);
|
||||
if (!reportResults?.reportData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Generate at-risk member list from critical applications
|
||||
const atRiskMemberDetails = getAtRiskMemberList(reportResults.reportData);
|
||||
|
||||
this.drawerDetailsSubject.next({
|
||||
open: true,
|
||||
invokerId,
|
||||
activeDrawerType: DrawerType.OrgAtRiskMembers,
|
||||
atRiskMemberDetails,
|
||||
appAtRiskMembers: null,
|
||||
atRiskAppDetails: null,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
setDrawerForCriticalAtRiskApps = async (invokerId: string = ""): Promise<void> => {
|
||||
const { open, activeDrawerType, invokerId: currentInvokerId } = this.drawerDetailsSubject.value;
|
||||
const shouldClose =
|
||||
open && activeDrawerType === DrawerType.OrgAtRiskApps && currentInvokerId === invokerId;
|
||||
|
||||
if (shouldClose) {
|
||||
this.closeDrawer();
|
||||
} else {
|
||||
const reportResults = await firstValueFrom(this.criticalReportResults$);
|
||||
if (!reportResults?.reportData) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Filter critical applications for those with at-risk passwords
|
||||
const criticalAtRiskApps = reportResults.reportData
|
||||
.filter((app) => app.atRiskPasswordCount > 0)
|
||||
.map((app) => ({
|
||||
applicationName: app.applicationName,
|
||||
atRiskPasswordCount: app.atRiskPasswordCount,
|
||||
}));
|
||||
|
||||
this.drawerDetailsSubject.next({
|
||||
open: true,
|
||||
invokerId,
|
||||
activeDrawerType: DrawerType.OrgAtRiskApps,
|
||||
atRiskMemberDetails: [],
|
||||
appAtRiskMembers: null,
|
||||
atRiskAppDetails: criticalAtRiskApps,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------ Critical application methods --------------
|
||||
saveCriticalApplications(selectedUrls: string[]) {
|
||||
return this.orchestrator.saveCriticalApplications$(selectedUrls);
|
||||
|
||||
@@ -23,11 +23,11 @@
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
@if (showNavigationLink && !buttonText) {
|
||||
@if (showActionLink && !buttonText) {
|
||||
<div class="tw-flex tw-items-baseline tw-mt-4 tw-gap-2">
|
||||
<p bitTypography="body1">
|
||||
<a bitLink (click)="navigateToLink(navigationLink)" rel="noreferrer">
|
||||
{{ navigationText }}
|
||||
<a bitLink href="#" (click)="onActionClick(); $event.preventDefault()" rel="noreferrer">
|
||||
{{ actionText }}
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -37,25 +37,14 @@ export class ActivityCardComponent {
|
||||
@Input() metricDescription: string = "";
|
||||
|
||||
/**
|
||||
* The link to navigate to for more information
|
||||
* The text to display for the action link
|
||||
*/
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
||||
// eslint-disable-next-line @angular-eslint/prefer-signals
|
||||
@Input() navigationLink: string = "";
|
||||
@Input() actionText: string = "";
|
||||
|
||||
/**
|
||||
* The text to display for the navigation link
|
||||
* Show action link
|
||||
*/
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
||||
// eslint-disable-next-line @angular-eslint/prefer-signals
|
||||
@Input() navigationText: string = "";
|
||||
|
||||
/**
|
||||
* Show Navigation link
|
||||
*/
|
||||
// FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals
|
||||
// eslint-disable-next-line @angular-eslint/prefer-signals
|
||||
@Input() showNavigationLink: boolean = false;
|
||||
@Input() showActionLink: boolean = false;
|
||||
|
||||
/**
|
||||
* Icon class to display next to metrics (e.g., "bwi-exclamation-triangle").
|
||||
@@ -86,13 +75,18 @@ export class ActivityCardComponent {
|
||||
// eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref
|
||||
@Output() buttonClick = new EventEmitter<void>();
|
||||
|
||||
constructor(private router: Router) {}
|
||||
/**
|
||||
* Event emitted when action link is clicked
|
||||
*/
|
||||
@Output() actionClick = new EventEmitter<void>();
|
||||
|
||||
navigateToLink = async (navigationLink: string) => {
|
||||
await this.router.navigateByUrl(navigationLink);
|
||||
};
|
||||
constructor(private router: Router) {}
|
||||
|
||||
onButtonClick = () => {
|
||||
this.buttonClick.emit();
|
||||
};
|
||||
|
||||
onActionClick = () => {
|
||||
this.actionClick.emit();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
[title]="'atRiskMembers' | i18n"
|
||||
[cardMetrics]="'membersAtRiskCount' | i18n: totalCriticalAppsAtRiskMemberCount"
|
||||
[metricDescription]="'membersWithAccessToAtRiskItemsForCriticalApps' | i18n"
|
||||
navigationText="{{ 'viewAtRiskMembers' | i18n }}"
|
||||
navigationLink="{{ getLinkForRiskInsightsTab(RiskInsightsTabType.AllApps) }}"
|
||||
[showNavigationLink]="totalCriticalAppsAtRiskMemberCount > 0"
|
||||
actionText="{{ 'viewAtRiskMembers' | i18n }}"
|
||||
[showActionLink]="totalCriticalAppsAtRiskMemberCount > 0"
|
||||
(actionClick)="onViewAtRiskMembers()"
|
||||
>
|
||||
</dirt-activity-card>
|
||||
</li>
|
||||
@@ -35,9 +35,9 @@
|
||||
: ('criticalApplicationsAreAtRisk'
|
||||
| i18n: totalCriticalAppsAtRiskCount : totalCriticalAppsCount)
|
||||
"
|
||||
navigationText="{{ 'viewAtRiskApplications' | i18n }}"
|
||||
navigationLink="{{ getLinkForRiskInsightsTab(RiskInsightsTabType.CriticalApps) }}"
|
||||
[showNavigationLink]="totalCriticalAppsAtRiskCount > 0"
|
||||
actionText="{{ 'viewAtRiskApplications' | i18n }}"
|
||||
[showActionLink]="totalCriticalAppsAtRiskCount > 0"
|
||||
(actionClick)="onViewAtRiskApplications()"
|
||||
>
|
||||
</dirt-activity-card>
|
||||
</li>
|
||||
|
||||
@@ -15,7 +15,6 @@ import { getById } from "@bitwarden/common/platform/misc";
|
||||
import { DialogService } from "@bitwarden/components";
|
||||
import { SharedModule } from "@bitwarden/web-vault/app/shared";
|
||||
|
||||
import { RiskInsightsTabType } from "../models/risk-insights.models";
|
||||
import { ApplicationsLoadingComponent } from "../shared/risk-insights-loading.component";
|
||||
|
||||
import { ActivityCardComponent } from "./activity-card.component";
|
||||
@@ -82,15 +81,6 @@ export class AllActivityComponent implements OnInit {
|
||||
}
|
||||
}
|
||||
|
||||
get RiskInsightsTabType() {
|
||||
return RiskInsightsTabType;
|
||||
}
|
||||
|
||||
getLinkForRiskInsightsTab(tabIndex: RiskInsightsTabType): string {
|
||||
const organizationId = this.activatedRoute.snapshot.paramMap.get("organizationId");
|
||||
return `/organizations/${organizationId}/access-intelligence/risk-insights?tabIndex=${tabIndex}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the review new applications button click.
|
||||
* Opens a dialog showing the list of new applications that can be marked as critical.
|
||||
@@ -102,4 +92,20 @@ export class AllActivityComponent implements OnInit {
|
||||
|
||||
await firstValueFrom(dialogRef.closed);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the "View at-risk members" link click.
|
||||
* Opens the at-risk members drawer for critical applications only.
|
||||
*/
|
||||
onViewAtRiskMembers = async () => {
|
||||
await this.dataService.setDrawerForCriticalAtRiskMembers("activityTabAtRiskMembers");
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the "View at-risk applications" link click.
|
||||
* Opens the at-risk applications drawer for critical applications only.
|
||||
*/
|
||||
onViewAtRiskApplications = async () => {
|
||||
await this.dataService.setDrawerForCriticalAtRiskApps("activityTabAtRiskApplications");
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user