From 0bc7813b1c0da2a9879f08d1ae328cd77768db6f Mon Sep 17 00:00:00 2001 From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com> Date: Fri, 21 Feb 2025 08:57:06 -0800 Subject: [PATCH] [PM-18132] - Update the Appearance settings page to include click to fill setting (#13460) * Update the Appearance settings page to include click to fill setting * fix tests * fix tests * add tests * new customization options callout * use classes instead of inline styling * revert changes to index and tw-theme * remove shared module * Revert "remove shared module" This reverts commit 0b68aaae232bd4c7c3cd19a2f88038ef0fce118d. * Revert "revert changes to index and tw-theme" This reverts commit 4a05f0ca203b15bcf9edb49f564e5d4b75a337f3. * Revert "use classes instead of inline styling" This reverts commit 0e441c4284bef133aa4428b636acf70b651bd4a5. * Revert "new customization options callout" This reverts commit f3054c9b2767436708cd890fa77e3309fda94871. * remove unused code * disable margin on autofill suggestion --- apps/browser/src/_locales/en/messages.json | 6 +++ .../popup/settings/autofill.component.html | 14 +----- .../popup/settings/autofill.component.ts | 9 ---- .../settings/appearance-v2.component.html | 27 +++++++----- .../settings/appearance-v2.component.spec.ts | 44 ++++++++++++++++++- .../popup/settings/appearance-v2.component.ts | 17 +++++++ 6 files changed, 83 insertions(+), 34 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index a3ac0cda882..1d3edd1a5a9 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -1029,6 +1029,9 @@ "clickToAutofillOnVault": { "message": "Click items to autofill on Vault view" }, + "clickToAutofill": { + "message": "Click items in autofill suggestion to fill" + }, "clearClipboard": { "message": "Clear clipboard", "description": "Clipboard is the operating system thing where you copy/paste data to on your device." @@ -2085,6 +2088,9 @@ "message": "to create a strong unique password", "description": "This will be used as part of a larger sentence, broken up to include the generator icon. The full sentence will read 'Use the generator [GENERATOR_ICON] to create a strong unique password'" }, + "vaultCustomization": { + "message": "Vault customization" + }, "vaultTimeoutAction": { "message": "Vault timeout action" }, diff --git a/apps/browser/src/autofill/popup/settings/autofill.component.html b/apps/browser/src/autofill/popup/settings/autofill.component.html index e8299f01166..340197f6bf3 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 @@ /> {{ "showCardsInVaultViewV2" | 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 884503fa360..f0b73838ba4 100644 --- a/apps/browser/src/autofill/popup/settings/autofill.component.ts +++ b/apps/browser/src/autofill/popup/settings/autofill.component.ts @@ -109,7 +109,6 @@ export class AutofillComponent implements OnInit { uriMatchOptions: { name: string; value: UriMatchStrategySetting }[]; showCardsCurrentTab: boolean = true; showIdentitiesCurrentTab: boolean = true; - clickItemsVaultView: boolean = false; autofillKeyboardHelperText: string; accountSwitcherEnabled: boolean = false; @@ -211,10 +210,6 @@ export class AutofillComponent implements OnInit { this.showIdentitiesCurrentTab = await firstValueFrom( this.vaultSettingsService.showIdentitiesCurrentTab$, ); - - this.clickItemsVaultView = await firstValueFrom( - this.vaultSettingsService.clickItemsToAutofillVaultView$, - ); } async updateInlineMenuVisibility() { @@ -421,8 +416,4 @@ 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/settings/appearance-v2.component.html b/apps/browser/src/vault/popup/settings/appearance-v2.component.html index 3a05d239592..4f7f2757e0e 100644 --- a/apps/browser/src/vault/popup/settings/appearance-v2.component.html +++ b/apps/browser/src/vault/popup/settings/appearance-v2.component.html @@ -31,25 +31,32 @@ > - - - {{ "showQuickCopyActions" | i18n }} - - {{ "showNumberOfAutofillSuggestions" | i18n }} - - - {{ "enableFavicon" | i18n }} - - {{ "showAnimations" | i18n }} +

{{ "vaultCustomization" | i18n }}

+ + + + {{ "enableFavicon" | i18n }} + + + + {{ "showQuickCopyActions" | i18n }} + + + + + {{ "clickToAutofill" | i18n }} + + + diff --git a/apps/browser/src/vault/popup/settings/appearance-v2.component.spec.ts b/apps/browser/src/vault/popup/settings/appearance-v2.component.spec.ts index bca83a2fba0..7d67a9458b2 100644 --- a/apps/browser/src/vault/popup/settings/appearance-v2.component.spec.ts +++ b/apps/browser/src/vault/popup/settings/appearance-v2.component.spec.ts @@ -12,6 +12,7 @@ import { MessagingService } from "@bitwarden/common/platform/abstractions/messag import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; +import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; import { PopupCompactModeService } from "../../../platform/popup/layout/popup-compact-mode.service"; import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; @@ -36,7 +37,9 @@ class MockPopupHeaderComponent { selector: "popup-page", template: ``, }) -class MockPopupPageComponent {} +class MockPopupPageComponent { + @Input() loading: boolean; +} describe("AppearanceV2Component", () => { let component: AppearanceV2Component; @@ -48,12 +51,14 @@ describe("AppearanceV2Component", () => { const enableRoutingAnimation$ = new BehaviorSubject(true); const enableCompactMode$ = new BehaviorSubject(false); const showQuickCopyActions$ = new BehaviorSubject(false); + const clickItemsToAutofillVaultView$ = new BehaviorSubject(false); const setSelectedTheme = jest.fn().mockResolvedValue(undefined); const setShowFavicons = jest.fn().mockResolvedValue(undefined); const setEnableBadgeCounter = jest.fn().mockResolvedValue(undefined); const setEnableRoutingAnimation = jest.fn().mockResolvedValue(undefined); const setEnableCompactMode = jest.fn().mockResolvedValue(undefined); const setShowQuickCopyActions = jest.fn().mockResolvedValue(undefined); + const setClickItemsToAutofillVaultView = jest.fn().mockResolvedValue(undefined); const mockWidthService: Partial = { width$: new BehaviorSubject("default"), @@ -98,6 +103,13 @@ describe("AppearanceV2Component", () => { provide: PopupSizeService, useValue: mockWidthService, }, + { + provide: VaultSettingsService, + useValue: { + clickItemsToAutofillVaultView$, + setClickItemsToAutofillVaultView, + }, + }, ], }) .overrideComponent(AppearanceV2Component, { @@ -115,7 +127,10 @@ describe("AppearanceV2Component", () => { fixture.detectChanges(); }); - it("populates the form with the user's current settings", () => { + it("populates the form with the user's current settings", async () => { + fixture.detectChanges(); + await fixture.whenStable(); + fixture.detectChanges(); expect(component.appearanceForm.value).toEqual({ enableAnimations: true, enableFavicon: true, @@ -124,6 +139,7 @@ describe("AppearanceV2Component", () => { enableCompactMode: false, showQuickCopyActions: false, width: "default", + clickItemsToAutofillVaultView: false, }); }); @@ -151,5 +167,29 @@ describe("AppearanceV2Component", () => { expect(setEnableRoutingAnimation).toHaveBeenCalledWith(false); }); + + it("updates the compact mode setting", () => { + component.appearanceForm.controls.enableCompactMode.setValue(true); + + expect(setEnableCompactMode).toHaveBeenCalledWith(true); + }); + + it("updates the quick copy actions setting", () => { + component.appearanceForm.controls.showQuickCopyActions.setValue(true); + + expect(setShowQuickCopyActions).toHaveBeenCalledWith(true); + }); + + it("updates the width setting", () => { + component.appearanceForm.controls.width.setValue("wide"); + + expect(mockWidthService.setWidth).toHaveBeenCalledWith("wide"); + }); + + it("updates the click items to autofill vault view setting", () => { + component.appearanceForm.controls.clickItemsToAutofillVaultView.setValue(true); + + expect(setClickItemsToAutofillVaultView).toHaveBeenCalledWith(true); + }); }); }); diff --git a/apps/browser/src/vault/popup/settings/appearance-v2.component.ts b/apps/browser/src/vault/popup/settings/appearance-v2.component.ts index deddbd444fc..d6fca96c08c 100644 --- a/apps/browser/src/vault/popup/settings/appearance-v2.component.ts +++ b/apps/browser/src/vault/popup/settings/appearance-v2.component.ts @@ -14,6 +14,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service"; import { ThemeType } from "@bitwarden/common/platform/enums"; import { ThemeStateService } from "@bitwarden/common/platform/theming/theme-state.service"; +import { VaultSettingsService } from "@bitwarden/common/vault/abstractions/vault-settings/vault-settings.service"; import { BadgeModule, CardComponent, @@ -64,6 +65,7 @@ export class AppearanceV2Component implements OnInit { enableCompactMode: false, showQuickCopyActions: false, width: "default" as PopupWidthOption, + clickItemsToAutofillVaultView: false, }); /** To avoid flashes of inaccurate values, only show the form after the entire form is populated. */ @@ -88,6 +90,7 @@ export class AppearanceV2Component implements OnInit { private destroyRef: DestroyRef, private animationControlService: AnimationControlService, i18nService: I18nService, + private vaultSettingsService: VaultSettingsService, ) { this.themeOptions = [ { name: i18nService.t("systemDefault"), value: ThemeType.System }, @@ -108,6 +111,9 @@ export class AppearanceV2Component implements OnInit { this.copyButtonsService.showQuickCopyActions$, ); const width = await firstValueFrom(this.popupSizeService.width$); + const clickItemsToAutofillVaultView = await firstValueFrom( + this.vaultSettingsService.clickItemsToAutofillVaultView$, + ); // Set initial values for the form this.appearanceForm.setValue({ @@ -118,6 +124,7 @@ export class AppearanceV2Component implements OnInit { enableCompactMode, showQuickCopyActions, width, + clickItemsToAutofillVaultView, }); this.formLoading = false; @@ -163,6 +170,16 @@ export class AppearanceV2Component implements OnInit { .subscribe((width) => { void this.updateWidth(width); }); + + this.appearanceForm.controls.clickItemsToAutofillVaultView.valueChanges + .pipe(takeUntilDestroyed(this.destroyRef)) + .subscribe((clickItemsToAutofillVaultView) => { + void this.updateClickItemsToAutofillVaultView(clickItemsToAutofillVaultView); + }); + } + + async updateClickItemsToAutofillVaultView(clickItemsToAutofillVaultView: boolean) { + await this.vaultSettingsService.setClickItemsToAutofillVaultView(clickItemsToAutofillVaultView); } async updateFavicon(enableFavicon: boolean) {