From 246765a1aab8035ff2c2587425fa3d372ec14310 Mon Sep 17 00:00:00 2001
From: Nick Krantz <125900171+nick-livefront@users.noreply.github.com>
Date: Mon, 19 Jan 2026 13:25:46 -0600
Subject: [PATCH] [PM-30453] Archive UI Updates (#18297)
* add org icon to archive list view
* update content of archive confirmation dialog
* fix typing
---
apps/browser/src/_locales/en/messages.json | 4 +-
.../item-more-options.component.ts | 3 +-
.../popup/settings/archive.component.html | 20 +++++++--
.../vault/popup/settings/archive.component.ts | 42 +++++++++++++++++++
apps/desktop/src/locales/en/messages.json | 4 +-
.../vault/individual-vault/vault.component.ts | 3 +-
apps/web/src/locales/en/messages.json | 4 +-
.../archive-cipher-utilities.service.ts | 3 +-
8 files changed, 71 insertions(+), 12 deletions(-)
diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json
index 36ba57cb7e8..90cc4a5c338 100644
--- a/apps/browser/src/_locales/en/messages.json
+++ b/apps/browser/src/_locales/en/messages.json
@@ -582,8 +582,8 @@
"archiveItem": {
"message": "Archive item"
},
- "archiveItemConfirmDesc": {
- "message": "Archived items are excluded from general search results and autofill suggestions. Are you sure you want to archive this item?"
+ "archiveItemDialogContent": {
+ "message": "Once archived, this item will be excluded from search results and autofill suggestions."
},
"archived": {
"message": "Archived"
diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts
index ce797d9755e..f881b07282b 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts
+++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.ts
@@ -376,7 +376,8 @@ export class ItemMoreOptionsComponent {
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "archiveItem" },
- content: { key: "archiveItemConfirmDesc" },
+ content: { key: "archiveItemDialogContent" },
+ acceptButtonText: { key: "archiveVerb" },
type: "info",
});
diff --git a/apps/browser/src/vault/popup/settings/archive.component.html b/apps/browser/src/vault/popup/settings/archive.component.html
index 16afab4384b..01ac799ba29 100644
--- a/apps/browser/src/vault/popup/settings/archive.component.html
+++ b/apps/browser/src/vault/popup/settings/archive.component.html
@@ -42,9 +42,23 @@
{{ cipher.name }}
- @if (CipherViewLikeUtils.hasAttachments(cipher)) {
-
- }
+
+ @if (cipher.organizationId) {
+
+ }
+ @if (CipherViewLikeUtils.hasAttachments(cipher)) {
+
+ }
+
{{ CipherViewLikeUtils.subtitle(cipher) }}
diff --git a/apps/browser/src/vault/popup/settings/archive.component.ts b/apps/browser/src/vault/popup/settings/archive.component.ts
index ecf091a7322..8a81d733039 100644
--- a/apps/browser/src/vault/popup/settings/archive.component.ts
+++ b/apps/browser/src/vault/popup/settings/archive.component.ts
@@ -1,11 +1,13 @@
import { CommonModule } from "@angular/common";
import { Component, inject } from "@angular/core";
+import { toSignal } from "@angular/core/rxjs-interop";
import { Router } from "@angular/router";
import { combineLatest, firstValueFrom, map, Observable, startWith, switchMap } from "rxjs";
import { CollectionService } from "@bitwarden/admin-console/common";
import { JslibModule } from "@bitwarden/angular/jslib.module";
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";
@@ -33,6 +35,7 @@ import {
import {
CanDeleteCipherDirective,
DecryptionFailureDialogComponent,
+ OrgIconDirective,
PasswordRepromptService,
} from "@bitwarden/vault";
@@ -60,6 +63,7 @@ import { ROUTES_AFTER_EDIT_DELETION } from "../components/vault-v2/add-edit/add-
SectionComponent,
SectionHeaderComponent,
TypographyModule,
+ OrgIconDirective,
CardComponent,
ButtonComponent,
],
@@ -79,6 +83,26 @@ export class ArchiveComponent {
private userId$: Observable = this.accountService.activeAccount$.pipe(getUserId);
+ private readonly orgMap = toSignal(
+ this.userId$.pipe(
+ switchMap((userId) =>
+ this.organizationService.organizations$(userId).pipe(
+ map((orgs) => {
+ const map = new Map();
+ for (const org of orgs) {
+ map.set(org.id, org);
+ }
+ return map;
+ }),
+ ),
+ ),
+ ),
+ );
+
+ private readonly collections = toSignal(
+ this.userId$.pipe(switchMap((userId) => this.collectionService.decryptedCollections$(userId))),
+ );
+
protected archivedCiphers$ = this.userId$.pipe(
switchMap((userId) => this.cipherArchiveService.archivedCiphers$(userId)),
);
@@ -242,4 +266,22 @@ export class ArchiveComponent {
return this.passwordRepromptService.passwordRepromptCheck(cipher);
}
+
+ /**
+ * Get the organization tier type for the given cipher.
+ */
+ orgTierType({ organizationId }: CipherViewLike) {
+ return this.orgMap()?.get(organizationId as string)?.productTierType;
+ }
+
+ /**
+ * Get the organization icon tooltip for the given cipher.
+ */
+ orgIconTooltip({ collectionIds }: CipherViewLike) {
+ if (collectionIds.length !== 1) {
+ return this.i18nService.t("nCollections", collectionIds.length);
+ }
+
+ return this.collections()?.find((c) => c.id === collectionIds[0])?.name;
+ }
}
diff --git a/apps/desktop/src/locales/en/messages.json b/apps/desktop/src/locales/en/messages.json
index 56eacc94e50..f9947e16692 100644
--- a/apps/desktop/src/locales/en/messages.json
+++ b/apps/desktop/src/locales/en/messages.json
@@ -4397,8 +4397,8 @@
"archiveItem": {
"message": "Archive item"
},
- "archiveItemConfirmDesc": {
- "message": "Archived items are excluded from general search results and autofill suggestions. Are you sure you want to archive this item?"
+ "archiveItemDialogContent": {
+ "message": "Once archived, this item will be excluded from search results and autofill suggestions."
},
"unArchiveAndSave": {
"message": "Unarchive and save"
diff --git a/apps/web/src/app/vault/individual-vault/vault.component.ts b/apps/web/src/app/vault/individual-vault/vault.component.ts
index cad2c97557b..527df0b5370 100644
--- a/apps/web/src/app/vault/individual-vault/vault.component.ts
+++ b/apps/web/src/app/vault/individual-vault/vault.component.ts
@@ -746,7 +746,8 @@ export class VaultComponent implements OnInit, OnDestr
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "archiveItem" },
- content: { key: "archiveItemConfirmDesc" },
+ content: { key: "archiveItemDialogContent" },
+ acceptButtonText: { key: "archiveVerb" },
type: "info",
});
diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json
index ecad9f8a624..b438920a99f 100644
--- a/apps/web/src/locales/en/messages.json
+++ b/apps/web/src/locales/en/messages.json
@@ -11701,8 +11701,8 @@
"message": "Archive item",
"description": "Verb"
},
- "archiveItemConfirmDesc": {
- "message": "Archived items are excluded from general search results and autofill suggestions. Are you sure you want to archive this item?"
+ "archiveItemDialogContent": {
+ "message": "Once archived, this item will be excluded from search results and autofill suggestions."
},
"archiveBulkItems": {
"message": "Archive items",
diff --git a/libs/vault/src/services/archive-cipher-utilities.service.ts b/libs/vault/src/services/archive-cipher-utilities.service.ts
index 5d3c5c33236..93e752b57dd 100644
--- a/libs/vault/src/services/archive-cipher-utilities.service.ts
+++ b/libs/vault/src/services/archive-cipher-utilities.service.ts
@@ -41,7 +41,8 @@ export class ArchiveCipherUtilitiesService {
const confirmed = await this.dialogService.openSimpleDialog({
title: { key: "archiveItem" },
- content: { key: "archiveItemConfirmDesc" },
+ content: { key: "archiveItemDialogContent" },
+ acceptButtonText: { key: "archiveVerb" },
type: "info",
});