1
0
mirror of https://github.com/bitwarden/browser.git synced 2025-01-22 21:21:35 +01:00

[PM-13306] - add missing elements to browser vault trash list ()

* add missing elements to trash list

* fix failing test
This commit is contained in:
Jordan Aasen 2025-01-09 09:40:59 -08:00 committed by GitHub
parent 8fe1802963
commit 06ca00f3c1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 17 deletions

View File

@ -361,20 +361,17 @@ describe("VaultPopupItemsService", () => {
});
describe("deletedCiphers$", () => {
it("should return deleted ciphers", (done) => {
const ciphers = [
{ id: "1", type: CipherType.Login, name: "Login 1", isDeleted: true },
{ id: "2", type: CipherType.Login, name: "Login 2", isDeleted: true },
{ id: "3", type: CipherType.Login, name: "Login 3", isDeleted: true },
{ id: "4", type: CipherType.Login, name: "Login 4", isDeleted: false },
] as CipherView[];
it("should return deleted ciphers", async () => {
const deletedCipher = new CipherView();
deletedCipher.deletedDate = new Date();
const ciphers = [new CipherView(), new CipherView(), new CipherView(), deletedCipher];
cipherServiceMock.getAllDecrypted.mockResolvedValue(ciphers);
service.deletedCiphers$.subscribe((deletedCiphers) => {
expect(deletedCiphers.length).toBe(3);
done();
});
(cipherServiceMock.ciphers$ as BehaviorSubject<any>).next(null);
const deletedCiphers = await firstValueFrom(service.deletedCiphers$);
expect(deletedCiphers.length).toBe(1);
});
});

View File

@ -247,8 +247,28 @@ export class VaultPopupItemsService {
/**
* Observable that contains the list of ciphers that have been deleted.
*/
deletedCiphers$: Observable<CipherView[]> = this._allDecryptedCiphers$.pipe(
map((ciphers) => ciphers.filter((c) => c.isDeleted)),
deletedCiphers$: Observable<PopupCipherView[]> = this._allDecryptedCiphers$.pipe(
switchMap((ciphers) =>
combineLatest([
this.organizationService.organizations$,
this.collectionService.decryptedCollections$,
]).pipe(
map(([organizations, collections]) => {
const orgMap = Object.fromEntries(organizations.map((org) => [org.id, org]));
const collectionMap = Object.fromEntries(collections.map((col) => [col.id, col]));
return ciphers
.filter((c) => c.isDeleted)
.map(
(cipher) =>
new PopupCipherView(
cipher,
cipher.collectionIds?.map((colId) => collectionMap[colId as CollectionId]),
orgMap[cipher.organizationId as OrganizationId],
),
);
}),
),
),
shareReplay({ refCount: false, bufferSize: 1 }),
);

View File

@ -13,8 +13,23 @@
[appA11yTitle]="'viewItemTitle' | i18n: cipher.name"
(click)="onViewCipher(cipher)"
>
<app-vault-icon slot="start" [cipher]="cipher"></app-vault-icon>
<div slot="start" class="tw-justify-start tw-w-7 tw-flex">
<app-vault-icon [cipher]="cipher"></app-vault-icon>
</div>
<span data-testid="item-name">{{ cipher.name }}</span>
<i
*ngIf="cipher.organizationId"
appOrgIcon
[tierType]="cipher.organization.productTierType"
[size]="'small'"
[appA11yTitle]="orgIconTooltip(cipher)"
></i>
<i
*ngIf="cipher.hasAttachments"
class="bwi bwi-paperclip bwi-sm"
[appA11yTitle]="'attachments' | i18n"
></i>
<span slot="secondary">{{ cipher.subTitle }}</span>
</button>
<ng-container slot="end" *ngIf="cipher.edit">
<bit-item-action>

View File

@ -23,9 +23,12 @@ import {
import {
CanDeleteCipherDirective,
DecryptionFailureDialogComponent,
OrgIconDirective,
PasswordRepromptService,
} from "@bitwarden/vault";
import { PopupCipherView } from "../../views/popup-cipher.view";
@Component({
selector: "app-trash-list-items-container",
templateUrl: "trash-list-items-container.component.html",
@ -39,6 +42,7 @@ import {
CanDeleteCipherDirective,
MenuModule,
IconButtonModule,
OrgIconDirective,
TypographyModule,
DecryptionFailureDialogComponent,
],
@ -49,7 +53,7 @@ export class TrashListItemsContainerComponent {
* The list of trashed items to display.
*/
@Input()
ciphers: CipherView[] = [];
ciphers: PopupCipherView[] = [];
@Input()
headerText: string;
@ -64,6 +68,17 @@ export class TrashListItemsContainerComponent {
private router: Router,
) {}
/**
* The tooltip text for the organization icon for ciphers that belong to an organization.
*/
orgIconTooltip(cipher: PopupCipherView) {
if (cipher.collectionIds.length > 1) {
return this.i18nService.t("nCollections", cipher.collectionIds.length);
}
return cipher.collections[0]?.name;
}
async restore(cipher: CipherView) {
try {
await this.cipherService.restoreWithServer(cipher.id);

View File

@ -8,7 +8,6 @@ import { VaultIcons } from "@bitwarden/vault";
import { PopOutComponent } from "../../../platform/popup/components/pop-out.component";
import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component";
import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component";
import { VaultListItemsContainerComponent } from "../components/vault-v2/vault-list-items-container/vault-list-items-container.component";
import { VaultPopupItemsService } from "../services/vault-popup-items.service";
import { TrashListItemsContainerComponent } from "./trash-list-items-container/trash-list-items-container.component";
@ -22,7 +21,6 @@ import { TrashListItemsContainerComponent } from "./trash-list-items-container/t
PopupPageComponent,
PopupHeaderComponent,
PopOutComponent,
VaultListItemsContainerComponent,
TrashListItemsContainerComponent,
CalloutModule,
NoItemsModule,