From 8793cc026790d4a79dfd2b14d59684775537c817 Mon Sep 17 00:00:00 2001 From: Maciej Zieniuk Date: Mon, 24 Jun 2024 16:54:07 +0200 Subject: [PATCH] SM-1146: Total counts update on CRUD --- .../layout/navigation.component.ts | 27 ++++++++++++++-- .../projects/project/project.component.ts | 15 +++++++-- .../service-account.component.ts | 11 ++++++- .../access-policies/access-policy.service.ts | 32 +++++++++++++++---- 4 files changed, 72 insertions(+), 13 deletions(-) diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/layout/navigation.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/layout/navigation.component.ts index 630fc4dadd..8ac9b46058 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/layout/navigation.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/layout/navigation.component.ts @@ -1,13 +1,26 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; -import { concatMap, distinctUntilChanged, map, Observable, Subject, takeUntil } from "rxjs"; +import { + combineLatest, + concatMap, + distinctUntilChanged, + map, + Observable, + startWith, + Subject, + switchMap, + takeUntil, +} from "rxjs"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; import { SecretsManagerLogo } from "@bitwarden/web-vault/app/layouts/secrets-manager-logo"; import { OrganizationCounts } from "../models/view/counts.view"; +import { ProjectService } from "../projects/project.service"; +import { SecretService } from "../secrets/secret.service"; import { SecretsManagerService } from "../secrets-manager.service"; +import { ServiceAccountService } from "../service-accounts/service-account.service"; @Component({ selector: "sm-navigation", @@ -24,6 +37,9 @@ export class NavigationComponent implements OnInit, OnDestroy { protected route: ActivatedRoute, private organizationService: OrganizationService, private secretsManagerService: SecretsManagerService, + private projectService: ProjectService, + private secretService: SecretService, + private serviceAccountService: ServiceAccountService, ) {} ngOnInit() { @@ -39,9 +55,14 @@ export class NavigationComponent implements OnInit, OnDestroy { takeUntil(this.destroy$), ); - orgId$ + combineLatest([ + orgId$, + this.projectService.project$.pipe(startWith(null)), + this.secretService.secret$.pipe(startWith(null)), + this.serviceAccountService.serviceAccount$.pipe(startWith(null)), + ]) .pipe( - concatMap((orgId) => this.secretsManagerService.getCounts(orgId)), + switchMap(([orgId]) => this.secretsManagerService.getCounts(orgId)), takeUntil(this.destroy$), ) .subscribe((organizationCounts) => { diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project.component.ts index 3e9f54b5cd..489de0907f 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project.component.ts @@ -18,6 +18,9 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { DialogService } from "@bitwarden/components"; import { ProjectView } from "../../models/view/project.view"; +import { SecretService } from "../../secrets/secret.service"; +import { ServiceAccountService } from "../../service-accounts/service-account.service"; +import { AccessPolicyService } from "../../shared/access-policies/access-policy.service"; import { OperationType, ProjectDialogComponent, @@ -42,6 +45,9 @@ export class ProjectComponent implements OnInit, OnDestroy { constructor( private route: ActivatedRoute, private projectService: ProjectService, + private secretService: SecretService, + private accessPolicyService: AccessPolicyService, + private serviceAccountService: ServiceAccountService, private router: Router, private dialogService: DialogService, private platformUtilsService: PlatformUtilsService, @@ -64,8 +70,13 @@ export class ProjectComponent implements OnInit, OnDestroy { const organization$ = this.route.params.pipe( concatMap((params) => this.organizationService.get$(params.organizationId)), ); - const projectCounts$ = this.route.params.pipe( - switchMap((params) => + const projectCounts$ = combineLatest([ + this.route.params, + this.secretService.secret$.pipe(startWith(null)), + this.accessPolicyService.accessPolicy$.pipe(startWith(null)), + this.serviceAccountService.serviceAccount$.pipe(startWith(null)), + ]).pipe( + switchMap(([params]) => this.projectService.getProjectCounts(params.organizationId, params.projectId), ), ); diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.component.ts index 8b4f79f316..8268ecb24b 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.component.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-account.component.ts @@ -7,7 +7,9 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl import { DialogService } from "@bitwarden/components"; import { ServiceAccountView } from "../models/view/service-account.view"; +import { AccessPolicyService } from "../shared/access-policies/access-policy.service"; +import { AccessService } from "./access/access.service"; import { AccessTokenCreateDialogComponent } from "./access/dialogs/access-token-create-dialog.component"; import { ServiceAccountCounts } from "./models/view/counts.view"; import { ServiceAccountService } from "./service-account.service"; @@ -40,6 +42,8 @@ export class ServiceAccountComponent implements OnInit, OnDestroy { constructor( private route: ActivatedRoute, private serviceAccountService: ServiceAccountService, + private accessPolicyService: AccessPolicyService, + private accessService: AccessService, private dialogService: DialogService, private router: Router, private platformUtilsService: PlatformUtilsService, @@ -47,7 +51,12 @@ export class ServiceAccountComponent implements OnInit, OnDestroy { ) {} ngOnInit(): void { - const serviceAccountCounts$ = combineLatest([this.route.params, this.onChange$]).pipe( + const serviceAccountCounts$ = combineLatest([ + this.route.params, + this.accessPolicyService.accessPolicy$.pipe(startWith(null)), + this.accessService.accessToken$.pipe(startWith(null)), + this.onChange$, + ]).pipe( switchMap(([params, _]) => this.serviceAccountService.getCounts(params.organizationId, params.serviceAccountId), ), diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts index 67fb9b19bc..ec1501145d 100644 --- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts +++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/access-policies/access-policy.service.ts @@ -1,4 +1,5 @@ import { Injectable } from "@angular/core"; +import { Subject } from "rxjs"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { ListResponse } from "@bitwarden/common/models/response/list.response"; @@ -45,6 +46,15 @@ import { GrantedProjectAccessPolicyPermissionDetailsResponse } from "./models/re providedIn: "root", }) export class AccessPolicyService { + protected _accessPolicy: Subject< + | ProjectPeopleAccessPoliciesView + | ProjectServiceAccountsAccessPoliciesView + | ServiceAccountPeopleAccessPoliciesView + | ServiceAccountGrantedPoliciesView + > = new Subject(); + + accessPolicy$ = this._accessPolicy.asObservable(); + constructor( private cryptoService: CryptoService, protected apiService: ApiService, @@ -69,7 +79,7 @@ export class AccessPolicyService { async putProjectPeopleAccessPolicies( projectId: string, peoplePoliciesView: ProjectPeopleAccessPoliciesView, - ) { + ): Promise { const request = this.getPeopleAccessPoliciesRequest(peoplePoliciesView); const r = await this.apiService.send( "PUT", @@ -79,7 +89,9 @@ export class AccessPolicyService { true, ); const results = new ProjectPeopleAccessPoliciesResponse(r); - return this.createPeopleAccessPoliciesView(results); + const view = this.createPeopleAccessPoliciesView(results); + this._accessPolicy.next(view); + return view; } async getServiceAccountPeopleAccessPolicies( @@ -100,7 +112,7 @@ export class AccessPolicyService { async putServiceAccountPeopleAccessPolicies( serviceAccountId: string, peoplePoliciesView: ServiceAccountPeopleAccessPoliciesView, - ) { + ): Promise { const request = this.getPeopleAccessPoliciesRequest(peoplePoliciesView); const r = await this.apiService.send( "PUT", @@ -110,7 +122,9 @@ export class AccessPolicyService { true, ); const results = new ServiceAccountPeopleAccessPoliciesResponse(r); - return this.createPeopleAccessPoliciesView(results); + const view = this.createPeopleAccessPoliciesView(results); + this._accessPolicy.next(view); + return view; } async getServiceAccountGrantedPolicies( @@ -144,7 +158,9 @@ export class AccessPolicyService { ); const result = new ServiceAccountGrantedPoliciesPermissionDetailsResponse(r); - return await this.createServiceAccountGrantedPoliciesView(result, organizationId); + const view = await this.createServiceAccountGrantedPoliciesView(result, organizationId); + this._accessPolicy.next(view); + return view; } async getProjectServiceAccountsAccessPolicies( @@ -178,7 +194,9 @@ export class AccessPolicyService { ); const result = new ProjectServiceAccountsAccessPoliciesResponse(r); - return await this.createProjectServiceAccountsAccessPoliciesView(result, organizationId); + const view = await this.createProjectServiceAccountsAccessPoliciesView(result, organizationId); + this._accessPolicy.next(view); + return view; } async getSecretAccessPolicies( @@ -435,7 +453,7 @@ export class AccessPolicyService { private createPeopleAccessPoliciesView( response: ProjectPeopleAccessPoliciesResponse | ServiceAccountPeopleAccessPoliciesResponse, - ) { + ): ProjectPeopleAccessPoliciesView | ServiceAccountPeopleAccessPoliciesView { return { userAccessPolicies: this.createUserAccessPolicyViews(response.userAccessPolicies), groupAccessPolicies: this.createGroupAccessPolicyViews(response.groupAccessPolicies),