diff --git a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html
index 6e6e30b359b..f9be1617d21 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html
+++ b/apps/browser/src/vault/popup/components/vault-v2/item-more-options/item-more-options.component.html
@@ -31,7 +31,11 @@
{{ "clone" | i18n }}
-
+
{{ "assignToCollections" | i18n }}
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 165dd6d6d30..75bc984e977 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
@@ -1,11 +1,12 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { CommonModule } from "@angular/common";
-import { booleanAttribute, Component, Input, OnInit } from "@angular/core";
+import { booleanAttribute, Component, Input } from "@angular/core";
import { Router, RouterModule } from "@angular/router";
-import { BehaviorSubject, firstValueFrom, map, switchMap } from "rxjs";
+import { BehaviorSubject, combineLatest, firstValueFrom, map, switchMap } from "rxjs";
import { filter } from "rxjs/operators";
+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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
@@ -32,7 +33,7 @@ import { AddEditQueryParams } from "../add-edit/add-edit-v2.component";
templateUrl: "./item-more-options.component.html",
imports: [ItemModule, IconButtonModule, MenuModule, CommonModule, JslibModule, RouterModule],
})
-export class ItemMoreOptionsComponent implements OnInit {
+export class ItemMoreOptionsComponent {
private _cipher$ = new BehaviorSubject(undefined);
@Input({
@@ -71,8 +72,21 @@ export class ItemMoreOptionsComponent implements OnInit {
switchMap((c) => this.cipherAuthorizationService.canCloneCipher$(c)),
);
- /** Boolean dependent on the current user having access to an organization */
- protected hasOrganizations = false;
+ /** Observable Boolean dependent on the current user having access to an organization and editable collections */
+ protected canAssignCollections$ = this.accountService.activeAccount$.pipe(
+ getUserId,
+ switchMap((userId) => {
+ return combineLatest([
+ this.organizationService.hasOrganizations(userId),
+ this.collectionService.decryptedCollections$,
+ ]).pipe(
+ map(([hasOrgs, collections]) => {
+ const canEditCollections = collections.some((c) => !c.readOnly);
+ return hasOrgs && canEditCollections;
+ }),
+ );
+ }),
+ );
constructor(
private cipherService: CipherService,
@@ -85,13 +99,9 @@ export class ItemMoreOptionsComponent implements OnInit {
private accountService: AccountService,
private organizationService: OrganizationService,
private cipherAuthorizationService: CipherAuthorizationService,
+ private collectionService: CollectionService,
) {}
- async ngOnInit(): Promise {
- const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
- this.hasOrganizations = await firstValueFrom(this.organizationService.hasOrganizations(userId));
- }
-
get canEdit() {
return this.cipher.edit;
}
diff --git a/apps/desktop/src/vault/app/vault/add-edit.component.html b/apps/desktop/src/vault/app/vault/add-edit.component.html
index 8457e72bdc1..9c316813d1d 100644
--- a/apps/desktop/src/vault/app/vault/add-edit.component.html
+++ b/apps/desktop/src/vault/app/vault/add-edit.component.html
@@ -788,7 +788,13 @@
diff --git a/apps/web/src/app/vault/components/vault-items/vault-items.component.ts b/apps/web/src/app/vault/components/vault-items/vault-items.component.ts
index 0ca2ea86bf6..9679f0879b9 100644
--- a/apps/web/src/app/vault/components/vault-items/vault-items.component.ts
+++ b/apps/web/src/app/vault/components/vault-items/vault-items.component.ts
@@ -298,8 +298,11 @@ export class VaultItemsComponent {
protected canAssignCollections(cipher: CipherView) {
const organization = this.allOrganizations.find((o) => o.id === cipher.organizationId);
+ const editableCollections = this.allCollections.filter((c) => !c.readOnly);
+
return (
- (organization?.canEditAllCiphers && this.viewingOrgVault) || cipher.canAssignToCollections
+ (organization?.canEditAllCiphers && this.viewingOrgVault) ||
+ (cipher.canAssignToCollections && editableCollections.length > 0)
);
}