1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 05:13:29 +00:00

[PM-21719] Remove Assign To Collections Modal When No Editable Collections (#15137)

* remove assign to collections option when user does not have editable collections
This commit is contained in:
Jason Ng
2025-06-10 18:03:17 -04:00
committed by GitHub
parent fc03ed662e
commit 3326877a67
4 changed files with 36 additions and 13 deletions

View File

@@ -31,7 +31,11 @@
<a bitMenuItem (click)="clone()" *ngIf="canClone$ | async">
{{ "clone" | i18n }}
</a>
<a bitMenuItem *ngIf="hasOrganizations" (click)="conditionallyNavigateToAssignCollections()">
<a
bitMenuItem
*ngIf="canAssignCollections$ | async"
(click)="conditionallyNavigateToAssignCollections()"
>
{{ "assignToCollections" | i18n }}
</a>
</ng-container>

View File

@@ -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<CipherView>(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<void> {
const userId = await firstValueFrom(getUserId(this.accountService.activeAccount$));
this.hasOrganizations = await firstValueFrom(this.organizationService.hasOrganizations(userId));
}
get canEdit() {
return this.cipher.edit;
}

View File

@@ -788,7 +788,13 @@
<button
type="button"
(click)="share()"
*ngIf="editMode && cipher && !cipher.organizationId && !cloneMode"
*ngIf="
editMode &&
cipher &&
!cipher.organizationId &&
!cloneMode &&
writeableCollections.length > 0
"
>
{{ "move" | i18n }}
</button>

View File

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