mirror of
https://github.com/bitwarden/browser
synced 2025-12-23 11:43:46 +00:00
remove bulk share dialog components and related modules and i18n keys (#13815)
This commit is contained in:
@@ -4,11 +4,10 @@ import { SharedModule } from "../../../shared";
|
||||
|
||||
import { BulkDeleteDialogComponent } from "./bulk-delete-dialog/bulk-delete-dialog.component";
|
||||
import { BulkMoveDialogComponent } from "./bulk-move-dialog/bulk-move-dialog.component";
|
||||
import { BulkShareDialogComponent } from "./bulk-share-dialog/bulk-share-dialog.component";
|
||||
|
||||
@NgModule({
|
||||
imports: [SharedModule],
|
||||
declarations: [BulkDeleteDialogComponent, BulkMoveDialogComponent, BulkShareDialogComponent],
|
||||
exports: [BulkDeleteDialogComponent, BulkMoveDialogComponent, BulkShareDialogComponent],
|
||||
declarations: [BulkDeleteDialogComponent, BulkMoveDialogComponent],
|
||||
exports: [BulkDeleteDialogComponent, BulkMoveDialogComponent],
|
||||
})
|
||||
export class BulkDialogsModule {}
|
||||
|
||||
@@ -1,73 +0,0 @@
|
||||
<bit-dialog>
|
||||
<span bitDialogTitle>
|
||||
{{ "moveSelectedToOrg" | i18n }}
|
||||
</span>
|
||||
<span bitDialogContent>
|
||||
<p>{{ "moveManyToOrgDesc" | i18n }}</p>
|
||||
<p>
|
||||
{{
|
||||
"moveSelectedItemsCountDesc"
|
||||
| i18n: this.ciphers.length : shareableCiphers.length : nonShareableCount
|
||||
}}
|
||||
</p>
|
||||
<bit-form-field>
|
||||
<bit-label for="organization">{{ "organization" | i18n }}</bit-label>
|
||||
<select
|
||||
bitInput
|
||||
[(ngModel)]="organizationId"
|
||||
id="organization"
|
||||
(change)="filterCollections()"
|
||||
>
|
||||
<option *ngFor="let o of organizations" [ngValue]="o.id">{{ o.name }}</option>
|
||||
</select>
|
||||
</bit-form-field>
|
||||
|
||||
<div class="d-flex">
|
||||
<label class="tw-mb-1 tw-block tw-font-semibold tw-text-main">{{
|
||||
"collections" | i18n
|
||||
}}</label>
|
||||
<div class="tw-ml-auto tw-flex tw-gap-2" *ngIf="collections && collections.length">
|
||||
<button bitLink type="button" (click)="selectAll(true)" class="tw-px-2">
|
||||
{{ "selectAll" | i18n }}
|
||||
</button>
|
||||
<button bitLink type="button" (click)="selectAll(false)" class="tw-px-2">
|
||||
{{ "unselectAll" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div *ngIf="!collections || !collections.length">
|
||||
{{ "noCollectionsInList" | i18n }}
|
||||
</div>
|
||||
<table
|
||||
class="table table-hover table-list mb-0"
|
||||
*ngIf="collections && collections.length"
|
||||
id="collections"
|
||||
>
|
||||
<tbody>
|
||||
<tr *ngFor="let c of collections; let i = index" (click)="check(c)">
|
||||
<td class="table-list-checkbox">
|
||||
<input
|
||||
bitInput
|
||||
type="checkbox"
|
||||
[(ngModel)]="c.checked"
|
||||
name="Collection[{{ i }}].Checked"
|
||||
attr.aria-label="Check {{ c.name }}"
|
||||
appStopProp
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
{{ c.name }}
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</span>
|
||||
<ng-container bitDialogFooter>
|
||||
<button bitButton type="submit" buttonType="primary" [bitAction]="submit">
|
||||
{{ "save" | i18n }}
|
||||
</button>
|
||||
<button bitButton type="button" buttonType="secondary" (click)="cancel()">
|
||||
{{ "cancel" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
</bit-dialog>
|
||||
@@ -1,160 +0,0 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { DialogConfig, DialogRef, DIALOG_DATA } from "@angular/cdk/dialog";
|
||||
import { Component, Inject, OnDestroy, OnInit } from "@angular/core";
|
||||
import { firstValueFrom, map } from "rxjs";
|
||||
|
||||
import { CollectionService, CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { Checkable, isChecked } from "@bitwarden/common/types/checkable";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { DialogService, ToastService } from "@bitwarden/components";
|
||||
|
||||
export interface BulkShareDialogParams {
|
||||
ciphers: CipherView[];
|
||||
organizationId?: string;
|
||||
}
|
||||
|
||||
export enum BulkShareDialogResult {
|
||||
Shared = "shared",
|
||||
Canceled = "canceled",
|
||||
}
|
||||
|
||||
/**
|
||||
* Strongly typed helper to open a BulkShareDialog
|
||||
* @param dialogService Instance of the dialog service that will be used to open the dialog
|
||||
* @param config Configuration for the dialog
|
||||
*/
|
||||
export const openBulkShareDialog = (
|
||||
dialogService: DialogService,
|
||||
config: DialogConfig<BulkShareDialogParams>,
|
||||
) => {
|
||||
return dialogService.open<BulkShareDialogResult, BulkShareDialogParams>(
|
||||
BulkShareDialogComponent,
|
||||
config,
|
||||
);
|
||||
};
|
||||
|
||||
@Component({
|
||||
templateUrl: "bulk-share-dialog.component.html",
|
||||
})
|
||||
export class BulkShareDialogComponent implements OnInit, OnDestroy {
|
||||
ciphers: CipherView[] = [];
|
||||
organizationId: string;
|
||||
|
||||
nonShareableCount = 0;
|
||||
collections: Checkable<CollectionView>[] = [];
|
||||
organizations: Organization[] = [];
|
||||
shareableCiphers: CipherView[] = [];
|
||||
|
||||
private writeableCollections: CollectionView[] = [];
|
||||
|
||||
constructor(
|
||||
@Inject(DIALOG_DATA) params: BulkShareDialogParams,
|
||||
private dialogRef: DialogRef<BulkShareDialogResult>,
|
||||
private cipherService: CipherService,
|
||||
private i18nService: I18nService,
|
||||
private collectionService: CollectionService,
|
||||
private organizationService: OrganizationService,
|
||||
private logService: LogService,
|
||||
private accountService: AccountService,
|
||||
private toastService: ToastService,
|
||||
) {
|
||||
this.ciphers = params.ciphers ?? [];
|
||||
this.organizationId = params.organizationId;
|
||||
}
|
||||
|
||||
async ngOnInit() {
|
||||
this.shareableCiphers = this.ciphers.filter(
|
||||
(c) => !c.hasOldAttachments && c.organizationId == null,
|
||||
);
|
||||
this.nonShareableCount = this.ciphers.length - this.shareableCiphers.length;
|
||||
const allCollections = await this.collectionService.getAllDecrypted();
|
||||
this.writeableCollections = allCollections.filter((c) => !c.readOnly);
|
||||
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
|
||||
this.organizations = await firstValueFrom(this.organizationService.organizations$(userId));
|
||||
if (this.organizationId == null && this.organizations.length > 0) {
|
||||
this.organizationId = this.organizations[0].id;
|
||||
}
|
||||
this.filterCollections();
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.selectAll(false);
|
||||
}
|
||||
|
||||
filterCollections() {
|
||||
this.selectAll(false);
|
||||
if (this.organizationId == null || this.writeableCollections.length === 0) {
|
||||
this.collections = [];
|
||||
} else {
|
||||
this.collections = this.writeableCollections.filter(
|
||||
(c) => c.organizationId === this.organizationId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
submit = async () => {
|
||||
const checkedCollectionIds = this.collections.filter(isChecked).map((c) => c.id);
|
||||
try {
|
||||
const activeUserId = await firstValueFrom(
|
||||
this.accountService.activeAccount$.pipe(map((a) => a?.id)),
|
||||
);
|
||||
await this.cipherService.shareManyWithServer(
|
||||
this.shareableCiphers,
|
||||
this.organizationId,
|
||||
checkedCollectionIds,
|
||||
activeUserId,
|
||||
);
|
||||
const orgName =
|
||||
this.organizations.find((o) => o.id === this.organizationId)?.name ??
|
||||
this.i18nService.t("organization");
|
||||
this.toastService.showToast({
|
||||
variant: "success",
|
||||
title: null,
|
||||
message: this.i18nService.t("movedItemsToOrg", orgName),
|
||||
});
|
||||
this.close(BulkShareDialogResult.Shared);
|
||||
} catch (e) {
|
||||
this.logService.error(e);
|
||||
}
|
||||
};
|
||||
|
||||
check(c: Checkable<CollectionView>, select?: boolean) {
|
||||
c.checked = select == null ? !c.checked : select;
|
||||
}
|
||||
|
||||
selectAll(select: boolean) {
|
||||
const collections = select ? this.collections : this.writeableCollections;
|
||||
collections.forEach((c) => this.check(c, select));
|
||||
}
|
||||
|
||||
get canSave() {
|
||||
if (
|
||||
this.shareableCiphers != null &&
|
||||
this.shareableCiphers.length > 0 &&
|
||||
this.collections != null
|
||||
) {
|
||||
for (let i = 0; i < this.collections.length; i++) {
|
||||
if (this.collections[i].checked) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected cancel() {
|
||||
this.close(BulkShareDialogResult.Canceled);
|
||||
}
|
||||
|
||||
private close(result: BulkShareDialogResult) {
|
||||
this.dialogRef.close(result);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user