bitwarden-estensione-browser/bitwarden_license/bit-web/src/app/admin-console/providers/clients/base-clients.component.ts

131 lines
4.1 KiB
TypeScript

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<void>();
private searchText$ = new BehaviorSubject<string>("");
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<string>(true, []);
protected clients: ProviderOrganizationOrganizationDetailsResponse[];
protected pagedClients: ProviderOrganizationOrganizationDetailsResponse[];
protected dataSource = new TableDataSource<ProviderOrganizationOrganizationDetailsResponse>();
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<void>;
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);
}
}
}