diff --git a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html
index c68df5bbfa..40a8954b05 100644
--- a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html
+++ b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.html
@@ -27,7 +27,7 @@
[label]="userEmail$ | async"
>
diff --git a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.spec.ts b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.spec.ts
index 3995422944..aa68770774 100644
--- a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.spec.ts
+++ b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.spec.ts
@@ -59,6 +59,9 @@ describe("ItemDetailsSectionComponent", () => {
initializedWithCachedCipher,
});
i18nService = mock();
+ i18nService.collator = {
+ compare: (a: string, b: string) => a.localeCompare(b),
+ } as Intl.Collator;
await TestBed.configureTestingModule({
imports: [ItemDetailsSectionComponent, CommonModule, ReactiveFormsModule],
@@ -184,16 +187,18 @@ describe("ItemDetailsSectionComponent", () => {
it("should allow ownership change if personal ownership is allowed and there is at least one organization", () => {
component.config.allowPersonalOwnership = true;
- component.config.organizations = [{ id: "org1" } as Organization];
+ component.config.organizations = [{ id: "org1", name: "org1" } as Organization];
+ fixture.detectChanges();
expect(component.allowOwnershipChange).toBe(true);
});
it("should allow ownership change if personal ownership is not allowed but there is more than one organization", () => {
component.config.allowPersonalOwnership = false;
component.config.organizations = [
- { id: "org1" } as Organization,
- { id: "org2" } as Organization,
+ { id: "org1", name: "org1" } as Organization,
+ { id: "org2", name: "org2" } as Organization,
];
+ fixture.detectChanges();
expect(component.allowOwnershipChange).toBe(true);
});
});
@@ -206,7 +211,8 @@ describe("ItemDetailsSectionComponent", () => {
it("should return the first organization id if personal ownership is not allowed", () => {
component.config.allowPersonalOwnership = false;
- component.config.organizations = [{ id: "org1" } as Organization];
+ component.config.organizations = [{ id: "org1", name: "Organization 1" } as Organization];
+ fixture.detectChanges();
expect(component.defaultOwner).toBe("org1");
});
});
@@ -250,6 +256,7 @@ describe("ItemDetailsSectionComponent", () => {
jest.spyOn(component, "allowOwnershipChange", "get").mockReturnValue(false);
component.config.mode = "edit";
component.config.organizations = [{ id: "org1" } as Organization];
+ fixture.detectChanges();
expect(component.showOwnership).toBe(true);
});
@@ -322,8 +329,8 @@ describe("ItemDetailsSectionComponent", () => {
it("should select the first organization if personal ownership is not allowed", async () => {
component.config.allowPersonalOwnership = false;
component.config.organizations = [
- { id: "org1" } as Organization,
- { id: "org2" } as Organization,
+ { id: "org1", name: "org1" } as Organization,
+ { id: "org2", name: "org2" } as Organization,
];
component.originalCipherView = {
name: "cipher1",
@@ -517,4 +524,23 @@ describe("ItemDetailsSectionComponent", () => {
expect(component["readOnlyCollectionsNames"]).toEqual(["Collection 1", "Collection 3"]);
});
});
+
+ describe("organizationOptions", () => {
+ it("should sort the organizations by name", async () => {
+ component.config.mode = "edit";
+ component.config.organizations = [
+ { id: "org2", name: "org2" } as Organization,
+ { id: "org1", name: "org1" } as Organization,
+ ];
+ component.originalCipherView = {} as CipherView;
+
+ await component.ngOnInit();
+ fixture.detectChanges();
+
+ const select = fixture.debugElement.query(By.directive(SelectComponent));
+ const { label } = select.componentInstance.items[0];
+
+ expect(label).toBe("org1");
+ });
+ });
});
diff --git a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts
index 50bafd48b4..dcbc4e8c92 100644
--- a/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts
+++ b/libs/vault/src/cipher-form/components/item-details/item-details-section.component.ts
@@ -12,6 +12,7 @@ import { OrganizationUserType } from "@bitwarden/common/admin-console/enums";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
+import { Utils } from "@bitwarden/common/platform/misc/utils";
import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import {
@@ -74,6 +75,8 @@ export class ItemDetailsSectionComponent implements OnInit {
/** The email address associated with the active account */
protected userEmail$ = this.accountService.activeAccount$.pipe(map((account) => account.email));
+ protected organizations: Organization[] = [];
+
@Input({ required: true })
config: CipherFormConfig;
@@ -90,10 +93,6 @@ export class ItemDetailsSectionComponent implements OnInit {
return this.config.mode === "partial-edit";
}
- get organizations(): Organization[] {
- return this.config.organizations;
- }
-
get allowPersonalOwnership() {
return this.config.allowPersonalOwnership;
}
@@ -186,6 +185,10 @@ export class ItemDetailsSectionComponent implements OnInit {
}
async ngOnInit() {
+ this.organizations = this.config.organizations.sort(
+ Utils.getSortFunction(this.i18nService, "name"),
+ );
+
if (!this.allowPersonalOwnership && this.organizations.length === 0) {
throw new Error("No organizations available for ownership.");
}