Skip to content

Commit

Permalink
[PM-16428] Option for primary click action to autofill on Vault view (#…
Browse files Browse the repository at this point in the history
…12557)

* add option for primary click action to autofill

* setting option string

* autofill setting for click items to autofill

* fix showQuickCopyActions

* apply setting

(cherry picked from commit f434334)
  • Loading branch information
kspearrin authored and Eeebru committed Dec 27, 2024
1 parent 5ce6891 commit 9d9a6ba
Show file tree
Hide file tree
Showing 12 changed files with 110 additions and 7 deletions.
3 changes: 3 additions & 0 deletions apps/browser/src/_locales/en/messages.json
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,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."
Expand Down
14 changes: 13 additions & 1 deletion apps/browser/src/autofill/popup/settings/autofill.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ <h2 bitTypography="h6">{{ "autofillSuggestionsSectionTitle" | i18n }}</h2>
/>
<bit-label for="showCardsSuggestions">{{ "showCardsInVaultView" | i18n }}</bit-label>
</bit-form-control>
<bit-form-control disableMargin>
<bit-form-control>
<input
bitCheckbox
id="showIdentitiesSuggestions"
Expand All @@ -132,6 +132,18 @@ <h2 bitTypography="h6">{{ "autofillSuggestionsSectionTitle" | i18n }}</h2>
{{ "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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,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;

Expand Down Expand Up @@ -205,6 +206,10 @@ export class AutofillComponent implements OnInit {
this.showIdentitiesCurrentTab = await firstValueFrom(
this.vaultSettingsService.showIdentitiesCurrentTab$,
);

this.clickItemsVaultView = await firstValueFrom(
this.vaultSettingsService.clickItemsToAutofillVaultView$,
);
}

async updateInlineMenuVisibility() {
Expand Down Expand Up @@ -411,4 +416,8 @@ export class AutofillComponent implements OnInit {
async updateShowInlineMenuIdentities() {
await this.autofillSettingsService.setShowInlineMenuIdentities(this.showInlineMenuIdentities);
}

async updateClickItemsVaultView() {
await this.vaultSettingsService.setClickItemsToAutofillVaultView(this.clickItemsVaultView);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
(onRefresh)="refreshCurrentTab()"
[description]="(showEmptyAutofillTip$ | async) ? ('autofillSuggestionsTip' | i18n) : null"
showAutofillButton
[primaryActionAutofill]="clickItemsToAutofillVaultView"
></app-vault-list-items-container>
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,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.
Expand Down Expand Up @@ -109,6 +116,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.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ <h2 bitTypography="h6">
<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>
Expand All @@ -49,7 +51,7 @@ <h2 bitTypography="h6">
<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
Expand All @@ -75,6 +77,7 @@ <h2 bitTypography="h6">
<app-item-more-options
[cipher]="cipher"
[hideAutofillOptions]="showAutofillButton"
[showViewOption]="primaryActionAutofill"
></app-item-more-options>
</ng-container>
</bit-item>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,12 @@ export class VaultListItemsContainerComponent {
@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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,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.
Expand All @@ -33,4 +39,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>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -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";

/**
Expand Down Expand Up @@ -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) {}

/**
Expand All @@ -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}
*/
Expand Down

0 comments on commit 9d9a6ba

Please sign in to comment.