mirror of
https://github.com/bitwarden/browser
synced 2026-02-06 03:33:30 +00:00
Apply the requested changes
This commit is contained in:
@@ -1,37 +1,19 @@
|
||||
@let isSuspensionActive = suspensionActive$ | async;
|
||||
@let isAdminOrServiceUser = isAdminOrServiceUser$ | async;
|
||||
<app-header>
|
||||
<bit-search
|
||||
class="tw-grow"
|
||||
[formControl]="searchControl"
|
||||
[placeholder]="'search' | i18n"
|
||||
></bit-search>
|
||||
<a
|
||||
bitButton
|
||||
routerLink="create"
|
||||
*ngIf="manageOrganizations && isSuspensionActive"
|
||||
buttonType="primary"
|
||||
>
|
||||
<a bitButton routerLink="create" *ngIf="isAdminOrServiceUser" buttonType="primary">
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "newClient" | i18n }}
|
||||
</a>
|
||||
<button
|
||||
*ngIf="manageOrganizations && isSuspensionActive"
|
||||
type="button"
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
[disabled]="true"
|
||||
[title]="'providerIsDisabled' | i18n"
|
||||
>
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "newClient" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
bitButton
|
||||
[disabled]="isSuspensionActive"
|
||||
[title]="isSuspensionActive ? ('providerIsDisabled' | i18n) : ''"
|
||||
(click)="addExistingOrganization()"
|
||||
*ngIf="manageOrganizations && showAddExisting"
|
||||
*ngIf="isAdminOrServiceUser && showAddExisting"
|
||||
>
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "addExistingOrganization" | i18n }}
|
||||
@@ -71,7 +53,7 @@
|
||||
<span>{{ row.plan }}</span>
|
||||
<div appListDropdown>
|
||||
<button
|
||||
*ngIf="manageOrganizations"
|
||||
*ngIf="isAdminOrServiceUser"
|
||||
[bitMenuTriggerFor]="removeMenu"
|
||||
bitMenuItem
|
||||
buttonType="secondary"
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Component } from "@angular/core";
|
||||
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
|
||||
import { FormControl } from "@angular/forms";
|
||||
import { ActivatedRoute, Router, RouterModule } from "@angular/router";
|
||||
import { firstValueFrom, from, map, combineLatest, switchMap, Observable } from "rxjs";
|
||||
import { firstValueFrom, from, map, Observable, switchMap, tap } from "rxjs";
|
||||
import { debounceTime, first } from "rxjs/operators";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
@@ -13,13 +13,10 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
|
||||
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||
import { ProviderStatusType, ProviderUserType } from "@bitwarden/common/admin-console/enums";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { Provider } from "@bitwarden/common/admin-console/models/domain/provider";
|
||||
import { ProviderOrganizationOrganizationDetailsResponse } from "@bitwarden/common/admin-console/models/response/provider/provider-organization.response";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
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 { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
|
||||
import {
|
||||
@@ -58,24 +55,21 @@ const DisallowedPlanTypes = [
|
||||
})
|
||||
export class ClientsComponent {
|
||||
providerId: string = "";
|
||||
provider: Provider | undefined;
|
||||
addableOrganizations: Organization[] = [];
|
||||
loading = true;
|
||||
manageOrganizations = false;
|
||||
showAddExisting = false;
|
||||
dataSource: TableDataSource<ProviderOrganizationOrganizationDetailsResponse> =
|
||||
new TableDataSource();
|
||||
protected searchControl = new FormControl("", { nonNullable: true });
|
||||
|
||||
protected providerId$: Observable<string> =
|
||||
this.activatedRoute.parent?.params.pipe(map((params) => params.providerId as string)) ??
|
||||
new Observable();
|
||||
this.activatedRoute.parent?.params.pipe(
|
||||
map((params) => params.providerId as string),
|
||||
tap((providerId) => (this.providerId = providerId)),
|
||||
) ?? new Observable();
|
||||
|
||||
protected provider$ = this.providerId$.pipe(
|
||||
switchMap((providerId) => {
|
||||
this.providerId = providerId;
|
||||
return this.providerService.get$(providerId);
|
||||
}),
|
||||
switchMap((providerId) => this.providerService.get$(providerId)),
|
||||
);
|
||||
|
||||
protected isAdminOrServiceUser$ = this.provider$.pipe(
|
||||
@@ -86,21 +80,6 @@ export class ClientsComponent {
|
||||
),
|
||||
);
|
||||
|
||||
protected providerPortalTakeover$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.PM21821_ProviderPortalTakeover,
|
||||
);
|
||||
|
||||
protected suspensionActive$ = combineLatest([
|
||||
this.isAdminOrServiceUser$,
|
||||
this.providerPortalTakeover$,
|
||||
this.provider$.pipe(map((provider) => provider?.enabled ?? false)),
|
||||
]).pipe(
|
||||
map(
|
||||
([isAdminOrServiceUser, portalTakeoverEnabled, providerEnabled]) =>
|
||||
isAdminOrServiceUser && portalTakeoverEnabled && !providerEnabled,
|
||||
),
|
||||
);
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private providerService: ProviderService,
|
||||
@@ -114,7 +93,6 @@ export class ClientsComponent {
|
||||
private toastService: ToastService,
|
||||
private validationService: ValidationService,
|
||||
private webProviderService: WebProviderService,
|
||||
private configService: ConfigService,
|
||||
) {
|
||||
this.activatedRoute.queryParams.pipe(first(), takeUntilDestroyed()).subscribe((queryParams) => {
|
||||
this.searchControl.setValue(queryParams.search);
|
||||
@@ -123,10 +101,6 @@ export class ClientsComponent {
|
||||
this.provider$
|
||||
.pipe(
|
||||
map((provider) => {
|
||||
this.provider = provider;
|
||||
this.manageOrganizations =
|
||||
provider.type === ProviderUserType.ProviderAdmin ||
|
||||
provider.type === ProviderUserType.ServiceUser;
|
||||
if (provider?.providerStatus === ProviderStatusType.Billable) {
|
||||
return from(
|
||||
this.router.navigate(["../manage-client-organizations"], {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
@let isSuspensionActive = suspensionActive$ | async;
|
||||
@let provider = provider$ | async;
|
||||
<app-header [title]="pageTitle">
|
||||
<bit-search [placeholder]="'search' | i18n" [formControl]="searchControl"></bit-search>
|
||||
<button
|
||||
@@ -8,9 +9,7 @@
|
||||
[bitMenuTriggerFor]="clientMenu"
|
||||
[disabled]="isSuspensionActive"
|
||||
[title]="isSuspensionActive ? ('providerIsDisabled' | i18n) : ''"
|
||||
appA11yTitle="{{
|
||||
isSuspensionActive ? ('add' | i18n) : isSuspensionActive ? ('providerIsDisabled' | i18n) : ''
|
||||
}}"
|
||||
appA11yTitle="{{ 'add' | i18n }}"
|
||||
>
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "add" | i18n }}
|
||||
@@ -110,18 +109,20 @@
|
||||
<i aria-hidden="true" class="bwi bwi-family"></i>
|
||||
{{ "manageSubscription" | i18n }}
|
||||
</button>
|
||||
<button *ngIf="isProviderAdmin" type="button" bitMenuItem (click)="remove(row)">
|
||||
<span class="tw-text-danger">
|
||||
<i aria-hidden="true" class="bwi bwi-close"></i> {{ "unlinkOrganization" | i18n }}
|
||||
</span>
|
||||
</button>
|
||||
@if (provider?.type === ProviderUserType.ProviderAdmin) {
|
||||
<button type="button" bitMenuItem (click)="remove(row)">
|
||||
<span class="tw-text-danger">
|
||||
<i aria-hidden="true" class="bwi bwi-close"></i> {{ "unlinkOrganization" | i18n }}
|
||||
</span>
|
||||
</button>
|
||||
}
|
||||
</bit-menu>
|
||||
</td>
|
||||
</ng-template>
|
||||
</bit-table-scroll>
|
||||
<div *ngIf="dataSource.data.length === 0" class="tw-mt-10">
|
||||
<app-no-clients
|
||||
[showAddOrganizationButton]="isProviderAdmin"
|
||||
[showAddOrganizationButton]="provider?.type === ProviderUserType.ProviderAdmin"
|
||||
[disableAddOrganizationButton]="isSuspensionActive"
|
||||
(addNewOrganizationClicked)="createClient()"
|
||||
/>
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
combineLatest,
|
||||
switchMap,
|
||||
Observable,
|
||||
tap,
|
||||
} from "rxjs";
|
||||
import { debounceTime, first } from "rxjs/operators";
|
||||
|
||||
@@ -72,29 +73,26 @@ import { ReplacePipe } from "./replace.pipe";
|
||||
})
|
||||
export class ManageClientsComponent {
|
||||
providerId: string = "";
|
||||
provider: Provider | undefined;
|
||||
loading = true;
|
||||
isProviderAdmin = false;
|
||||
isServiceUser = false;
|
||||
dataSource: TableDataSource<ProviderOrganizationOrganizationDetailsResponse> =
|
||||
new TableDataSource();
|
||||
|
||||
protected searchControl = new FormControl("", { nonNullable: true });
|
||||
protected plans: PlanResponse[] = [];
|
||||
protected ProviderUserType = ProviderUserType;
|
||||
|
||||
pageTitle = this.i18nService.t("clients");
|
||||
clientColumnHeader = this.i18nService.t("client");
|
||||
newClientButtonLabel = this.i18nService.t("newClient");
|
||||
|
||||
protected providerId$: Observable<string> =
|
||||
this.activatedRoute.parent?.params.pipe(map((params) => params.providerId as string)) ??
|
||||
new Observable();
|
||||
this.activatedRoute.parent?.params.pipe(
|
||||
map((params) => params.providerId as string),
|
||||
tap((providerId) => (this.providerId = providerId)),
|
||||
) ?? new Observable();
|
||||
|
||||
protected provider$ = this.providerId$.pipe(
|
||||
switchMap((providerId) => {
|
||||
this.providerId = providerId;
|
||||
return this.providerService.get$(providerId);
|
||||
}),
|
||||
switchMap((providerId) => this.providerService.get$(providerId)),
|
||||
);
|
||||
|
||||
protected isAdminOrServiceUser$ = this.provider$.pipe(
|
||||
@@ -146,9 +144,8 @@ export class ManageClientsComponent {
|
||||
relativeTo: this.activatedRoute,
|
||||
}),
|
||||
);
|
||||
} else {
|
||||
return from(this.load());
|
||||
}
|
||||
return from(this.load());
|
||||
}),
|
||||
takeUntilDestroyed(),
|
||||
)
|
||||
@@ -164,14 +161,12 @@ export class ManageClientsComponent {
|
||||
|
||||
async load() {
|
||||
try {
|
||||
this.provider = await firstValueFrom(this.providerService.get$(this.providerId));
|
||||
if (this.provider?.providerType === ProviderType.BusinessUnit) {
|
||||
const provider = await firstValueFrom(this.providerService.get$(this.providerId));
|
||||
if (provider?.providerType === ProviderType.BusinessUnit) {
|
||||
this.pageTitle = this.i18nService.t("businessUnits");
|
||||
this.clientColumnHeader = this.i18nService.t("businessUnit");
|
||||
this.newClientButtonLabel = this.i18nService.t("newBusinessUnit");
|
||||
}
|
||||
this.isProviderAdmin = this.provider?.type === ProviderUserType.ProviderAdmin;
|
||||
this.isServiceUser = this.provider?.type === ProviderUserType.ServiceUser;
|
||||
this.dataSource.data = (
|
||||
await this.billingApiService.getProviderClientOrganizations(this.providerId)
|
||||
).data;
|
||||
@@ -183,10 +178,11 @@ export class ManageClientsComponent {
|
||||
}
|
||||
|
||||
addExistingOrganization = async () => {
|
||||
if (this.provider) {
|
||||
const provider = await firstValueFrom(this.provider$);
|
||||
if (provider) {
|
||||
const reference = AddExistingOrganizationDialogComponent.open(this.dialogService, {
|
||||
data: {
|
||||
provider: this.provider,
|
||||
provider: provider,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -235,10 +231,11 @@ export class ManageClientsComponent {
|
||||
manageClientSubscription = async (
|
||||
organization: ProviderOrganizationOrganizationDetailsResponse,
|
||||
) => {
|
||||
const provider = await firstValueFrom(this.provider$);
|
||||
const dialogRef = openManageClientSubscriptionDialog(this.dialogService, {
|
||||
data: {
|
||||
organization,
|
||||
provider: this.provider!,
|
||||
provider: provider!,
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user