mirror of
https://github.com/bitwarden/browser.git
synced 2024-12-23 16:38:45 +01:00
[PM-13928]use the user's email address in owner dropdown rather than "You" (#11798)
* use the user's email address in owner dropdown rather than "You" * show ownership value in individual vault when disabled * import account service in storybook
This commit is contained in:
parent
a049b553a6
commit
00e1c936fb
@ -13,6 +13,7 @@ import { CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { EventCollectionService } from "@bitwarden/common/abstractions/event/event-collection.service";
|
||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service";
|
||||
import { DomainSettingsService } from "@bitwarden/common/autofill/services/domain-settings.service";
|
||||
import { ClientType } from "@bitwarden/common/enums";
|
||||
@ -183,6 +184,12 @@ export default {
|
||||
getClientType: () => ClientType.Browser,
|
||||
},
|
||||
},
|
||||
{
|
||||
provide: AccountService,
|
||||
useValue: {
|
||||
activeAccount$: new BehaviorSubject({ email: "test@example.com" }),
|
||||
},
|
||||
},
|
||||
],
|
||||
}),
|
||||
componentWrapperDecorator(
|
||||
|
@ -27,9 +27,9 @@
|
||||
<bit-label>{{ "owner" | i18n }}</bit-label>
|
||||
<bit-select formControlName="organizationId">
|
||||
<bit-option
|
||||
*ngIf="allowPersonalOwnership"
|
||||
*ngIf="showPersonalOwnerOption"
|
||||
[value]="null"
|
||||
[label]="'selfOwnershipLabel' | i18n"
|
||||
[label]="userEmail$ | async"
|
||||
></bit-option>
|
||||
<bit-option
|
||||
*ngFor="let org of config.organizations"
|
||||
|
@ -1,13 +1,17 @@
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { ComponentFixture, fakeAsync, TestBed, tick } from "@angular/core/testing";
|
||||
import { ReactiveFormsModule } from "@angular/forms";
|
||||
import { By } from "@angular/platform-browser";
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { BehaviorSubject } from "rxjs";
|
||||
|
||||
import { CollectionView } from "@bitwarden/admin-console/common";
|
||||
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 { CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { SelectComponent } from "@bitwarden/components";
|
||||
|
||||
import { CipherFormConfig } from "../../abstractions/cipher-form-config.service";
|
||||
import { CipherFormContainer } from "../../cipher-form-container";
|
||||
@ -20,6 +24,8 @@ describe("ItemDetailsSectionComponent", () => {
|
||||
let cipherFormProvider: MockProxy<CipherFormContainer>;
|
||||
let i18nService: MockProxy<I18nService>;
|
||||
|
||||
const activeAccount$ = new BehaviorSubject<{ email: string }>({ email: "test@example.com" });
|
||||
|
||||
beforeEach(async () => {
|
||||
cipherFormProvider = mock<CipherFormContainer>();
|
||||
i18nService = mock<I18nService>();
|
||||
@ -29,6 +35,7 @@ describe("ItemDetailsSectionComponent", () => {
|
||||
providers: [
|
||||
{ provide: CipherFormContainer, useValue: cipherFormProvider },
|
||||
{ provide: I18nService, useValue: i18nService },
|
||||
{ provide: AccountService, useValue: { activeAccount$ } },
|
||||
],
|
||||
}).compileComponents();
|
||||
|
||||
@ -207,6 +214,35 @@ describe("ItemDetailsSectionComponent", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("showPersonalOwnerOption", () => {
|
||||
it("should show personal ownership when the configuration allows", () => {
|
||||
component.config.mode = "edit";
|
||||
component.config.allowPersonalOwnership = true;
|
||||
component.config.organizations = [{ id: "134-433-22" } as Organization];
|
||||
fixture.detectChanges();
|
||||
|
||||
const select = fixture.debugElement.query(By.directive(SelectComponent));
|
||||
const { value, label } = select.componentInstance.items[0];
|
||||
|
||||
expect(value).toBeNull();
|
||||
expect(label).toBe("test@example.com");
|
||||
});
|
||||
|
||||
it("should show personal ownership when the control is disabled", async () => {
|
||||
component.config.mode = "edit";
|
||||
component.config.allowPersonalOwnership = false;
|
||||
component.config.organizations = [{ id: "134-433-22" } as Organization];
|
||||
await component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const select = fixture.debugElement.query(By.directive(SelectComponent));
|
||||
|
||||
const { value, label } = select.componentInstance.items[0];
|
||||
expect(value).toBeNull();
|
||||
expect(label).toBe("test@example.com");
|
||||
});
|
||||
});
|
||||
|
||||
describe("showOwnership", () => {
|
||||
it("should return true if ownership change is allowed or in edit mode with at least one organization", () => {
|
||||
jest.spyOn(component, "allowOwnershipChange", "get").mockReturnValue(true);
|
||||
|
@ -7,6 +7,7 @@ import { concatMap, map } from "rxjs";
|
||||
import { CollectionView } from "@bitwarden/admin-console/common";
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
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 { CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
@ -68,6 +69,9 @@ export class ItemDetailsSectionComponent implements OnInit {
|
||||
|
||||
protected showCollectionsControl: boolean;
|
||||
|
||||
/** The email address associated with the active account */
|
||||
protected userEmail$ = this.accountService.activeAccount$.pipe(map((account) => account.email));
|
||||
|
||||
@Input({ required: true })
|
||||
config: CipherFormConfig;
|
||||
|
||||
@ -96,11 +100,23 @@ export class ItemDetailsSectionComponent implements OnInit {
|
||||
return this.config.initialValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the personal ownership option in the Owner dropdown when:
|
||||
* - Personal ownership is allowed
|
||||
* - The `organizationId` control is disabled. This avoids the scenario
|
||||
* where a the dropdown is empty because the user personally owns the cipher
|
||||
* but cannot edit the ownership.
|
||||
*/
|
||||
get showPersonalOwnerOption() {
|
||||
return this.allowPersonalOwnership || !this.itemDetailsForm.controls.organizationId.enabled;
|
||||
}
|
||||
|
||||
constructor(
|
||||
private cipherFormContainer: CipherFormContainer,
|
||||
private formBuilder: FormBuilder,
|
||||
private i18nService: I18nService,
|
||||
private destroyRef: DestroyRef,
|
||||
private accountService: AccountService,
|
||||
) {
|
||||
this.cipherFormContainer.registerChildForm("itemDetails", this.itemDetailsForm);
|
||||
this.itemDetailsForm.valueChanges
|
||||
|
Loading…
Reference in New Issue
Block a user