1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-09-27 04:03:00 +02:00
bitwarden-browser/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.ts
Colton Hurst 138a4923c7
SM-615: Add Error Messages for Unselected Bulk Actions in SM (#5006)
* SM-615: Add error message when doing bulk actions on projects and secrets but nothing is selected

* SM-615: Add alert for service account unselected bulk deletes
2023-03-20 11:31:14 -04:00

164 lines
4.6 KiB
TypeScript

import { SelectionModel } from "@angular/cdk/collections";
import { Component, EventEmitter, Input, OnDestroy, Output } from "@angular/core";
import { Subject, takeUntil } from "rxjs";
import { I18nService } from "@bitwarden/common/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/abstractions/platformUtils.service";
import { TableDataSource } from "@bitwarden/components";
import { SecretListView } from "../models/view/secret-list.view";
import { SecretService } from "../secrets/secret.service";
@Component({
selector: "sm-secrets-list",
templateUrl: "./secrets-list.component.html",
})
export class SecretsListComponent implements OnDestroy {
protected dataSource = new TableDataSource<SecretListView>();
@Input()
get secrets(): SecretListView[] {
return this._secrets;
}
set secrets(secrets: SecretListView[]) {
this.selection.clear();
this._secrets = secrets;
this.dataSource.data = secrets;
}
private _secrets: SecretListView[];
@Input()
set search(search: string) {
this.dataSource.filter = search;
}
@Input() trash: boolean;
@Output() editSecretEvent = new EventEmitter<string>();
@Output() copySecretNameEvent = new EventEmitter<string>();
@Output() copySecretValueEvent = new EventEmitter<string>();
@Output() onSecretCheckedEvent = new EventEmitter<string[]>();
@Output() deleteSecretsEvent = new EventEmitter<SecretListView[]>();
@Output() newSecretEvent = new EventEmitter();
@Output() restoreSecretsEvent = new EventEmitter();
private destroy$: Subject<void> = new Subject<void>();
selection = new SelectionModel<string>(true, []);
constructor(
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService
) {
this.selection.changed
.pipe(takeUntil(this.destroy$))
.subscribe((_) => this.onSecretCheckedEvent.emit(this.selection.selected));
}
ngOnDestroy(): void {
this.destroy$.next();
this.destroy$.complete();
}
isAllSelected() {
const numSelected = this.selection.selected.length;
const numRows = this.secrets.length;
return numSelected === numRows;
}
toggleAll() {
this.isAllSelected()
? this.selection.clear()
: this.selection.select(...this.secrets.map((s) => s.id));
}
bulkDeleteSecrets() {
if (this.selection.selected.length >= 1) {
this.deleteSecretsEvent.emit(
this.secrets.filter((secret) => this.selection.isSelected(secret.id))
);
} else {
this.platformUtilsService.showToast(
"error",
this.i18nService.t("errorOccurred"),
this.i18nService.t("nothingSelected")
);
}
}
bulkRestoreSecrets() {
if (this.selection.selected.length >= 1) {
this.restoreSecretsEvent.emit(this.selection.selected);
} else {
this.platformUtilsService.showToast(
"error",
this.i18nService.t("errorOccurred"),
this.i18nService.t("nothingSelected")
);
}
}
sortProjects = (a: SecretListView, b: SecretListView): number => {
const aProjects = a.projects;
const bProjects = b.projects;
if (aProjects.length !== bProjects.length) {
return aProjects.length - bProjects.length;
}
return aProjects[0]?.name.localeCompare(bProjects[0].name);
};
/**
* TODO: Refactor to smart component and remove
*/
static copySecretName(
name: string,
platformUtilsService: PlatformUtilsService,
i18nService: I18nService
) {
platformUtilsService.copyToClipboard(name);
platformUtilsService.showToast(
"success",
null,
i18nService.t("valueCopied", i18nService.t("name"))
);
}
/**
* TODO: Refactor to smart component and remove
*/
static copySecretValue(
id: string,
platformUtilsService: PlatformUtilsService,
i18nService: I18nService,
secretService: SecretService
) {
const value = secretService.getBySecretId(id).then((secret) => secret.value);
SecretsListComponent.copyToClipboardAsync(value, platformUtilsService).then(() => {
platformUtilsService.showToast(
"success",
null,
i18nService.t("valueCopied", i18nService.t("value"))
);
});
}
/**
* TODO: Remove in favor of updating `PlatformUtilsService.copyToClipboard`
*/
private static copyToClipboardAsync(
text: Promise<string>,
platformUtilsService: PlatformUtilsService
) {
if (platformUtilsService.isSafari()) {
return navigator.clipboard.write([
new ClipboardItem({
["text/plain"]: text,
}),
]);
}
return text.then((t) => platformUtilsService.copyToClipboard(t));
}
}