mirror of
https://github.com/bitwarden/browser
synced 2025-12-06 00:13:28 +00:00
[PM-16428] Option for primary click action to autofill on Vault view (#12557)
* add option for primary click action to autofill * setting option string * autofill setting for click items to autofill * fix showQuickCopyActions * apply setting
This commit is contained in:
@@ -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."
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
/>
|
||||
<bit-label for="showCardsSuggestions">{{ "showCardsInVaultView" | i18n }}</bit-label>
|
||||
</bit-form-control>
|
||||
<bit-form-control disableMargin>
|
||||
<bit-form-control>
|
||||
<input
|
||||
bitCheckbox
|
||||
id="showIdentitiesSuggestions"
|
||||
@@ -132,6 +132,18 @@
|
||||
{{ "showIdentitiesInVaultView" | i18n }}
|
||||
</bit-label>
|
||||
</bit-form-control>
|
||||
<bit-form-control disableMargin>
|
||||
<input
|
||||
bitCheckbox
|
||||
id="clickToAutofill"
|
||||
type="checkbox"
|
||||
(change)="updateClickItemsVaultView()"
|
||||
[(ngModel)]="clickItemsVaultView"
|
||||
/>
|
||||
<bit-label for="clickToAutofill" class="tw-whitespace-normal">
|
||||
{{ "clickToAutofillOnVault" | i18n }}
|
||||
</bit-label>
|
||||
</bit-form-control>
|
||||
</bit-card>
|
||||
</bit-section>
|
||||
<bit-section>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,4 +6,5 @@
|
||||
(onRefresh)="refreshCurrentTab()"
|
||||
[description]="(showEmptyAutofillTip$ | async) ? ('autofillSuggestionsTip' | i18n) : null"
|
||||
showAutofillButton
|
||||
[primaryActionAutofill]="clickItemsToAutofillVaultView"
|
||||
></app-vault-list-items-container>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -18,6 +18,11 @@
|
||||
</button>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="showViewOption">
|
||||
<button type="button" bitMenuItem (click)="onView()">
|
||||
{{ "view" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<button type="button" bitMenuItem (click)="toggleFavorite()">
|
||||
{{ favoriteText | i18n }}
|
||||
</button>
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -27,9 +27,11 @@
|
||||
<button
|
||||
bit-item-content
|
||||
type="button"
|
||||
(click)="onViewCipher(cipher)"
|
||||
(click)="primaryActionAutofill ? doAutofill(cipher) : onViewCipher(cipher)"
|
||||
(dblclick)="launchCipher(cipher)"
|
||||
[appA11yTitle]="'viewItemTitle' | i18n: cipher.name"
|
||||
[appA11yTitle]="
|
||||
(primaryActionAutofill ? 'autofillTitle' : 'viewItemTitle') | i18n: cipher.name
|
||||
"
|
||||
class="{{ itemHeightClass }}"
|
||||
>
|
||||
<app-vault-icon slot="start" [cipher]="cipher"></app-vault-icon>
|
||||
@@ -49,7 +51,7 @@
|
||||
<span slot="secondary">{{ cipher.subTitle }}</span>
|
||||
</button>
|
||||
<ng-container slot="end">
|
||||
<bit-item-action *ngIf="showAutofillButton">
|
||||
<bit-item-action *ngIf="showAutofillButton && !primaryActionAutofill">
|
||||
<button
|
||||
type="button"
|
||||
bitBadge
|
||||
@@ -75,6 +77,7 @@
|
||||
<app-item-more-options
|
||||
[cipher]="cipher"
|
||||
[hideAutofillOptions]="showAutofillButton"
|
||||
[showViewOption]="primaryActionAutofill"
|
||||
></app-item-more-options>
|
||||
</ng-container>
|
||||
</bit-item>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -19,6 +19,12 @@ export abstract class VaultSettingsService {
|
||||
*/
|
||||
showIdentitiesCurrentTab$: Observable<boolean>;
|
||||
/**
|
||||
/**
|
||||
* An observable monitoring the state of the click items on the Vault view
|
||||
* for Autofill suggestions.
|
||||
*/
|
||||
clickItemsToAutofillVaultView$: Observable<boolean>;
|
||||
/**
|
||||
|
||||
/**
|
||||
* 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<void>;
|
||||
/**
|
||||
* 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<void>;
|
||||
}
|
||||
|
||||
@@ -25,3 +25,12 @@ export const SHOW_IDENTITIES_CURRENT_TAB = new UserKeyDefinition<boolean>(
|
||||
clearOn: [], // do not clear user settings
|
||||
},
|
||||
);
|
||||
|
||||
export const CLICK_ITEMS_AUTOFILL_VAULT_VIEW = new UserKeyDefinition<boolean>(
|
||||
VAULT_SETTINGS_DISK,
|
||||
"clickItemsToAutofillOnVaultView",
|
||||
{
|
||||
deserializer: (obj) => obj,
|
||||
clearOn: [], // do not clear user settings
|
||||
},
|
||||
);
|
||||
|
||||
@@ -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<boolean> =
|
||||
this.showIdentitiesCurrentTabState.state$.pipe(map((x) => x ?? true));
|
||||
|
||||
private clickItemsToAutofillVaultViewState: ActiveUserState<boolean> =
|
||||
this.stateProvider.getActive(CLICK_ITEMS_AUTOFILL_VAULT_VIEW);
|
||||
/**
|
||||
* {@link VaultSettingsServiceAbstraction.clickItemsToAutofillVaultView$$}
|
||||
*/
|
||||
readonly clickItemsToAutofillVaultView$: Observable<boolean> =
|
||||
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<void> {
|
||||
await this.clickItemsToAutofillVaultViewState.update(() => value);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link VaultSettingsServiceAbstraction.setEnablePasskeys}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user