mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-22 16:29:09 +01:00
[PM-13156] - Access intelligence page (#11420)
* WIP - access intelligence page * finish access intelligence page * finish access intelligence page * use tab label directive * remove extension swap change * only show when feature flag enabled * Move files under tools ownership --------- Co-authored-by: Daniel James Smith <djsmith85@users.noreply.github.com>
This commit is contained in:
parent
36c965c453
commit
7fc987d806
@ -39,6 +39,11 @@
|
|||||||
*ngIf="organization.canAccessReports"
|
*ngIf="organization.canAccessReports"
|
||||||
></bit-nav-item>
|
></bit-nav-item>
|
||||||
</bit-nav-group>
|
</bit-nav-group>
|
||||||
|
<bit-nav-item
|
||||||
|
*ngIf="isAccessIntelligenceFeatureEnabled"
|
||||||
|
[text]="'accessIntelligence' | i18n"
|
||||||
|
route="access-intelligence"
|
||||||
|
></bit-nav-item>
|
||||||
<bit-nav-group
|
<bit-nav-group
|
||||||
icon="bwi-billing"
|
icon="bwi-billing"
|
||||||
[text]="'billing' | i18n"
|
[text]="'billing' | i18n"
|
||||||
|
@ -51,6 +51,7 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
showPaymentAndHistory$: Observable<boolean>;
|
showPaymentAndHistory$: Observable<boolean>;
|
||||||
hideNewOrgButton$: Observable<boolean>;
|
hideNewOrgButton$: Observable<boolean>;
|
||||||
organizationIsUnmanaged$: Observable<boolean>;
|
organizationIsUnmanaged$: Observable<boolean>;
|
||||||
|
isAccessIntelligenceFeatureEnabled = false;
|
||||||
|
|
||||||
private _destroy = new Subject<void>();
|
private _destroy = new Subject<void>();
|
||||||
|
|
||||||
@ -70,6 +71,10 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
document.body.classList.remove("layout_frontend");
|
document.body.classList.remove("layout_frontend");
|
||||||
|
|
||||||
|
this.isAccessIntelligenceFeatureEnabled = await this.configService.getFeatureFlag(
|
||||||
|
FeatureFlag.AccessIntelligence,
|
||||||
|
);
|
||||||
|
|
||||||
this.organization$ = this.route.params
|
this.organization$ = this.route.params
|
||||||
.pipe(takeUntil(this._destroy))
|
.pipe(takeUntil(this._destroy))
|
||||||
.pipe<string>(map((p) => p.organizationId))
|
.pipe<string>(map((p) => p.organizationId))
|
||||||
|
@ -62,6 +62,13 @@ const routes: Routes = [
|
|||||||
(m) => m.OrganizationReportingModule,
|
(m) => m.OrganizationReportingModule,
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "access-intelligence",
|
||||||
|
loadChildren: () =>
|
||||||
|
import("../../tools/access-intelligence/access-intelligence.module").then(
|
||||||
|
(m) => m.AccessIntelligenceModule,
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "billing",
|
path: "billing",
|
||||||
loadChildren: () =>
|
loadChildren: () =>
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
import { NgModule } from "@angular/core";
|
||||||
|
import { RouterModule, Routes } from "@angular/router";
|
||||||
|
|
||||||
|
import { unauthGuardFn } from "@bitwarden/angular/auth/guards";
|
||||||
|
import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
|
||||||
|
import { AccessIntelligenceComponent } from "./access-intelligence.component";
|
||||||
|
|
||||||
|
const routes: Routes = [
|
||||||
|
{
|
||||||
|
path: "",
|
||||||
|
component: AccessIntelligenceComponent,
|
||||||
|
canActivate: [canAccessFeature(FeatureFlag.AccessIntelligence), unauthGuardFn()],
|
||||||
|
data: {
|
||||||
|
titleId: "accessIntelligence",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [RouterModule.forChild(routes)],
|
||||||
|
exports: [RouterModule],
|
||||||
|
})
|
||||||
|
export class AccessIntelligenceRoutingModule {}
|
@ -0,0 +1,23 @@
|
|||||||
|
<app-header></app-header>
|
||||||
|
<bit-tab-group [(selectedIndex)]="tabIndex">
|
||||||
|
<bit-tab label="{{ 'allApplicationsWithCount' | i18n: apps.length }}">
|
||||||
|
<h2 bitTypography="h2">{{ "allApplications" | i18n }}</h2>
|
||||||
|
<tools-application-table></tools-application-table>
|
||||||
|
</bit-tab>
|
||||||
|
<bit-tab>
|
||||||
|
<ng-template bitTabLabel>
|
||||||
|
<i class="bwi bwi-star"></i>
|
||||||
|
{{ "priorityApplicationsWithCount" | i18n: priorityApps.length }}
|
||||||
|
</ng-template>
|
||||||
|
<h2 bitTypography>{{ "priorityApplications" | i18n }}</h2>
|
||||||
|
<tools-application-table></tools-application-table>
|
||||||
|
</bit-tab>
|
||||||
|
<bit-tab>
|
||||||
|
<ng-template bitTabLabel>
|
||||||
|
<i class="bwi bwi-envelope"></i>
|
||||||
|
{{ "notifiedMembersWithCount" | i18n: priorityApps.length }}
|
||||||
|
</ng-template>
|
||||||
|
<h2 bitTypography="h2">{{ "notifiedMembers" | i18n }}</h2>
|
||||||
|
<tools-notified-members-table></tools-notified-members-table>
|
||||||
|
</bit-tab>
|
||||||
|
</bit-tab-group>
|
@ -0,0 +1,45 @@
|
|||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { Component } from "@angular/core";
|
||||||
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
|
import { ActivatedRoute } from "@angular/router";
|
||||||
|
import { first } from "rxjs";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
|
import { TabsModule } from "@bitwarden/components";
|
||||||
|
|
||||||
|
import { HeaderModule } from "../../layouts/header/header.module";
|
||||||
|
|
||||||
|
import { ApplicationTableComponent } from "./application-table.component";
|
||||||
|
import { NotifiedMembersTableComponent } from "./notified-members-table.component";
|
||||||
|
|
||||||
|
export enum AccessIntelligenceTabType {
|
||||||
|
AllApps = 0,
|
||||||
|
PriorityApps = 1,
|
||||||
|
NotifiedMembers = 2,
|
||||||
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
standalone: true,
|
||||||
|
templateUrl: "./access-intelligence.component.html",
|
||||||
|
imports: [
|
||||||
|
ApplicationTableComponent,
|
||||||
|
CommonModule,
|
||||||
|
JslibModule,
|
||||||
|
HeaderModule,
|
||||||
|
NotifiedMembersTableComponent,
|
||||||
|
TabsModule,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AccessIntelligenceComponent {
|
||||||
|
tabIndex: AccessIntelligenceTabType;
|
||||||
|
|
||||||
|
apps: any[] = [];
|
||||||
|
priorityApps: any[] = [];
|
||||||
|
notifiedMembers: any[] = [];
|
||||||
|
|
||||||
|
constructor(route: ActivatedRoute) {
|
||||||
|
route.queryParams.pipe(takeUntilDestroyed(), first()).subscribe(({ tabIndex }) => {
|
||||||
|
this.tabIndex = !isNaN(tabIndex) ? tabIndex : AccessIntelligenceTabType.AllApps;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
import { NgModule } from "@angular/core";
|
||||||
|
|
||||||
|
import { AccessIntelligenceRoutingModule } from "./access-intelligence-routing.module";
|
||||||
|
import { AccessIntelligenceComponent } from "./access-intelligence.component";
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [AccessIntelligenceComponent, AccessIntelligenceRoutingModule],
|
||||||
|
})
|
||||||
|
export class AccessIntelligenceModule {}
|
@ -0,0 +1,11 @@
|
|||||||
|
<!-- <bit-table [dataSource]="dataSource"> -->
|
||||||
|
<ng-container header>
|
||||||
|
<tr>
|
||||||
|
<th bitCell>{{ "application" | i18n }}</th>
|
||||||
|
<th bitCell>{{ "atRiskPasswords" | i18n }}</th>
|
||||||
|
<th bitCell>{{ "totalPasswords" | i18n }}</th>
|
||||||
|
<th bitCell>{{ "atRiskMembers" | i18n }}</th>
|
||||||
|
<th bitCell>{{ "totalMembers" | i18n }}</th>
|
||||||
|
</tr>
|
||||||
|
</ng-container>
|
||||||
|
<!-- </bit-table> -->
|
@ -0,0 +1,19 @@
|
|||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { Component } from "@angular/core";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
|
import { TableDataSource, TableModule } from "@bitwarden/components";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
standalone: true,
|
||||||
|
selector: "tools-application-table",
|
||||||
|
templateUrl: "./application-table.component.html",
|
||||||
|
imports: [CommonModule, JslibModule, TableModule],
|
||||||
|
})
|
||||||
|
export class ApplicationTableComponent {
|
||||||
|
protected dataSource = new TableDataSource<any>();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.dataSource.data = [];
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<!-- <bit-table [dataSource]="dataSource"> -->
|
||||||
|
<ng-container header>
|
||||||
|
<tr>
|
||||||
|
<th bitCell>{{ "member" | i18n }}</th>
|
||||||
|
<th bitCell>{{ "atRiskPasswords" | i18n }}</th>
|
||||||
|
<th bitCell>{{ "totalPasswords" | i18n }}</th>
|
||||||
|
<th bitCell>{{ "atRiskApplications" | i18n }}</th>
|
||||||
|
<th bitCell>{{ "totalApplications" | i18n }}</th>
|
||||||
|
</tr>
|
||||||
|
</ng-container>
|
||||||
|
<!-- </bit-table> -->
|
@ -0,0 +1,19 @@
|
|||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
import { Component } from "@angular/core";
|
||||||
|
|
||||||
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
|
import { TableDataSource, TableModule } from "@bitwarden/components";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
standalone: true,
|
||||||
|
selector: "tools-notified-members-table",
|
||||||
|
templateUrl: "./notified-members-table.component.html",
|
||||||
|
imports: [CommonModule, JslibModule, TableModule],
|
||||||
|
})
|
||||||
|
export class NotifiedMembersTableComponent {
|
||||||
|
dataSource = new TableDataSource<any>();
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.dataSource.data = [];
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,64 @@
|
|||||||
{
|
{
|
||||||
|
"allApplications": {
|
||||||
|
"message": "All applications"
|
||||||
|
},
|
||||||
|
"priorityApplications": {
|
||||||
|
"message": "Priority applications"
|
||||||
|
},
|
||||||
|
"accessIntelligence": {
|
||||||
|
"message": "Access Intelligence"
|
||||||
|
},
|
||||||
|
"notifiedMembers": {
|
||||||
|
"message": "Notified members"
|
||||||
|
},
|
||||||
|
"allApplicationsWithCount": {
|
||||||
|
"message": "All applications ($COUNT$)",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"priorityApplicationsWithCount": {
|
||||||
|
"message": "Priority applications ($COUNT$)",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notifiedMembersWithCount": {
|
||||||
|
"message": "Notified members ($COUNT$)",
|
||||||
|
"placeholders": {
|
||||||
|
"count": {
|
||||||
|
"content": "$1",
|
||||||
|
"example": "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"application": {
|
||||||
|
"message": "Application"
|
||||||
|
},
|
||||||
|
"atRiskPasswords": {
|
||||||
|
"message": "At-risk passwords"
|
||||||
|
},
|
||||||
|
"totalPasswords": {
|
||||||
|
"message": "Total passwords"
|
||||||
|
},
|
||||||
|
"atRiskMembers": {
|
||||||
|
"message": "At-risk members"
|
||||||
|
},
|
||||||
|
"totalMembers": {
|
||||||
|
"message": "Total members"
|
||||||
|
},
|
||||||
|
"atRiskApplications": {
|
||||||
|
"message": "At-risk applications"
|
||||||
|
},
|
||||||
|
"totalApplications": {
|
||||||
|
"message": "Total applications"
|
||||||
|
},
|
||||||
"whatTypeOfItem": {
|
"whatTypeOfItem": {
|
||||||
"message": "What type of item is this?"
|
"message": "What type of item is this?"
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user