From d206832cd3c91ce2366e55a60ff9255f4fc51f3f Mon Sep 17 00:00:00 2001 From: jaasen-livefront Date: Wed, 5 Nov 2025 15:41:21 -0800 Subject: [PATCH] add persistent callout in settings for non-premium users --- apps/browser/src/_locales/en/messages.json | 3 ++ .../popup/settings/settings-v2.component.html | 15 +++++++++ .../popup/settings/settings-v2.component.ts | 30 ++++++++++++++--- ...more-from-bitwarden-page-v2.component.html | 6 ---- .../spotlight/spotlight.component.html | 16 ++++----- .../spotlight/spotlight.component.ts | 33 +++++-------------- 6 files changed, 61 insertions(+), 42 deletions(-) diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index a8743b0db68..20a9c7c722a 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -4890,6 +4890,9 @@ "premium": { "message": "Premium" }, + "unlockFeaturesWithPremium": { + "message": "Unlock reporting, emergency access, and more security features with Premium." + }, "freeOrgsCannotUseAttachments": { "message": "Free organizations cannot use attachments" }, diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.html b/apps/browser/src/tools/popup/settings/settings-v2.component.html index a12c5fe005f..1bc81bcf06f 100644 --- a/apps/browser/src/tools/popup/settings/settings-v2.component.html +++ b/apps/browser/src/tools/popup/settings/settings-v2.component.html @@ -1,4 +1,19 @@ + + {{ "unlockFeaturesWithPremium" | i18n }} + + diff --git a/apps/browser/src/tools/popup/settings/settings-v2.component.ts b/apps/browser/src/tools/popup/settings/settings-v2.component.ts index 1c370381f54..4139ff687ac 100644 --- a/apps/browser/src/tools/popup/settings/settings-v2.component.ts +++ b/apps/browser/src/tools/popup/settings/settings-v2.component.ts @@ -1,5 +1,5 @@ import { CommonModule } from "@angular/common"; -import { Component, OnInit } from "@angular/core"; +import { ChangeDetectionStrategy, Component, OnInit } from "@angular/core"; import { RouterModule } from "@angular/router"; import { combineLatest, @@ -11,11 +11,20 @@ import { switchMap, } from "rxjs"; +import { PremiumUpgradeDialogComponent } from "@bitwarden/angular/billing/components"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { NudgesService, NudgeType } from "@bitwarden/angular/vault"; +import { SpotlightComponent } from "@bitwarden/angular/vault/components/spotlight/spotlight.component"; import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service"; +import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions"; import { UserId } from "@bitwarden/common/types/guid"; -import { BadgeComponent, ItemModule } from "@bitwarden/components"; +import { + BadgeComponent, + DialogService, + ItemModule, + LinkModule, + TypographyModule, +} from "@bitwarden/components"; import { CurrentAccountComponent } from "../../../auth/popup/account-switching/current-account.component"; import { AutofillBrowserSettingsService } from "../../../autofill/services/autofill-browser-settings.service"; @@ -24,8 +33,6 @@ import { PopOutComponent } from "../../../platform/popup/components/pop-out.comp import { PopupHeaderComponent } from "../../../platform/popup/layout/popup-header.component"; import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.component"; -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ templateUrl: "settings-v2.component.html", imports: [ @@ -38,7 +45,11 @@ import { PopupPageComponent } from "../../../platform/popup/layout/popup-page.co ItemModule, CurrentAccountComponent, BadgeComponent, + SpotlightComponent, + TypographyModule, + LinkModule, ], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class SettingsV2Component implements OnInit { NudgeType = NudgeType; @@ -50,6 +61,11 @@ export class SettingsV2Component implements OnInit { shareReplay({ bufferSize: 1, refCount: true }), ); + protected hasPremium$ = this.authenticatedAccount$.pipe( + switchMap((account) => this.accountProfileStateService.hasPremiumFromAnySource$(account.id)), + shareReplay({ bufferSize: 1, refCount: true }), + ); + showDownloadBitwardenNudge$: Observable = this.authenticatedAccount$.pipe( switchMap((account) => this.nudgesService.showNudgeBadge$(NudgeType.DownloadBitwarden, account.id), @@ -79,8 +95,14 @@ export class SettingsV2Component implements OnInit { private readonly nudgesService: NudgesService, private readonly accountService: AccountService, private readonly autofillBrowserSettingsService: AutofillBrowserSettingsService, + private readonly accountProfileStateService: BillingAccountProfileStateService, + private readonly dialogService: DialogService, ) {} + openUpgradeDialog() { + PremiumUpgradeDialogComponent.open(this.dialogService); + } + async ngOnInit() { this.isBrowserAutofillSettingOverridden = await this.autofillBrowserSettingsService.isBrowserAutofillSettingOverridden( diff --git a/apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.html b/apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.html index a2d01ce752e..a8ed75b5de6 100644 --- a/apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.html +++ b/apps/browser/src/vault/popup/settings/more-from-bitwarden-page-v2.component.html @@ -6,12 +6,6 @@ - - - {{ "premiumMembership" | i18n }} - - -
-

{{ title }}

+

{{ title() }}

- +
diff --git a/libs/angular/src/vault/components/spotlight/spotlight.component.ts b/libs/angular/src/vault/components/spotlight/spotlight.component.ts index a912e4ce11b..dc4a94834a5 100644 --- a/libs/angular/src/vault/components/spotlight/spotlight.component.ts +++ b/libs/angular/src/vault/components/spotlight/spotlight.component.ts @@ -1,43 +1,28 @@ import { CommonModule } from "@angular/common"; -import { Component, EventEmitter, Input, Output } from "@angular/core"; +import { ChangeDetectionStrategy, Component, input, output } from "@angular/core"; import { ButtonModule, IconButtonModule, TypographyModule } from "@bitwarden/components"; import { I18nPipe } from "@bitwarden/ui-common"; -// FIXME(https://bitwarden.atlassian.net/browse/CL-764): Migrate to OnPush -// eslint-disable-next-line @angular-eslint/prefer-on-push-component-change-detection @Component({ selector: "bit-spotlight", templateUrl: "spotlight.component.html", imports: [ButtonModule, CommonModule, IconButtonModule, I18nPipe, TypographyModule], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class SpotlightComponent { // The title of the component - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - @Input({ required: true }) title: string | null = null; + readonly title = input(null); // The subtitle of the component - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - @Input() subtitle?: string | null = null; + readonly subtitle = input(null); // The text to display on the button - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - @Input() buttonText?: string; + readonly buttonText = input(null); // Wheter the component can be dismissed, if true, the component will not show a close button - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - @Input() persistent = false; + readonly persistent = input(false); // Optional icon to display on the button - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-signals - @Input() buttonIcon: string | null = null; - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref - @Output() onDismiss = new EventEmitter(); - // FIXME(https://bitwarden.atlassian.net/browse/CL-903): Migrate to Signals - // eslint-disable-next-line @angular-eslint/prefer-output-emitter-ref - @Output() onButtonClick = new EventEmitter(); + readonly buttonIcon = input(null); + readonly onDismiss = output(); + readonly onButtonClick = output(); handleButtonClick(event: MouseEvent): void { this.onButtonClick.emit(event);