1
0
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:
Jordan Aasen
2025-03-14 15:37:44 -07:00
committed by GitHub
parent 53a032ca65
commit fdcb6ff7a2
5 changed files with 2 additions and 277 deletions

View File

@@ -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": {

View File

@@ -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 {}

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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)"
},