[PM-12252] Autofill name of new ciphers (#11127)
* autofill name for new ciphers * only include name and uri when the extension is not popped out * only populate name and uri for login ciphers * source the URL directly from the new item dropdown component * fix new item dropdown tests
This commit is contained in:
parent
69bf91a15e
commit
17c9b26336
|
@ -7,6 +7,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
|||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { ButtonModule, DialogService, MenuModule } from "@bitwarden/components";
|
||||
|
||||
import { BrowserApi } from "../../../../../platform/browser/browser-api";
|
||||
import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils";
|
||||
import { AddEditQueryParams } from "../add-edit/add-edit-v2.component";
|
||||
import { AddEditFolderDialogComponent } from "../add-edit-folder-dialog/add-edit-folder-dialog.component";
|
||||
|
||||
|
@ -18,6 +20,10 @@ describe("NewItemDropdownV2Component", () => {
|
|||
const open = jest.fn();
|
||||
const navigate = jest.fn();
|
||||
|
||||
jest
|
||||
.spyOn(BrowserApi, "getTabFromCurrentWindow")
|
||||
.mockResolvedValue({ url: "https://example.com" } as chrome.tabs.Tab);
|
||||
|
||||
beforeEach(async () => {
|
||||
open.mockClear();
|
||||
navigate.mockClear();
|
||||
|
@ -54,46 +60,74 @@ describe("NewItemDropdownV2Component", () => {
|
|||
jest.spyOn(component, "newItemNavigate");
|
||||
});
|
||||
|
||||
it("navigates to new login", () => {
|
||||
component.newItemNavigate(CipherType.Login);
|
||||
it("navigates to new login", async () => {
|
||||
await component.newItemNavigate(CipherType.Login);
|
||||
|
||||
expect(navigate).toHaveBeenCalledWith(["/add-cipher"], {
|
||||
queryParams: { type: CipherType.Login.toString(), ...emptyParams },
|
||||
queryParams: {
|
||||
type: CipherType.Login.toString(),
|
||||
name: "example.com",
|
||||
uri: "https://example.com",
|
||||
...emptyParams,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("navigates to new card", () => {
|
||||
component.newItemNavigate(CipherType.Card);
|
||||
it("navigates to new card", async () => {
|
||||
await component.newItemNavigate(CipherType.Card);
|
||||
|
||||
expect(navigate).toHaveBeenCalledWith(["/add-cipher"], {
|
||||
queryParams: { type: CipherType.Card.toString(), ...emptyParams },
|
||||
});
|
||||
});
|
||||
|
||||
it("navigates to new identity", () => {
|
||||
component.newItemNavigate(CipherType.Identity);
|
||||
it("navigates to new identity", async () => {
|
||||
await component.newItemNavigate(CipherType.Identity);
|
||||
|
||||
expect(navigate).toHaveBeenCalledWith(["/add-cipher"], {
|
||||
queryParams: { type: CipherType.Identity.toString(), ...emptyParams },
|
||||
});
|
||||
});
|
||||
|
||||
it("navigates to new note", () => {
|
||||
component.newItemNavigate(CipherType.SecureNote);
|
||||
it("navigates to new note", async () => {
|
||||
await component.newItemNavigate(CipherType.SecureNote);
|
||||
|
||||
expect(navigate).toHaveBeenCalledWith(["/add-cipher"], {
|
||||
queryParams: { type: CipherType.SecureNote.toString(), ...emptyParams },
|
||||
});
|
||||
});
|
||||
|
||||
it("includes initial values", () => {
|
||||
it("includes initial values", async () => {
|
||||
component.initialValues = {
|
||||
folderId: "222-333-444",
|
||||
organizationId: "444-555-666",
|
||||
collectionId: "777-888-999",
|
||||
} as NewItemInitialValues;
|
||||
|
||||
component.newItemNavigate(CipherType.Login);
|
||||
await component.newItemNavigate(CipherType.Login);
|
||||
|
||||
expect(navigate).toHaveBeenCalledWith(["/add-cipher"], {
|
||||
queryParams: {
|
||||
type: CipherType.Login.toString(),
|
||||
folderId: "222-333-444",
|
||||
organizationId: "444-555-666",
|
||||
collectionId: "777-888-999",
|
||||
uri: "https://example.com",
|
||||
name: "example.com",
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("does not include name or uri when the extension is popped out", async () => {
|
||||
jest.spyOn(BrowserPopupUtils, "inPopout").mockReturnValue(true);
|
||||
|
||||
component.initialValues = {
|
||||
folderId: "222-333-444",
|
||||
organizationId: "444-555-666",
|
||||
collectionId: "777-888-999",
|
||||
} as NewItemInitialValues;
|
||||
|
||||
await component.newItemNavigate(CipherType.Login);
|
||||
|
||||
expect(navigate).toHaveBeenCalledWith(["/add-cipher"], {
|
||||
queryParams: {
|
||||
|
|
|
@ -3,10 +3,13 @@ import { Component, Input } from "@angular/core";
|
|||
import { Router, RouterLink } from "@angular/router";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||
import { CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
|
||||
import { CipherType } from "@bitwarden/common/vault/enums";
|
||||
import { ButtonModule, DialogService, MenuModule, NoItemsModule } from "@bitwarden/components";
|
||||
|
||||
import { BrowserApi } from "../../../../../platform/browser/browser-api";
|
||||
import BrowserPopupUtils from "../../../../../platform/popup/browser-popup-utils";
|
||||
import { AddEditQueryParams } from "../add-edit/add-edit-v2.component";
|
||||
import { AddEditFolderDialogComponent } from "../add-edit-folder-dialog/add-edit-folder-dialog.component";
|
||||
|
||||
|
@ -14,7 +17,6 @@ export interface NewItemInitialValues {
|
|||
folderId?: string;
|
||||
organizationId?: OrganizationId;
|
||||
collectionId?: CollectionId;
|
||||
uri?: string;
|
||||
}
|
||||
|
||||
@Component({
|
||||
|
@ -37,18 +39,30 @@ export class NewItemDropdownV2Component {
|
|||
private dialogService: DialogService,
|
||||
) {}
|
||||
|
||||
private buildQueryParams(type: CipherType): AddEditQueryParams {
|
||||
private async buildQueryParams(type: CipherType): Promise<AddEditQueryParams> {
|
||||
const tab = await BrowserApi.getTabFromCurrentWindow();
|
||||
const poppedOut = BrowserPopupUtils.inPopout(window);
|
||||
|
||||
const loginDetails: { uri?: string; name?: string } = {};
|
||||
|
||||
// When a Login Cipher is created and the extension is not popped out,
|
||||
// pass along the uri and name
|
||||
if (!poppedOut && type === CipherType.Login && tab) {
|
||||
loginDetails.uri = tab.url;
|
||||
loginDetails.name = Utils.getHostname(tab.url);
|
||||
}
|
||||
|
||||
return {
|
||||
type: type.toString(),
|
||||
collectionId: this.initialValues?.collectionId,
|
||||
organizationId: this.initialValues?.organizationId,
|
||||
folderId: this.initialValues?.folderId,
|
||||
uri: this.initialValues?.uri,
|
||||
...loginDetails,
|
||||
};
|
||||
}
|
||||
|
||||
newItemNavigate(type: CipherType) {
|
||||
void this.router.navigate(["/add-cipher"], { queryParams: this.buildQueryParams(type) });
|
||||
async newItemNavigate(type: CipherType) {
|
||||
await this.router.navigate(["/add-cipher"], { queryParams: await this.buildQueryParams(type) });
|
||||
}
|
||||
|
||||
openFolderDialog() {
|
||||
|
|
|
@ -12,7 +12,6 @@ import { ButtonModule, Icons, NoItemsModule } from "@bitwarden/components";
|
|||
import { VaultIcons } from "@bitwarden/vault";
|
||||
|
||||
import { CurrentAccountComponent } from "../../../../auth/popup/account-switching/current-account.component";
|
||||
import { BrowserApi } from "../../../../platform/browser/browser-api";
|
||||
import { PopOutComponent } from "../../../../platform/popup/components/pop-out.component";
|
||||
import { PopupHeaderComponent } from "../../../../platform/popup/layout/popup-header.component";
|
||||
import { PopupPageComponent } from "../../../../platform/popup/layout/popup-page.component";
|
||||
|
@ -72,7 +71,6 @@ export class VaultV2Component implements OnInit, OnDestroy {
|
|||
filter.collection?.organizationId) as OrganizationId,
|
||||
collectionId: filter.collection?.id as CollectionId,
|
||||
folderId: filter.folder?.id,
|
||||
uri: (await BrowserApi.getTabFromCurrentWindow())?.url,
|
||||
}) as NewItemInitialValues,
|
||||
),
|
||||
shareReplay({ refCount: true, bufferSize: 1 }),
|
||||
|
|
Loading…
Reference in New Issue