mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 21:33:27 +00:00
remove bulk share dialog components and related modules and i18n keys (#13815)
This commit is contained in:
@@ -4733,15 +4733,6 @@
|
||||
"nothingSelected": {
|
||||
"message": "You have not selected anything."
|
||||
},
|
||||
"movedItemsToOrg": {
|
||||
"message": "Selected items moved to $ORGNAME$",
|
||||
"placeholders": {
|
||||
"orgname": {
|
||||
"content": "$1",
|
||||
"example": "Company Name"
|
||||
}
|
||||
}
|
||||
},
|
||||
"itemsMovedToOrg": {
|
||||
"message": "Items moved to $ORGNAME$",
|
||||
"placeholders": {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -900,9 +900,6 @@
|
||||
"filter": {
|
||||
"message": "Filter"
|
||||
},
|
||||
"moveSelectedToOrg": {
|
||||
"message": "Move selected to organization"
|
||||
},
|
||||
"deleteSelected": {
|
||||
"message": "Delete selected"
|
||||
},
|
||||
@@ -958,15 +955,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"movedItemsToOrg": {
|
||||
"message": "Selected items moved to $ORGNAME$",
|
||||
"placeholders": {
|
||||
"orgname": {
|
||||
"content": "$1",
|
||||
"example": "Company Name"
|
||||
}
|
||||
}
|
||||
},
|
||||
"itemsMovedToOrg": {
|
||||
"message": "Items moved to $ORGNAME$",
|
||||
"placeholders": {
|
||||
@@ -1592,9 +1580,6 @@
|
||||
"moveToOrgDesc": {
|
||||
"message": "Choose an organization that you wish to move this item to. Moving to an organization transfers ownership of the item to that organization. You will no longer be the direct owner of this item once it has been moved."
|
||||
},
|
||||
"moveManyToOrgDesc": {
|
||||
"message": "Choose an organization that you wish to move these items to. Moving to an organization transfers ownership of the items to that organization. You will no longer be the direct owner of these items once they have been moved."
|
||||
},
|
||||
"collectionsDesc": {
|
||||
"message": "Edit the collections that this item is being shared with. Only organization users with access to these collections will be able to see this item."
|
||||
},
|
||||
@@ -1628,23 +1613,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"moveSelectedItemsCountDesc": {
|
||||
"message": "You have selected $COUNT$ item(s). $MOVEABLE_COUNT$ item(s) can be moved to an organization, $NONMOVEABLE_COUNT$ cannot.",
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"content": "$1",
|
||||
"example": "10"
|
||||
},
|
||||
"moveable_count": {
|
||||
"content": "$2",
|
||||
"example": "8"
|
||||
},
|
||||
"nonmoveable_count": {
|
||||
"content": "$3",
|
||||
"example": "2"
|
||||
}
|
||||
}
|
||||
},
|
||||
"verificationCodeTotp": {
|
||||
"message": "Verification code (TOTP)"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user