diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json
index 8fe283ba289..06f11406b68 100644
--- a/apps/browser/src/_locales/en/messages.json
+++ b/apps/browser/src/_locales/en/messages.json
@@ -1004,6 +1004,9 @@
"showIdentitiesCurrentTabDesc": {
"message": "List identity items on the Tab page for easy autofill."
},
+ "clickToAutofillOnVault": {
+ "message": "Click items to autofill on Vault view"
+ },
"clearClipboard": {
"message": "Clear clipboard",
"description": "Clipboard is the operating system thing where you copy/paste data to on your device."
diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html
index 18c6f515337..e8882cf7bbb 100644
--- a/apps/browser/src/autofill/popup/settings/autofill.component.html
+++ b/apps/browser/src/autofill/popup/settings/autofill.component.html
@@ -120,7 +120,7 @@
/>
{{ "showCardsInVaultView" | i18n }}
-
+
+
+
+
+ {{ "clickToAutofillOnVault" | i18n }}
+
+
diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.ts b/apps/browser/src/autofill/popup/settings/autofill.component.ts
index 828b45e7b37..da997f550b3 100644
--- a/apps/browser/src/autofill/popup/settings/autofill.component.ts
+++ b/apps/browser/src/autofill/popup/settings/autofill.component.ts
@@ -110,6 +110,7 @@ export class AutofillComponent implements OnInit {
uriMatchOptions: { name: string; value: UriMatchStrategySetting }[];
showCardsCurrentTab: boolean = true;
showIdentitiesCurrentTab: boolean = true;
+ clickItemsVaultView: boolean = false;
autofillKeyboardHelperText: string;
accountSwitcherEnabled: boolean = false;
@@ -207,6 +208,10 @@ export class AutofillComponent implements OnInit {
this.showIdentitiesCurrentTab = await firstValueFrom(
this.vaultSettingsService.showIdentitiesCurrentTab$,
);
+
+ this.clickItemsVaultView = await firstValueFrom(
+ this.vaultSettingsService.clickItemsToAutofillVaultView$,
+ );
}
async updateInlineMenuVisibility() {
@@ -413,4 +418,8 @@ export class AutofillComponent implements OnInit {
async updateShowInlineMenuIdentities() {
await this.autofillSettingsService.setShowInlineMenuIdentities(this.showInlineMenuIdentities);
}
+
+ async updateClickItemsVaultView() {
+ await this.vaultSettingsService.setClickItemsToAutofillVaultView(this.clickItemsVaultView);
+ }
}
diff --git a/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.html b/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.html
index 52ae387e8b9..7c4ea3e5b46 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.html
+++ b/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.html
@@ -6,4 +6,5 @@
(onRefresh)="refreshCurrentTab()"
[description]="(showEmptyAutofillTip$ | async) ? ('autofillSuggestionsTip' | i18n) : null"
showAutofillButton
+ [primaryActionAutofill]="clickItemsToAutofillVaultView"
>
diff --git a/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.ts b/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.ts
index 8e72d84053d..deba204bd71 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.ts
+++ b/apps/browser/src/vault/popup/components/vault-v2/autofill-vault-list-items/autofill-vault-list-items.component.ts
@@ -1,8 +1,9 @@
import { CommonModule } from "@angular/common";
-import { Component } from "@angular/core";
-import { combineLatest, map, Observable } from "rxjs";
+import { Component, OnInit } from "@angular/core";
+import { combineLatest, firstValueFrom, map, Observable } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
+import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service";
import { CipherType } from "@bitwarden/common/vault/enums";
import {
IconButtonModule,
@@ -31,7 +32,7 @@ import { VaultListItemsContainerComponent } from "../vault-list-items-container/
selector: "app-autofill-vault-list-items",
templateUrl: "autofill-vault-list-items.component.html",
})
-export class AutofillVaultListItemsComponent {
+export class AutofillVaultListItemsComponent implements OnInit {
/**
* The list of ciphers that can be used to autofill the current page.
* @protected
@@ -45,6 +46,8 @@ export class AutofillVaultListItemsComponent {
*/
protected showRefresh: boolean = BrowserPopupUtils.inSidebar(window);
+ clickItemsToAutofillVaultView = false;
+
/**
* Observable that determines whether the empty autofill tip should be shown.
* The tip is shown when there are no login ciphers to autofill, no filter is applied, and autofill is allowed in
@@ -65,10 +68,17 @@ export class AutofillVaultListItemsComponent {
constructor(
private vaultPopupItemsService: VaultPopupItemsService,
private vaultPopupAutofillService: VaultPopupAutofillService,
+ private vaultSettingsService: VaultSettingsService,
) {
// TODO: Migrate logic to show Autofill policy toast PM-8144
}
+ async ngOnInit() {
+ this.clickItemsToAutofillVaultView = await firstValueFrom(
+ this.vaultSettingsService.clickItemsToAutofillVaultView$,
+ );
+ }
+
/**
* Refreshes the current tab to re-populate the autofill ciphers.
* @protected
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 8b70896e019..7f87f32fcd4 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
@@ -18,6 +18,11 @@
+
+
+
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 9dca0eec7c2..5d3dee9018e 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
@@ -46,6 +46,13 @@ export class ItemMoreOptionsComponent implements OnInit {
return this._cipher$.value;
}
+ /**
+ * Flag to show view item menu option. Used when something else is
+ * assigned as the primary action for the item, such as autofill.
+ */
+ @Input({ transform: booleanAttribute })
+ showViewOption: boolean;
+
/**
* Flag to hide the autofill menu options. Used for items that are
* already in the autofill list suggestion.
@@ -111,6 +118,16 @@ export class ItemMoreOptionsComponent implements OnInit {
await this.vaultPopupAutofillService.doAutofillAndSave(this.cipher, false);
}
+ async onView() {
+ const repromptPassed = await this.passwordRepromptService.passwordRepromptCheck(this.cipher);
+ if (!repromptPassed) {
+ return;
+ }
+ await this.router.navigate(["/view-cipher"], {
+ queryParams: { cipherId: this.cipher.id, type: this.cipher.type },
+ });
+ }
+
/**
* Toggles the favorite status of the cipher and updates it on the server.
*/
diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html
index 067c8dbdf0b..72ac590c779 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html
+++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.html
@@ -27,9 +27,11 @@
-
+
diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts
index b4022560c35..29c9f14e2aa 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts
+++ b/apps/browser/src/vault/popup/components/vault-v2/vault-list-items-container/vault-list-items-container.component.ts
@@ -124,6 +124,12 @@ export class VaultListItemsContainerComponent implements AfterViewInit {
@Input({ transform: booleanAttribute })
showAutofillButton: boolean;
+ /**
+ * Option to perform autofill operation as the primary action for autofill suggestions.
+ */
+ @Input({ transform: booleanAttribute })
+ primaryActionAutofill: boolean;
+
/**
* Remove the bottom margin from the bit-section in this component
* (used for containers at the end of the page where bottom margin is not needed)
diff --git a/libs/common/src/vault/abstractions/vault-settings/vault-settings.service.ts b/libs/common/src/vault/abstractions/vault-settings/vault-settings.service.ts
index 9b3fde47a15..ea1e73c2685 100644
--- a/libs/common/src/vault/abstractions/vault-settings/vault-settings.service.ts
+++ b/libs/common/src/vault/abstractions/vault-settings/vault-settings.service.ts
@@ -19,6 +19,12 @@ export abstract class VaultSettingsService {
*/
showIdentitiesCurrentTab$: Observable;
/**
+ /**
+ * An observable monitoring the state of the click items on the Vault view
+ * for Autofill suggestions.
+ */
+ clickItemsToAutofillVaultView$: Observable;
+ /**
/**
* Saves the enable passkeys setting to disk.
@@ -35,4 +41,10 @@ export abstract class VaultSettingsService {
* @param value The new value for the show identities on tab page setting.
*/
setShowIdentitiesCurrentTab: (value: boolean) => Promise;
+ /**
+ * Saves the click items on vault View for Autofill suggestions to disk.
+ * @param value The new value for the click items on vault View for
+ * Autofill suggestions setting.
+ */
+ setClickItemsToAutofillVaultView: (value: boolean) => Promise;
}
diff --git a/libs/common/src/vault/services/key-state/vault-settings.state.ts b/libs/common/src/vault/services/key-state/vault-settings.state.ts
index 21364bbbf8e..35bb776cc96 100644
--- a/libs/common/src/vault/services/key-state/vault-settings.state.ts
+++ b/libs/common/src/vault/services/key-state/vault-settings.state.ts
@@ -25,3 +25,12 @@ export const SHOW_IDENTITIES_CURRENT_TAB = new UserKeyDefinition(
clearOn: [], // do not clear user settings
},
);
+
+export const CLICK_ITEMS_AUTOFILL_VAULT_VIEW = new UserKeyDefinition(
+ VAULT_SETTINGS_DISK,
+ "clickItemsToAutofillOnVaultView",
+ {
+ deserializer: (obj) => obj,
+ clearOn: [], // do not clear user settings
+ },
+);
diff --git a/libs/common/src/vault/services/vault-settings/vault-settings.service.ts b/libs/common/src/vault/services/vault-settings/vault-settings.service.ts
index 39b96318217..85ab3914158 100644
--- a/libs/common/src/vault/services/vault-settings/vault-settings.service.ts
+++ b/libs/common/src/vault/services/vault-settings/vault-settings.service.ts
@@ -6,6 +6,7 @@ import {
SHOW_CARDS_CURRENT_TAB,
SHOW_IDENTITIES_CURRENT_TAB,
USER_ENABLE_PASSKEYS,
+ CLICK_ITEMS_AUTOFILL_VAULT_VIEW,
} from "../key-state/vault-settings.state";
/**
@@ -39,6 +40,14 @@ export class VaultSettingsService implements VaultSettingsServiceAbstraction {
readonly showIdentitiesCurrentTab$: Observable =
this.showIdentitiesCurrentTabState.state$.pipe(map((x) => x ?? true));
+ private clickItemsToAutofillVaultViewState: ActiveUserState =
+ this.stateProvider.getActive(CLICK_ITEMS_AUTOFILL_VAULT_VIEW);
+ /**
+ * {@link VaultSettingsServiceAbstraction.clickItemsToAutofillVaultView$$}
+ */
+ readonly clickItemsToAutofillVaultView$: Observable =
+ this.clickItemsToAutofillVaultViewState.state$.pipe(map((x) => x ?? false));
+
constructor(private stateProvider: StateProvider) {}
/**
@@ -55,6 +64,13 @@ export class VaultSettingsService implements VaultSettingsServiceAbstraction {
await this.showIdentitiesCurrentTabState.update(() => value);
}
+ /**
+ * {@link VaultSettingsServiceAbstraction.setClickItemsToAutofillVaultView}
+ */
+ async setClickItemsToAutofillVaultView(value: boolean): Promise {
+ await this.clickItemsToAutofillVaultViewState.update(() => value);
+ }
+
/**
* {@link VaultSettingsServiceAbstraction.setEnablePasskeys}
*/