From cbf7c292f33dc38e3872d4527a970e0b36a3f283 Mon Sep 17 00:00:00 2001 From: Alex Morask <144709477+amorask-bitwarden@users.noreply.github.com> Date: Thu, 25 Apr 2024 15:27:06 -0400 Subject: [PATCH] [AC-2485] Add redirects to clients components based on FF and provider status (#8839) * Add provider clients redirects based on FF and provider status * Fixing broken test --- .../clients/base-clients.component.ts | 130 +++++++++++ .../providers/clients/clients.component.ts | 187 +++++---------- .../providers/providers-layout.component.html | 7 +- .../providers/providers-layout.component.ts | 3 + ...t-organization-subscription.component.html | 9 +- .../manage-client-organizations.component.ts | 213 ++++++------------ libs/common/src/admin-console/enums/index.ts | 1 + .../enums/provider-status-type.enum.ts | 5 + .../models/data/provider.data.ts | 4 +- .../admin-console/models/domain/provider.ts | 4 +- .../response/profile-provider.response.ts | 4 +- .../services/provider.service.spec.ts | 3 +- 12 files changed, 287 insertions(+), 283 deletions(-) create mode 100644 bitwarden_license/bit-web/src/app/admin-console/providers/clients/base-clients.component.ts create mode 100644 libs/common/src/admin-console/enums/provider-status-type.enum.ts diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/base-clients.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/base-clients.component.ts new file mode 100644 index 0000000000..604d61f3db --- /dev/null +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/base-clients.component.ts @@ -0,0 +1,130 @@ +import { SelectionModel } from "@angular/cdk/collections"; +import { Directive, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { BehaviorSubject, from, Subject, switchMap } from "rxjs"; +import { first, takeUntil } from "rxjs/operators"; + +import { SearchService } from "@bitwarden/common/abstractions/search.service"; +import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response"; +import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; +import { DialogService, TableDataSource, ToastService } from "@bitwarden/components"; + +import { WebProviderService } from "../services/web-provider.service"; + +@Directive() +export abstract class BaseClientsComponent implements OnInit, OnDestroy { + protected destroy$ = new Subject(); + + private searchText$ = new BehaviorSubject(""); + + get searchText() { + return this.searchText$.value; + } + + set searchText(value: string) { + this.searchText$.next(value); + this.selection.clear(); + this.dataSource.filter = value; + } + + private searching = false; + protected scrolled = false; + protected pageSize = 100; + private pagedClientsCount = 0; + protected selection = new SelectionModel(true, []); + + protected clients: ProviderOrganizationOrganizationDetailsResponse[]; + protected pagedClients: ProviderOrganizationOrganizationDetailsResponse[]; + protected dataSource = new TableDataSource(); + + abstract providerId: string; + + protected constructor( + protected activatedRoute: ActivatedRoute, + protected dialogService: DialogService, + private i18nService: I18nService, + private searchService: SearchService, + private toastService: ToastService, + private validationService: ValidationService, + private webProviderService: WebProviderService, + ) {} + + abstract load(): Promise; + + ngOnInit() { + this.activatedRoute.queryParams + .pipe(first(), takeUntil(this.destroy$)) + .subscribe((queryParams) => { + this.searchText = queryParams.search; + }); + + this.searchText$ + .pipe( + switchMap((searchText) => from(this.searchService.isSearchable(searchText))), + takeUntil(this.destroy$), + ) + .subscribe((isSearchable) => { + this.searching = isSearchable; + }); + } + + ngOnDestroy() { + this.destroy$.next(); + this.destroy$.complete(); + } + + isPaging() { + if (this.searching && this.scrolled) { + this.resetPaging(); + } + return !this.searching && this.clients && this.clients.length > this.pageSize; + } + + resetPaging() { + this.pagedClients = []; + this.loadMore(); + } + + loadMore() { + if (!this.clients || this.clients.length <= this.pageSize) { + return; + } + const pagedLength = this.pagedClients.length; + let pagedSize = this.pageSize; + if (pagedLength === 0 && this.pagedClientsCount > this.pageSize) { + pagedSize = this.pagedClientsCount; + } + if (this.clients.length > pagedLength) { + this.pagedClients = this.pagedClients.concat( + this.clients.slice(pagedLength, pagedLength + pagedSize), + ); + } + this.pagedClientsCount = this.pagedClients.length; + this.scrolled = this.pagedClients.length > this.pageSize; + } + + async remove(organization: ProviderOrganizationOrganizationDetailsResponse) { + const confirmed = await this.dialogService.openSimpleDialog({ + title: organization.organizationName, + content: { key: "detachOrganizationConfirmation" }, + type: "warning", + }); + + if (!confirmed) { + return; + } + + try { + await this.webProviderService.detachOrganization(this.providerId, organization.id); + this.toastService.showToast({ + variant: "success", + title: null, + message: this.i18nService.t("detachedOrganization", organization.organizationName), + }); + await this.load(); + } catch (e) { + this.validationService.showError(e); + } + } +} diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts index abdfd6deff..54e264c666 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts @@ -1,29 +1,26 @@ -import { Component, OnInit } from "@angular/core"; +import { Component } from "@angular/core"; import { ActivatedRoute, Router } from "@angular/router"; -import { BehaviorSubject, Subject, firstValueFrom, from } from "rxjs"; -import { first, switchMap, takeUntil } from "rxjs/operators"; +import { combineLatest, firstValueFrom, from } from "rxjs"; +import { concatMap, switchMap, takeUntil } from "rxjs/operators"; -import { ModalService } from "@bitwarden/angular/services/modal.service"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { OrganizationApiServiceAbstraction } from "@bitwarden/common/admin-console/abstractions/organization/organization-api.service.abstraction"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; -import { ProviderUserType } from "@bitwarden/common/admin-console/enums"; +import { ProviderStatusType, ProviderUserType } from "@bitwarden/common/admin-console/enums"; import { Organization } from "@bitwarden/common/admin-console/models/domain/organization"; -import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response"; import { PlanType } from "@bitwarden/common/billing/enums"; import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; -import { DialogService } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; import { WebProviderService } from "../services/web-provider.service"; import { AddOrganizationComponent } from "./add-organization.component"; +import { BaseClientsComponent } from "./base-clients.component"; const DisallowedPlanTypes = [ PlanType.Free, @@ -36,90 +33,76 @@ const DisallowedPlanTypes = [ @Component({ templateUrl: "clients.component.html", }) -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class ClientsComponent implements OnInit { +export class ClientsComponent extends BaseClientsComponent { providerId: string; addableOrganizations: Organization[]; loading = true; manageOrganizations = false; showAddExisting = false; - clients: ProviderOrganizationOrganizationDetailsResponse[]; - pagedClients: ProviderOrganizationOrganizationDetailsResponse[]; - - protected didScroll = false; - protected pageSize = 100; - protected actionPromise: Promise; - private pagedClientsCount = 0; - - protected enableConsolidatedBilling$ = this.configService.getFeatureFlag$( + protected consolidatedBillingEnabled$ = this.configService.getFeatureFlag$( FeatureFlag.EnableConsolidatedBilling, false, ); - private destroy$ = new Subject(); - private _searchText$ = new BehaviorSubject(""); - private isSearching: boolean = false; - - get searchText() { - return this._searchText$.value; - } - - set searchText(value: string) { - this._searchText$.next(value); - } constructor( - private route: ActivatedRoute, private router: Router, private providerService: ProviderService, private apiService: ApiService, - private searchService: SearchService, - private platformUtilsService: PlatformUtilsService, - private i18nService: I18nService, - private validationService: ValidationService, - private webProviderService: WebProviderService, - private logService: LogService, - private modalService: ModalService, private organizationService: OrganizationService, private organizationApiService: OrganizationApiServiceAbstraction, - private dialogService: DialogService, private configService: ConfigService, - ) {} + activatedRoute: ActivatedRoute, + dialogService: DialogService, + i18nService: I18nService, + searchService: SearchService, + toastService: ToastService, + validationService: ValidationService, + webProviderService: WebProviderService, + ) { + super( + activatedRoute, + dialogService, + i18nService, + searchService, + toastService, + validationService, + webProviderService, + ); + } - async ngOnInit() { - const enableConsolidatedBilling = await firstValueFrom(this.enableConsolidatedBilling$); - - if (enableConsolidatedBilling) { - await this.router.navigate(["../manage-client-organizations"], { relativeTo: this.route }); - } else { - this.route.parent.params - .pipe( - switchMap((params) => { - this.providerId = params.providerId; - return from(this.load()); - }), - takeUntil(this.destroy$), - ) - .subscribe(); - - this.route.queryParams.pipe(first(), takeUntil(this.destroy$)).subscribe((qParams) => { - this.searchText = qParams.search; - }); - - this._searchText$ - .pipe( - switchMap((searchText) => from(this.searchService.isSearchable(searchText))), - takeUntil(this.destroy$), - ) - .subscribe((isSearchable) => { - this.isSearching = isSearchable; - }); - } + ngOnInit() { + this.activatedRoute.parent.params + .pipe( + switchMap((params) => { + this.providerId = params.providerId; + return combineLatest([ + this.providerService.get(this.providerId), + this.consolidatedBillingEnabled$, + ]).pipe( + concatMap(([provider, consolidatedBillingEnabled]) => { + if ( + consolidatedBillingEnabled && + provider.providerStatus === ProviderStatusType.Billable + ) { + return from( + this.router.navigate(["../manage-client-organizations"], { + relativeTo: this.activatedRoute, + }), + ); + } else { + return from(this.load()); + } + }), + ); + }), + takeUntil(this.destroy$), + ) + .subscribe(); } ngOnDestroy() { - this.destroy$.next(); - this.destroy$.complete(); + super.ngOnDestroy(); } async load() { @@ -141,37 +124,6 @@ export class ClientsComponent implements OnInit { this.loading = false; } - isPaging() { - const searching = this.isSearching; - if (searching && this.didScroll) { - this.resetPaging(); - } - return !searching && this.clients && this.clients.length > this.pageSize; - } - - resetPaging() { - this.pagedClients = []; - this.loadMore(); - } - - loadMore() { - if (!this.clients || this.clients.length <= this.pageSize) { - return; - } - const pagedLength = this.pagedClients.length; - let pagedSize = this.pageSize; - if (pagedLength === 0 && this.pagedClientsCount > this.pageSize) { - pagedSize = this.pagedClientsCount; - } - if (this.clients.length > pagedLength) { - this.pagedClients = this.pagedClients.concat( - this.clients.slice(pagedLength, pagedLength + pagedSize), - ); - } - this.pagedClientsCount = this.pagedClients.length; - this.didScroll = this.pagedClients.length > this.pageSize; - } - async addExistingOrganization() { const dialogRef = AddOrganizationComponent.open(this.dialogService, { providerId: this.providerId, @@ -182,33 +134,4 @@ export class ClientsComponent implements OnInit { await this.load(); } } - - async remove(organization: ProviderOrganizationOrganizationDetailsResponse) { - const confirmed = await this.dialogService.openSimpleDialog({ - title: organization.organizationName, - content: { key: "detachOrganizationConfirmation" }, - type: "warning", - }); - - if (!confirmed) { - return false; - } - - this.actionPromise = this.webProviderService.detachOrganization( - this.providerId, - organization.id, - ); - try { - await this.actionPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("detachedOrganization", organization.organizationName), - ); - await this.load(); - } catch (e) { - this.validationService.showError(e); - } - this.actionPromise = null; - } } diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html index ca2b1a3545..55efbe1386 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/providers-layout.component.html @@ -7,7 +7,12 @@ {{ "assignedSeats" | i18n }} - +

diff --git a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-organizations.component.ts b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-organizations.component.ts index 2184a617cf..3cc96c4589 100644 --- a/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-organizations.component.ts +++ b/bitwarden_license/bit-web/src/app/billing/providers/clients/manage-client-organizations.component.ts @@ -1,21 +1,23 @@ -import { SelectionModel } from "@angular/cdk/collections"; -import { Component, OnDestroy, OnInit } from "@angular/core"; -import { ActivatedRoute } from "@angular/router"; -import { BehaviorSubject, firstValueFrom, from, lastValueFrom, Subject } from "rxjs"; -import { first, switchMap, takeUntil } from "rxjs/operators"; +import { Component } from "@angular/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { combineLatest, firstValueFrom, from, lastValueFrom } from "rxjs"; +import { concatMap, switchMap, takeUntil } from "rxjs/operators"; import { ApiService } from "@bitwarden/common/abstractions/api.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service"; -import { ProviderUserType } from "@bitwarden/common/admin-console/enums"; +import { ProviderStatusType, ProviderUserType } from "@bitwarden/common/admin-console/enums"; +import { Provider } from "@bitwarden/common/admin-console/models/domain/provider"; import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response"; import { BillingApiServiceAbstraction as BillingApiService } from "@bitwarden/common/billing/abstractions/billilng-api.service.abstraction"; import { PlanResponse } from "@bitwarden/common/billing/models/response/plan.response"; +import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; +import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; -import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service"; -import { DialogService, TableDataSource } from "@bitwarden/components"; +import { DialogService, ToastService } from "@bitwarden/components"; +import { BaseClientsComponent } from "../../../admin-console/providers/clients/base-clients.component"; import { WebProviderService } from "../../../admin-console/providers/services/web-provider.service"; import { @@ -27,127 +29,91 @@ import { ManageClientOrganizationSubscriptionComponent } from "./manage-client-o @Component({ templateUrl: "manage-client-organizations.component.html", }) - -// eslint-disable-next-line rxjs-angular/prefer-takeuntil -export class ManageClientOrganizationsComponent implements OnInit, OnDestroy { +export class ManageClientOrganizationsComponent extends BaseClientsComponent { providerId: string; + provider: Provider; + loading = true; manageOrganizations = false; - private destroy$ = new Subject(); - private _searchText$ = new BehaviorSubject(""); - private isSearching: boolean = false; + private consolidatedBillingEnabled$ = this.configService.getFeatureFlag$( + FeatureFlag.EnableConsolidatedBilling, + false, + ); - get searchText() { - return this._searchText$.value; - } - - set searchText(search: string) { - this._searchText$.value; - - this.selection.clear(); - this.dataSource.filter = search; - } - - clients: ProviderOrganizationOrganizationDetailsResponse[]; - pagedClients: ProviderOrganizationOrganizationDetailsResponse[]; - - protected didScroll = false; - protected pageSize = 100; - protected actionPromise: Promise; - private pagedClientsCount = 0; - selection = new SelectionModel(true, []); - protected dataSource = new TableDataSource(); protected plans: PlanResponse[]; constructor( - private route: ActivatedRoute, - private providerService: ProviderService, private apiService: ApiService, - private searchService: SearchService, - private platformUtilsService: PlatformUtilsService, - private i18nService: I18nService, - private validationService: ValidationService, - private webProviderService: WebProviderService, - private dialogService: DialogService, private billingApiService: BillingApiService, - ) {} - - async ngOnInit() { - // eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe - this.route.parent.params.subscribe(async (params) => { - this.providerId = params.providerId; - - await this.load(); - - /* eslint-disable-next-line rxjs-angular/prefer-takeuntil, rxjs/no-async-subscribe, rxjs/no-nested-subscribe */ - this.route.queryParams.pipe(first()).subscribe(async (qParams) => { - this.searchText = qParams.search; - }); - }); - - this._searchText$ - .pipe( - switchMap((searchText) => from(this.searchService.isSearchable(searchText))), - takeUntil(this.destroy$), - ) - .subscribe((isSearchable) => { - this.isSearching = isSearchable; - }); + private configService: ConfigService, + private providerService: ProviderService, + private router: Router, + activatedRoute: ActivatedRoute, + dialogService: DialogService, + i18nService: I18nService, + searchService: SearchService, + toastService: ToastService, + validationService: ValidationService, + webProviderService: WebProviderService, + ) { + super( + activatedRoute, + dialogService, + i18nService, + searchService, + toastService, + validationService, + webProviderService, + ); } - ngOnDestroy(): void { - this.destroy$.next(); - this.destroy$.complete(); + ngOnInit() { + this.activatedRoute.parent.params + .pipe( + switchMap((params) => { + this.providerId = params.providerId; + return combineLatest([ + this.providerService.get(this.providerId), + this.consolidatedBillingEnabled$, + ]).pipe( + concatMap(([provider, consolidatedBillingEnabled]) => { + if ( + !consolidatedBillingEnabled || + provider.providerStatus !== ProviderStatusType.Billable + ) { + return from( + this.router.navigate(["../clients"], { + relativeTo: this.activatedRoute, + }), + ); + } else { + this.provider = provider; + this.manageOrganizations = this.provider.type === ProviderUserType.ProviderAdmin; + return from(this.load()); + } + }), + ); + }), + takeUntil(this.destroy$), + ) + .subscribe(); + } + + ngOnDestroy() { + super.ngOnDestroy(); } async load() { - const clientsResponse = await this.apiService.getProviderClients(this.providerId); - this.clients = - clientsResponse.data != null && clientsResponse.data.length > 0 ? clientsResponse.data : []; - this.dataSource.data = this.clients; - this.manageOrganizations = - (await this.providerService.get(this.providerId)).type === ProviderUserType.ProviderAdmin; + this.clients = (await this.apiService.getProviderClients(this.providerId)).data; - const plansResponse = await this.billingApiService.getPlans(); - this.plans = plansResponse.data; + this.dataSource.data = this.clients; + + this.plans = (await this.billingApiService.getPlans()).data; this.loading = false; } - isPaging() { - const searching = this.isSearching; - if (searching && this.didScroll) { - // FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling. - // eslint-disable-next-line @typescript-eslint/no-floating-promises - this.resetPaging(); - } - return !searching && this.clients && this.clients.length > this.pageSize; - } - - async resetPaging() { - this.pagedClients = []; - this.loadMore(); - } - - loadMore() { - if (!this.clients || this.clients.length <= this.pageSize) { - return; - } - const pagedLength = this.pagedClients.length; - let pagedSize = this.pageSize; - if (pagedLength === 0 && this.pagedClientsCount > this.pageSize) { - pagedSize = this.pagedClientsCount; - } - if (this.clients.length > pagedLength) { - this.pagedClients = this.pagedClients.concat( - this.clients.slice(pagedLength, pagedLength + pagedSize), - ); - } - this.pagedClientsCount = this.pagedClients.length; - this.didScroll = this.pagedClients.length > this.pageSize; - } - async manageSubscription(organization: ProviderOrganizationOrganizationDetailsResponse) { if (organization == null) { return; @@ -161,35 +127,6 @@ export class ManageClientOrganizationsComponent implements OnInit, OnDestroy { await this.load(); } - async remove(organization: ProviderOrganizationOrganizationDetailsResponse) { - const confirmed = await this.dialogService.openSimpleDialog({ - title: organization.organizationName, - content: { key: "detachOrganizationConfirmation" }, - type: "warning", - }); - - if (!confirmed) { - return false; - } - - this.actionPromise = this.webProviderService.detachOrganization( - this.providerId, - organization.id, - ); - try { - await this.actionPromise; - this.platformUtilsService.showToast( - "success", - null, - this.i18nService.t("detachedOrganization", organization.organizationName), - ); - await this.load(); - } catch (e) { - this.validationService.showError(e); - } - this.actionPromise = null; - } - createClientOrganization = async () => { const reference = openCreateClientOrganizationDialog(this.dialogService, { data: { diff --git a/libs/common/src/admin-console/enums/index.ts b/libs/common/src/admin-console/enums/index.ts index 0cbdf65805..83b8a941a0 100644 --- a/libs/common/src/admin-console/enums/index.ts +++ b/libs/common/src/admin-console/enums/index.ts @@ -7,3 +7,4 @@ export * from "./provider-type.enum"; export * from "./provider-user-status-type.enum"; export * from "./provider-user-type.enum"; export * from "./scim-provider-type.enum"; +export * from "./provider-status-type.enum"; diff --git a/libs/common/src/admin-console/enums/provider-status-type.enum.ts b/libs/common/src/admin-console/enums/provider-status-type.enum.ts new file mode 100644 index 0000000000..8da60af0eb --- /dev/null +++ b/libs/common/src/admin-console/enums/provider-status-type.enum.ts @@ -0,0 +1,5 @@ +export enum ProviderStatusType { + Pending = 0, + Created = 1, + Billable = 2, +} diff --git a/libs/common/src/admin-console/models/data/provider.data.ts b/libs/common/src/admin-console/models/data/provider.data.ts index a848888025..ff060ae270 100644 --- a/libs/common/src/admin-console/models/data/provider.data.ts +++ b/libs/common/src/admin-console/models/data/provider.data.ts @@ -1,4 +1,4 @@ -import { ProviderUserStatusType, ProviderUserType } from "../../enums"; +import { ProviderStatusType, ProviderUserStatusType, ProviderUserType } from "../../enums"; import { ProfileProviderResponse } from "../response/profile-provider.response"; export class ProviderData { @@ -9,6 +9,7 @@ export class ProviderData { enabled: boolean; userId: string; useEvents: boolean; + providerStatus: ProviderStatusType; constructor(response: ProfileProviderResponse) { this.id = response.id; @@ -18,5 +19,6 @@ export class ProviderData { this.enabled = response.enabled; this.userId = response.userId; this.useEvents = response.useEvents; + this.providerStatus = response.providerStatus; } } diff --git a/libs/common/src/admin-console/models/domain/provider.ts b/libs/common/src/admin-console/models/domain/provider.ts index d6d3d3c462..d51f698547 100644 --- a/libs/common/src/admin-console/models/domain/provider.ts +++ b/libs/common/src/admin-console/models/domain/provider.ts @@ -1,4 +1,4 @@ -import { ProviderUserStatusType, ProviderUserType } from "../../enums"; +import { ProviderStatusType, ProviderUserStatusType, ProviderUserType } from "../../enums"; import { ProviderData } from "../data/provider.data"; export class Provider { @@ -9,6 +9,7 @@ export class Provider { enabled: boolean; userId: string; useEvents: boolean; + providerStatus: ProviderStatusType; constructor(obj?: ProviderData) { if (obj == null) { @@ -22,6 +23,7 @@ export class Provider { this.enabled = obj.enabled; this.userId = obj.userId; this.useEvents = obj.useEvents; + this.providerStatus = obj.providerStatus; } get canAccess() { diff --git a/libs/common/src/admin-console/models/response/profile-provider.response.ts b/libs/common/src/admin-console/models/response/profile-provider.response.ts index eaecc9b847..701fe843de 100644 --- a/libs/common/src/admin-console/models/response/profile-provider.response.ts +++ b/libs/common/src/admin-console/models/response/profile-provider.response.ts @@ -1,5 +1,5 @@ import { BaseResponse } from "../../../models/response/base.response"; -import { ProviderUserStatusType, ProviderUserType } from "../../enums"; +import { ProviderStatusType, ProviderUserStatusType, ProviderUserType } from "../../enums"; import { PermissionsApi } from "../api/permissions.api"; export class ProfileProviderResponse extends BaseResponse { @@ -12,6 +12,7 @@ export class ProfileProviderResponse extends BaseResponse { permissions: PermissionsApi; userId: string; useEvents: boolean; + providerStatus: ProviderStatusType; constructor(response: any) { super(response); @@ -24,5 +25,6 @@ export class ProfileProviderResponse extends BaseResponse { this.permissions = new PermissionsApi(this.getResponseProperty("permissions")); this.userId = this.getResponseProperty("UserId"); this.useEvents = this.getResponseProperty("UseEvents"); + this.providerStatus = this.getResponseProperty("ProviderStatus"); } } diff --git a/libs/common/src/admin-console/services/provider.service.spec.ts b/libs/common/src/admin-console/services/provider.service.spec.ts index fcba9d5023..95da633f5c 100644 --- a/libs/common/src/admin-console/services/provider.service.spec.ts +++ b/libs/common/src/admin-console/services/provider.service.spec.ts @@ -2,7 +2,7 @@ import { FakeAccountService, FakeStateProvider, mockAccountServiceWith } from ". import { FakeActiveUserState, FakeSingleUserState } from "../../../spec/fake-state"; import { Utils } from "../../platform/misc/utils"; import { UserId } from "../../types/guid"; -import { ProviderUserStatusType, ProviderUserType } from "../enums"; +import { ProviderStatusType, ProviderUserStatusType, ProviderUserType } from "../enums"; import { ProviderData } from "../models/data/provider.data"; import { Provider } from "../models/domain/provider"; @@ -64,6 +64,7 @@ describe("PROVIDERS key definition", () => { enabled: true, userId: "string", useEvents: true, + providerStatus: ProviderStatusType.Pending, }, }; const result = sut.deserializer(JSON.parse(JSON.stringify(expectedResult)));