mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
[PM-14268] - Access intelligence - add tabbing and events (#11831)
* comment code * small fixes * undo change to flags
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
{{ "refresh" | i18n }}
|
{{ "refresh" | i18n }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<bit-tab-group [(selectedIndex)]="tabIndex">
|
<bit-tab-group [(selectedIndex)]="tabIndex" (selectedIndexChange)="onTabChange($event)">
|
||||||
<bit-tab label="{{ 'allApplicationsWithCount' | i18n: apps.length }}">
|
<bit-tab label="{{ 'allApplicationsWithCount' | i18n: apps.length }}">
|
||||||
<tools-all-applications></tools-all-applications>
|
<tools-all-applications></tools-all-applications>
|
||||||
</bit-tab>
|
</bit-tab>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { CommonModule } from "@angular/common";
|
import { CommonModule } from "@angular/common";
|
||||||
import { Component } from "@angular/core";
|
import { Component } from "@angular/core";
|
||||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { first } from "rxjs";
|
|
||||||
|
|
||||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||||
import { AsyncActionsModule, ButtonModule, TabsModule } from "@bitwarden/components";
|
import { AsyncActionsModule, ButtonModule, TabsModule } from "@bitwarden/components";
|
||||||
@@ -18,7 +17,7 @@ import { PasswordHealthComponent } from "./password-health.component";
|
|||||||
|
|
||||||
export enum AccessIntelligenceTabType {
|
export enum AccessIntelligenceTabType {
|
||||||
AllApps = 0,
|
AllApps = 0,
|
||||||
PriorityApps = 1,
|
CriticalApps = 1,
|
||||||
NotifiedMembers = 2,
|
NotifiedMembers = 2,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,8 +57,19 @@ export class AccessIntelligenceComponent {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(route: ActivatedRoute) {
|
onTabChange = async (newIndex: number) => {
|
||||||
route.queryParams.pipe(takeUntilDestroyed(), first()).subscribe(({ tabIndex }) => {
|
await this.router.navigate([], {
|
||||||
|
relativeTo: this.route,
|
||||||
|
queryParams: { tabIndex: newIndex },
|
||||||
|
queryParamsHandling: "merge",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
protected route: ActivatedRoute,
|
||||||
|
private router: Router,
|
||||||
|
) {
|
||||||
|
route.queryParams.pipe(takeUntilDestroyed()).subscribe(({ tabIndex }) => {
|
||||||
this.tabIndex = !isNaN(tabIndex) ? tabIndex : AccessIntelligenceTabType.AllApps;
|
this.tabIndex = !isNaN(tabIndex) ? tabIndex : AccessIntelligenceTabType.AllApps;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,15 @@
|
|||||||
</h2>
|
</h2>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container slot="description">
|
<ng-container slot="description">
|
||||||
<p class="tw-text-muted">
|
<div class="tw-flex tw-flex-col tw-mb-2">
|
||||||
{{ "noAppsInOrgDescription" | i18n }}
|
<span class="tw-text-muted">
|
||||||
|
{{ "noAppsInOrgDescription" | i18n }}
|
||||||
|
</span>
|
||||||
<a class="text-primary" routerLink="/login">{{ "learnMore" | i18n }}</a>
|
<a class="text-primary" routerLink="/login">{{ "learnMore" | i18n }}</a>
|
||||||
</p>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container slot="button">
|
<ng-container slot="button">
|
||||||
<button bitButton buttonType="primary" type="button">
|
<button (click)="goToCreateNewLoginItem()" bitButton buttonType="primary" type="button">
|
||||||
{{ "createNewLoginItem" | i18n }}
|
{{ "createNewLoginItem" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@@ -50,7 +52,15 @@
|
|||||||
class="tw-grow"
|
class="tw-grow"
|
||||||
[formControl]="searchControl"
|
[formControl]="searchControl"
|
||||||
></bit-search>
|
></bit-search>
|
||||||
<button class="tw-rounded-lg" type="button" buttonType="secondary" bitButton>
|
<button
|
||||||
|
class="tw-rounded-lg"
|
||||||
|
type="button"
|
||||||
|
buttonType="secondary"
|
||||||
|
bitButton
|
||||||
|
[disabled]="!selectedIds.size"
|
||||||
|
[loading]="markingAsCritical"
|
||||||
|
(click)="markAppsAsCritical()"
|
||||||
|
>
|
||||||
<i class="bwi bwi-star-f tw-mr-2"></i>
|
<i class="bwi bwi-star-f tw-mr-2"></i>
|
||||||
{{ "markAppAsCritical" | i18n }}
|
{{ "markAppAsCritical" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export class AllApplicationsComponent implements OnInit {
|
|||||||
protected loading = false;
|
protected loading = false;
|
||||||
protected organization: Organization;
|
protected organization: Organization;
|
||||||
noItemsIcon = Icons.Security;
|
noItemsIcon = Icons.Security;
|
||||||
|
protected markingAsCritical = false;
|
||||||
|
|
||||||
// MOCK DATA
|
// MOCK DATA
|
||||||
protected mockData = applicationTableMockData;
|
protected mockData = applicationTableMockData;
|
||||||
@@ -76,8 +77,18 @@ export class AllApplicationsComponent implements OnInit {
|
|||||||
.subscribe((v) => (this.dataSource.filter = v));
|
.subscribe((v) => (this.dataSource.filter = v));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goToCreateNewLoginItem = async () => {
|
||||||
|
// TODO: implement
|
||||||
|
this.toastService.showToast({
|
||||||
|
variant: "warning",
|
||||||
|
title: null,
|
||||||
|
message: "Not yet implemented",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
markAppsAsCritical = async () => {
|
markAppsAsCritical = async () => {
|
||||||
// TODO: Send to API once implemented
|
// TODO: Send to API once implemented
|
||||||
|
this.markingAsCritical = true;
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.selectedIds.clear();
|
this.selectedIds.clear();
|
||||||
@@ -87,6 +98,7 @@ export class AllApplicationsComponent implements OnInit {
|
|||||||
message: this.i18nService.t("appsMarkedAsCritical"),
|
message: this.i18nService.t("appsMarkedAsCritical"),
|
||||||
});
|
});
|
||||||
resolve(true);
|
resolve(true);
|
||||||
|
this.markingAsCritical = false;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -19,7 +19,9 @@
|
|||||||
</p>
|
</p>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container slot="button">
|
<ng-container slot="button">
|
||||||
<button bitButton buttonType="primary" type="button">{{ "markCriticalApps" | i18n }}</button>
|
<button (click)="goToAllAppsTab()" bitButton buttonType="primary" type="button">
|
||||||
|
{{ "markCriticalApps" | i18n }}
|
||||||
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</bit-no-items>
|
</bit-no-items>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Component, DestroyRef, inject, OnInit } from "@angular/core";
|
import { Component, DestroyRef, inject, OnInit } from "@angular/core";
|
||||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||||
import { FormControl } from "@angular/forms";
|
import { FormControl } from "@angular/forms";
|
||||||
import { ActivatedRoute } from "@angular/router";
|
import { ActivatedRoute, Router } from "@angular/router";
|
||||||
import { debounceTime, map } from "rxjs";
|
import { debounceTime, map } from "rxjs";
|
||||||
|
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
@@ -12,6 +12,7 @@ import { HeaderModule } from "../../layouts/header/header.module";
|
|||||||
import { SharedModule } from "../../shared";
|
import { SharedModule } from "../../shared";
|
||||||
import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module";
|
import { PipesModule } from "../../vault/individual-vault/pipes/pipes.module";
|
||||||
|
|
||||||
|
import { AccessIntelligenceTabType } from "./access-intelligence.component";
|
||||||
import { applicationTableMockData } from "./application-table.mock";
|
import { applicationTableMockData } from "./application-table.mock";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -26,8 +27,10 @@ export class CriticalApplicationsComponent implements OnInit {
|
|||||||
protected searchControl = new FormControl("", { nonNullable: true });
|
protected searchControl = new FormControl("", { nonNullable: true });
|
||||||
private destroyRef = inject(DestroyRef);
|
private destroyRef = inject(DestroyRef);
|
||||||
protected loading = false;
|
protected loading = false;
|
||||||
|
protected organizationId: string;
|
||||||
noItemsIcon = Icons.Security;
|
noItemsIcon = Icons.Security;
|
||||||
// MOCK DATA
|
// MOCK DATA
|
||||||
|
protected mockData = applicationTableMockData;
|
||||||
protected mockAtRiskMembersCount = 0;
|
protected mockAtRiskMembersCount = 0;
|
||||||
protected mockAtRiskAppsCount = 0;
|
protected mockAtRiskAppsCount = 0;
|
||||||
protected mockTotalMembersCount = 0;
|
protected mockTotalMembersCount = 0;
|
||||||
@@ -38,18 +41,26 @@ export class CriticalApplicationsComponent implements OnInit {
|
|||||||
.pipe(
|
.pipe(
|
||||||
takeUntilDestroyed(this.destroyRef),
|
takeUntilDestroyed(this.destroyRef),
|
||||||
map(async (params) => {
|
map(async (params) => {
|
||||||
// const organizationId = params.get("organizationId");
|
this.organizationId = params.get("organizationId");
|
||||||
// TODO: use organizationId to fetch data
|
// TODO: use organizationId to fetch data
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.subscribe();
|
.subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
goToAllAppsTab = async () => {
|
||||||
|
await this.router.navigate([`organizations/${this.organizationId}/access-intelligence`], {
|
||||||
|
queryParams: { tabIndex: AccessIntelligenceTabType.AllApps },
|
||||||
|
queryParamsHandling: "merge",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
protected i18nService: I18nService,
|
protected i18nService: I18nService,
|
||||||
protected activatedRoute: ActivatedRoute,
|
protected activatedRoute: ActivatedRoute,
|
||||||
|
protected router: Router,
|
||||||
) {
|
) {
|
||||||
this.dataSource.data = applicationTableMockData;
|
this.dataSource.data = []; //applicationTableMockData;
|
||||||
this.searchControl.valueChanges
|
this.searchControl.valueChanges
|
||||||
.pipe(debounceTime(200), takeUntilDestroyed())
|
.pipe(debounceTime(200), takeUntilDestroyed())
|
||||||
.subscribe((v) => (this.dataSource.filter = v));
|
.subscribe((v) => (this.dataSource.filter = v));
|
||||||
|
|||||||
Reference in New Issue
Block a user