1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-22 11:13:46 +00:00
Files
browser/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts
2024-07-09 14:33:07 +01:00

128 lines
4.7 KiB
TypeScript

import { Component, OnDestroy, OnInit } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { firstValueFrom, from, map } from "rxjs";
import { switchMap, takeUntil } from "rxjs/operators";
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 { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { hasConsolidatedBilling } from "@bitwarden/common/billing/abstractions/provider-billing.service.abstraction";
import { PlanType } from "@bitwarden/common/billing/enums";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
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,
PlanType.FamiliesAnnually2019,
PlanType.FamiliesAnnually,
PlanType.TeamsStarter2023,
PlanType.TeamsStarter,
];
@Component({
templateUrl: "clients.component.html",
})
export class ClientsComponent extends BaseClientsComponent implements OnInit, OnDestroy {
providerId: string;
addableOrganizations: Organization[];
loading = true;
manageOrganizations = false;
showAddExisting = false;
constructor(
private router: Router,
private providerService: ProviderService,
private apiService: ApiService,
private organizationService: OrganizationService,
private organizationApiService: OrganizationApiServiceAbstraction,
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,
);
}
ngOnInit() {
this.activatedRoute.parent.params
.pipe(
switchMap((params) => {
this.providerId = params.providerId;
return this.providerService.get$(this.providerId).pipe(
hasConsolidatedBilling(this.configService),
map((hasConsolidatedBilling) => {
if (hasConsolidatedBilling) {
return from(
this.router.navigate(["../manage-client-organizations"], {
relativeTo: this.activatedRoute,
}),
);
} else {
return from(this.load());
}
}),
);
}),
takeUntil(this.destroy$),
)
.subscribe();
}
ngOnDestroy() {
super.ngOnDestroy();
}
async load() {
const response = await this.apiService.getProviderClients(this.providerId);
this.clients = response.data != null && response.data.length > 0 ? response.data : [];
this.manageOrganizations =
(await this.providerService.get(this.providerId)).type === ProviderUserType.ProviderAdmin;
const candidateOrgs = (await this.organizationService.getAll()).filter(
(o) => o.isOwner && o.providerId == null,
);
const allowedOrgsIds = await Promise.all(
candidateOrgs.map((o) => this.organizationApiService.get(o.id)),
).then((orgs) =>
orgs.filter((o) => !DisallowedPlanTypes.includes(o.planType)).map((o) => o.id),
);
this.addableOrganizations = candidateOrgs.filter((o) => allowedOrgsIds.includes(o.id));
this.showAddExisting = this.addableOrganizations.length !== 0;
this.loading = false;
}
async addExistingOrganization() {
const dialogRef = AddOrganizationComponent.open(this.dialogService, {
providerId: this.providerId,
organizations: this.addableOrganizations,
});
if (await firstValueFrom(dialogRef.closed)) {
await this.load();
}
}
}