mirror of
https://github.com/bitwarden/browser
synced 2026-01-09 03:53:53 +00:00
[EC-8] Restructure Tabs (#3109)
* Cherry pick pending PR for tabs component [CL-17] Tabs - Routing * Update organization tabs from 4 to 6 * Create initial 'Members' tab * Create initial 'Groups' tab * Add initial "Reporting" tab * Use correct report label/layout by product type * Create initial 'Billing' tab * Breakup billing payment and billing history pages * Cleanup org routing and nav permission service * More org tab permission cleanup * Refactor organization billing to use a module * Refactor organization reporting to use module * Cherry pick finished/merged tabs component [CL-17] Tabs - Router (#2952) * This partially reverts commit24bb775to fix tracking of people.component.html rename. * Fix people component file rename * Recover lost member page changes * Undo members component rename as it was causing difficult merge conflicts * Fix member and group page container * Remove unnecessary organization lookup * [EC-8] Some PR suggestions * [EC-8] Reuse user billing history for orgs * [EC-8] Renamed user billing history component * [EC-8] Repurpose payment method component Update end user payment method component to be usable for organizations. * [EC-8] Fix missing verify bank condition * [EC-8] Remove org payment method component * [EC-8] Use CL in payment method component * [EC-8] Extend maxWidth Tailwind theme config * [EC-8] Add lazy loading to org reports * [EC-8] Add lazy loading to org billing * [EC-8] Prettier * [EC-8] Cleanup org reporting component redundancy * [EC-8] Use different class for negative margin * [EC-8] Make billing history component "dumb" * Revert "[EC-8] Cleanup org reporting component redundancy" This reverts commiteca337e89b. * [EC-8] Create and export shared reports module * [EC-8] Use shared reports module in orgs * [EC-8] Use takeUntil pattern * [EC-8] Move org reporting module out of old modules folder * [EC-8] Move org billing module out of old modules folder * [EC-8] Fix some remaining merge conflicts * [EC-8] Move maxWidth into 'extend' key for Tailwind config * [EC-8] Remove unused module * [EC-8] Rename org report list component * Prettier Co-authored-by: Vincent Salucci <vincesalucci21@gmail.com>
This commit is contained in:
@@ -0,0 +1,98 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
import { RouterModule, Routes } from "@angular/router";
|
||||
|
||||
import { Permissions } from "@bitwarden/common/enums/permissions";
|
||||
|
||||
import { PermissionsGuard } from "../guards/permissions.guard";
|
||||
import { EventsComponent } from "../manage/events.component";
|
||||
import { NavigationPermissionsService } from "../services/navigation-permissions.service";
|
||||
import { ExposedPasswordsReportComponent } from "../tools/exposed-passwords-report.component";
|
||||
import { InactiveTwoFactorReportComponent } from "../tools/inactive-two-factor-report.component";
|
||||
import { ReusedPasswordsReportComponent } from "../tools/reused-passwords-report.component";
|
||||
import { UnsecuredWebsitesReportComponent } from "../tools/unsecured-websites-report.component";
|
||||
import { WeakPasswordsReportComponent } from "../tools/weak-passwords-report.component";
|
||||
|
||||
import { ReportingComponent } from "./reporting.component";
|
||||
import { ReportsHomeComponent } from "./reports-home.component";
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: "",
|
||||
component: ReportingComponent,
|
||||
canActivate: [PermissionsGuard],
|
||||
data: { permissions: NavigationPermissionsService.getPermissions("reporting") },
|
||||
children: [
|
||||
{ path: "", pathMatch: "full", redirectTo: "reports" },
|
||||
{
|
||||
path: "reports",
|
||||
component: ReportsHomeComponent,
|
||||
canActivate: [PermissionsGuard],
|
||||
data: {
|
||||
titleId: "reports",
|
||||
permissions: [Permissions.AccessReports],
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: "exposed-passwords-report",
|
||||
component: ExposedPasswordsReportComponent,
|
||||
canActivate: [PermissionsGuard],
|
||||
data: {
|
||||
titleId: "exposedPasswordsReport",
|
||||
permissions: [Permissions.AccessReports],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "inactive-two-factor-report",
|
||||
component: InactiveTwoFactorReportComponent,
|
||||
canActivate: [PermissionsGuard],
|
||||
data: {
|
||||
titleId: "inactive2faReport",
|
||||
permissions: [Permissions.AccessReports],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "reused-passwords-report",
|
||||
component: ReusedPasswordsReportComponent,
|
||||
canActivate: [PermissionsGuard],
|
||||
data: {
|
||||
titleId: "reusedPasswordsReport",
|
||||
permissions: [Permissions.AccessReports],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "unsecured-websites-report",
|
||||
component: UnsecuredWebsitesReportComponent,
|
||||
canActivate: [PermissionsGuard],
|
||||
data: {
|
||||
titleId: "unsecuredWebsitesReport",
|
||||
permissions: [Permissions.AccessReports],
|
||||
},
|
||||
},
|
||||
{
|
||||
path: "weak-passwords-report",
|
||||
component: WeakPasswordsReportComponent,
|
||||
canActivate: [PermissionsGuard],
|
||||
data: {
|
||||
titleId: "weakPasswordsReport",
|
||||
permissions: [Permissions.AccessReports],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: "events",
|
||||
component: EventsComponent,
|
||||
canActivate: [PermissionsGuard],
|
||||
data: {
|
||||
titleId: "eventLogs",
|
||||
permissions: [Permissions.AccessEventLogs],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
@NgModule({
|
||||
imports: [RouterModule.forChild(routes)],
|
||||
exports: [RouterModule],
|
||||
})
|
||||
export class OrganizationReportingRoutingModule {}
|
||||
@@ -0,0 +1,14 @@
|
||||
import { NgModule } from "@angular/core";
|
||||
|
||||
import { ReportsSharedModule } from "../../reports";
|
||||
import { SharedModule } from "../../shared/shared.module";
|
||||
|
||||
import { OrganizationReportingRoutingModule } from "./organization-reporting-routing.module";
|
||||
import { ReportingComponent } from "./reporting.component";
|
||||
import { ReportsHomeComponent } from "./reports-home.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [SharedModule, ReportsSharedModule, OrganizationReportingRoutingModule],
|
||||
declarations: [ReportsHomeComponent, ReportingComponent],
|
||||
})
|
||||
export class OrganizationReportingModule {}
|
||||
@@ -0,0 +1,30 @@
|
||||
<div class="container page-content">
|
||||
<div class="row">
|
||||
<div class="col-3" *ngIf="showLeftNav">
|
||||
<div class="card" *ngIf="organization">
|
||||
<div class="card-header">{{ "reporting" | i18n }}</div>
|
||||
<div class="list-group list-group-flush">
|
||||
<a
|
||||
routerLink="reports"
|
||||
class="list-group-item"
|
||||
routerLinkActive="active"
|
||||
*ngIf="organization.canAccessReports"
|
||||
>
|
||||
{{ "reports" | i18n }}
|
||||
</a>
|
||||
<a
|
||||
routerLink="events"
|
||||
class="list-group-item"
|
||||
routerLinkActive="active"
|
||||
*ngIf="organization.canAccessEventLogs && accessEvents"
|
||||
>
|
||||
{{ "eventLogs" | i18n }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-9" [ngClass]="showLeftNav ? 'col-9' : 'col-12'">
|
||||
<router-outlet></router-outlet>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,24 @@
|
||||
import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
|
||||
import { OrganizationService } from "@bitwarden/common/abstractions/organization.service";
|
||||
import { Organization } from "@bitwarden/common/models/domain/organization";
|
||||
|
||||
@Component({
|
||||
selector: "app-org-reporting",
|
||||
templateUrl: "reporting.component.html",
|
||||
})
|
||||
export class ReportingComponent implements OnInit {
|
||||
organization: Organization;
|
||||
accessEvents = false;
|
||||
showLeftNav = true;
|
||||
|
||||
constructor(private route: ActivatedRoute, private organizationService: OrganizationService) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.route.parent.params.subscribe(async (params) => {
|
||||
this.organization = await this.organizationService.get(params.organizationId);
|
||||
this.accessEvents = this.showLeftNav = this.organization.useEvents;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<ng-container *ngIf="homepage">
|
||||
<div class="page-header">
|
||||
<h1>{{ "reports" | i18n }}</h1>
|
||||
</div>
|
||||
|
||||
<p>{{ "orgsReportsDesc" | i18n }}</p>
|
||||
|
||||
<app-report-list [reports]="reports"></app-report-list>
|
||||
</ng-container>
|
||||
|
||||
<router-outlet></router-outlet>
|
||||
|
||||
<div class="row mt-4">
|
||||
<div class="col">
|
||||
<a bitButton routerLink="./" *ngIf="!homepage">
|
||||
<i class="bwi bwi-angle-left" aria-hidden="true"></i>
|
||||
{{ "backToReports" | i18n }}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,65 @@
|
||||
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||
import { NavigationEnd, Router } from "@angular/router";
|
||||
import { filter, Subject, takeUntil } from "rxjs";
|
||||
|
||||
import { StateService } from "@bitwarden/common/abstractions/state.service";
|
||||
|
||||
import { ReportVariant, reports, ReportType, ReportEntry } from "../../reports";
|
||||
|
||||
@Component({
|
||||
selector: "app-org-reports-home",
|
||||
templateUrl: "reports-home.component.html",
|
||||
})
|
||||
export class ReportsHomeComponent implements OnInit, OnDestroy {
|
||||
reports: ReportEntry[];
|
||||
|
||||
homepage = true;
|
||||
private destrory$: Subject<void> = new Subject<void>();
|
||||
|
||||
constructor(private stateService: StateService, router: Router) {
|
||||
router.events
|
||||
.pipe(
|
||||
takeUntil(this.destrory$),
|
||||
filter((event) => event instanceof NavigationEnd)
|
||||
)
|
||||
.subscribe((event) => {
|
||||
this.homepage = (event as NavigationEnd).urlAfterRedirects.endsWith("/reports");
|
||||
});
|
||||
}
|
||||
|
||||
async ngOnInit(): Promise<void> {
|
||||
const userHasPremium = await this.stateService.getCanAccessPremium();
|
||||
|
||||
const reportRequiresPremium = userHasPremium
|
||||
? ReportVariant.Enabled
|
||||
: ReportVariant.RequiresPremium;
|
||||
|
||||
this.reports = [
|
||||
{
|
||||
...reports[ReportType.ExposedPasswords],
|
||||
variant: reportRequiresPremium,
|
||||
},
|
||||
{
|
||||
...reports[ReportType.ReusedPasswords],
|
||||
variant: reportRequiresPremium,
|
||||
},
|
||||
{
|
||||
...reports[ReportType.WeakPasswords],
|
||||
variant: reportRequiresPremium,
|
||||
},
|
||||
{
|
||||
...reports[ReportType.UnsecuredWebsites],
|
||||
variant: reportRequiresPremium,
|
||||
},
|
||||
{
|
||||
...reports[ReportType.Inactive2fa],
|
||||
variant: reportRequiresPremium,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destrory$.next();
|
||||
this.destrory$.complete();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user