mirror of
https://github.com/bitwarden/browser
synced 2025-12-10 13:23:34 +00:00
remove PM8851_BrowserOnboardingNudge feature flag (#15956)
This commit is contained in:
@@ -1,11 +1,9 @@
|
||||
import { Component } from "@angular/core";
|
||||
import { combineLatest, map, Observable, startWith, switchMap } from "rxjs";
|
||||
import { map, Observable, startWith, switchMap } from "rxjs";
|
||||
|
||||
import { NudgesService } from "@bitwarden/angular/vault";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { Icons } from "@bitwarden/components";
|
||||
|
||||
import { NavButton } from "../platform/popup/layout/popup-tab-navigation.component";
|
||||
@@ -19,12 +17,9 @@ export class TabsV2Component {
|
||||
private hasActiveBadges$ = this.accountService.activeAccount$
|
||||
.pipe(getUserId)
|
||||
.pipe(switchMap((userId) => this.nudgesService.hasActiveBadges$(userId)));
|
||||
protected navButtons$: Observable<NavButton[]> = combineLatest([
|
||||
this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge),
|
||||
this.hasActiveBadges$,
|
||||
]).pipe(
|
||||
startWith([false, false]),
|
||||
map(([onboardingFeatureEnabled, hasBadges]) => {
|
||||
protected navButtons$: Observable<NavButton[]> = this.hasActiveBadges$.pipe(
|
||||
startWith(false),
|
||||
map((hasBadges) => {
|
||||
return [
|
||||
{
|
||||
label: "vault",
|
||||
@@ -49,7 +44,7 @@ export class TabsV2Component {
|
||||
page: "/tabs/settings",
|
||||
icon: Icons.SettingsInactive,
|
||||
iconActive: Icons.SettingsActive,
|
||||
showBerry: onboardingFeatureEnabled && hasBadges,
|
||||
showBerry: hasBadges,
|
||||
},
|
||||
];
|
||||
}),
|
||||
@@ -57,6 +52,5 @@ export class TabsV2Component {
|
||||
constructor(
|
||||
private nudgesService: NudgesService,
|
||||
private accountService: AccountService,
|
||||
private readonly configService: ConfigService,
|
||||
) {}
|
||||
}
|
||||
|
||||
@@ -23,12 +23,6 @@
|
||||
<i slot="end" class="bwi bwi-external-link" aria-hidden="true"></i>
|
||||
</button>
|
||||
</bit-item>
|
||||
<bit-item *ngIf="!(isNudgeFeatureEnabled$ | async)">
|
||||
<a bit-item-content routerLink="/more-from-bitwarden">
|
||||
{{ "moreFromBitwarden" | i18n }}
|
||||
<i slot="end" class="bwi bwi-angle-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</bit-item>
|
||||
<bit-item>
|
||||
<button type="button" bit-item-content (click)="rate()">
|
||||
{{ "rateExtension" | i18n }}
|
||||
|
||||
@@ -5,8 +5,6 @@ import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { DeviceType } from "@bitwarden/common/enums";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
|
||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||
import { DialogService, ItemModule } from "@bitwarden/components";
|
||||
@@ -48,17 +46,12 @@ export class AboutPageV2Component {
|
||||
private dialogService: DialogService,
|
||||
private environmentService: EnvironmentService,
|
||||
private platformUtilsService: PlatformUtilsService,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
|
||||
about() {
|
||||
this.dialogService.open(AboutDialogComponent);
|
||||
}
|
||||
|
||||
protected isNudgeFeatureEnabled$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.PM8851_BrowserOnboardingNudge,
|
||||
);
|
||||
|
||||
async launchHelp() {
|
||||
const confirmed = await this.dialogService.openSimpleDialog({
|
||||
title: { key: "continueToHelpCenter" },
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
<i slot="end" class="bwi bwi-angle-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</bit-item>
|
||||
<bit-item *ngIf="isNudgeFeatureEnabled$ | async">
|
||||
<bit-item>
|
||||
<a bit-item-content routerLink="/download-bitwarden">
|
||||
<i slot="start" class="bwi bwi-mobile" aria-hidden="true"></i>
|
||||
<div class="tw-flex tw-items-center tw-justify-center">
|
||||
@@ -92,7 +92,7 @@
|
||||
<i slot="end" class="bwi bwi-angle-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</bit-item>
|
||||
<bit-item *ngIf="isNudgeFeatureEnabled$ | async">
|
||||
<bit-item>
|
||||
<a bit-item-content routerLink="/more-from-bitwarden">
|
||||
<i slot="start" class="bwi bwi-filter" aria-hidden="true"></i>
|
||||
{{ "moreFromBitwarden" | i18n }}
|
||||
|
||||
@@ -14,8 +14,6 @@ import {
|
||||
import { JslibModule } from "@bitwarden/angular/jslib.module";
|
||||
import { NudgesService, NudgeType } from "@bitwarden/angular/vault";
|
||||
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { BadgeComponent, ItemModule } from "@bitwarden/components";
|
||||
|
||||
@@ -75,15 +73,10 @@ export class SettingsV2Component implements OnInit {
|
||||
),
|
||||
);
|
||||
|
||||
protected isNudgeFeatureEnabled$ = this.configService.getFeatureFlag$(
|
||||
FeatureFlag.PM8851_BrowserOnboardingNudge,
|
||||
);
|
||||
|
||||
constructor(
|
||||
private readonly nudgesService: NudgesService,
|
||||
private readonly accountService: AccountService,
|
||||
private readonly autofillBrowserSettingsService: AutofillBrowserSettingsService,
|
||||
private readonly configService: ConfigService,
|
||||
) {}
|
||||
|
||||
async ngOnInit() {
|
||||
|
||||
@@ -1,29 +1,23 @@
|
||||
import { TestBed } from "@angular/core/testing";
|
||||
import { Router } from "@angular/router";
|
||||
import { mock, MockProxy } from "jest-mock-extended";
|
||||
import { of } from "rxjs";
|
||||
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
|
||||
import { IntroCarouselService } from "../services/intro-carousel.service";
|
||||
|
||||
import { IntroCarouselGuard } from "./intro-carousel.guard";
|
||||
|
||||
describe("IntroCarouselGuard", () => {
|
||||
let mockConfigService: MockProxy<ConfigService>;
|
||||
const mockIntroCarouselService = {
|
||||
introCarouselState$: of(true),
|
||||
};
|
||||
const createUrlTree = jest.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
mockConfigService = mock<ConfigService>();
|
||||
createUrlTree.mockClear();
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
providers: [
|
||||
{ provide: Router, useValue: { createUrlTree } },
|
||||
{ provide: ConfigService, useValue: mockConfigService },
|
||||
{
|
||||
provide: IntroCarouselService,
|
||||
useValue: mockIntroCarouselService,
|
||||
@@ -32,22 +26,16 @@ describe("IntroCarouselGuard", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("should return true if the feature flag is off", async () => {
|
||||
mockConfigService.getFeatureFlag.mockResolvedValue(false);
|
||||
const result = await TestBed.runInInjectionContext(async () => await IntroCarouselGuard());
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
it("should navigate to intro-carousel route if feature flag is true and dismissed is true", async () => {
|
||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
||||
it("should return true when dismissed is true", async () => {
|
||||
const result = await TestBed.runInInjectionContext(async () => await IntroCarouselGuard());
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should navigate to intro-carousel route if feature flag is true and dismissed is false", async () => {
|
||||
it("should navigate to intro-carousel route when dismissed is false", async () => {
|
||||
TestBed.overrideProvider(IntroCarouselService, {
|
||||
useValue: { introCarouselState$: of(false) },
|
||||
});
|
||||
mockConfigService.getFeatureFlag.mockResolvedValue(true);
|
||||
|
||||
await TestBed.runInInjectionContext(async () => await IntroCarouselGuard());
|
||||
expect(createUrlTree).toHaveBeenCalledWith(["/intro-carousel"]);
|
||||
});
|
||||
|
||||
@@ -2,23 +2,15 @@ import { inject } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { firstValueFrom } from "rxjs";
|
||||
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
|
||||
import { IntroCarouselService } from "../services/intro-carousel.service";
|
||||
|
||||
export const IntroCarouselGuard = async () => {
|
||||
const router = inject(Router);
|
||||
const configService = inject(ConfigService);
|
||||
const introCarouselService = inject(IntroCarouselService);
|
||||
|
||||
const hasOnboardingNudgesFlag = await configService.getFeatureFlag(
|
||||
FeatureFlag.PM8851_BrowserOnboardingNudge,
|
||||
);
|
||||
|
||||
const hasIntroCarouselDismissed = await firstValueFrom(introCarouselService.introCarouselState$);
|
||||
|
||||
if (!hasOnboardingNudgesFlag || hasIntroCarouselDismissed) {
|
||||
if (hasIntroCarouselDismissed) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { Injectable } from "@angular/core";
|
||||
import { firstValueFrom, map, Observable } from "rxjs";
|
||||
import { map, Observable } from "rxjs";
|
||||
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import {
|
||||
GlobalState,
|
||||
KeyDefinition,
|
||||
@@ -28,17 +26,9 @@ export class IntroCarouselService {
|
||||
map((x) => x ?? false),
|
||||
);
|
||||
|
||||
constructor(
|
||||
private stateProvider: StateProvider,
|
||||
private configService: ConfigService,
|
||||
) {}
|
||||
constructor(private stateProvider: StateProvider) {}
|
||||
|
||||
async setIntroCarouselDismissed(): Promise<void> {
|
||||
const hasVaultNudgeFlag = await firstValueFrom(
|
||||
this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge),
|
||||
);
|
||||
if (hasVaultNudgeFlag) {
|
||||
await this.introCarouselState.update(() => true);
|
||||
}
|
||||
await this.introCarouselState.update(() => true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { PinServiceAbstraction } from "@bitwarden/common/key-management/pin/pin.service.abstraction";
|
||||
import { VaultTimeoutSettingsService } from "@bitwarden/common/key-management/vault-timeout";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
|
||||
import { StateProvider } from "@bitwarden/common/platform/state";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
@@ -31,10 +30,6 @@ describe("Vault Nudges Service", () => {
|
||||
let fakeStateProvider: FakeStateProvider;
|
||||
|
||||
let testBed: TestBed;
|
||||
const mockConfigService = {
|
||||
getFeatureFlag$: jest.fn().mockReturnValue(of(true)),
|
||||
getFeatureFlag: jest.fn().mockReturnValue(true),
|
||||
};
|
||||
|
||||
const nudgeServices = [
|
||||
EmptyVaultNudgeService,
|
||||
@@ -58,7 +53,6 @@ describe("Vault Nudges Service", () => {
|
||||
provide: StateProvider,
|
||||
useValue: fakeStateProvider,
|
||||
},
|
||||
{ provide: ConfigService, useValue: mockConfigService },
|
||||
{
|
||||
provide: HasItemsNudgeService,
|
||||
useValue: mock<HasItemsNudgeService>(),
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { inject, Injectable } from "@angular/core";
|
||||
import { combineLatest, map, Observable, of, shareReplay, switchMap } from "rxjs";
|
||||
import { combineLatest, map, Observable, shareReplay } from "rxjs";
|
||||
|
||||
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
|
||||
import { UserKeyDefinition, NUDGES_DISK } from "@bitwarden/common/platform/state";
|
||||
import { UserId } from "@bitwarden/common/types/guid";
|
||||
import { UnionOfValues } from "@bitwarden/common/vault/types/union-of-values";
|
||||
@@ -83,7 +81,6 @@ export class NudgesService {
|
||||
* @private
|
||||
*/
|
||||
private defaultNudgeService = inject(DefaultSingleNudgeService);
|
||||
private configService = inject(ConfigService);
|
||||
|
||||
private getNudgeService(nudge: NudgeType): SingleNudgeService {
|
||||
return this.customNudgeServices[nudge] ?? this.defaultNudgeService;
|
||||
@@ -95,16 +92,9 @@ export class NudgesService {
|
||||
* @param userId
|
||||
*/
|
||||
showNudgeSpotlight$(nudge: NudgeType, userId: UserId): Observable<boolean> {
|
||||
return this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge).pipe(
|
||||
switchMap((hasVaultNudgeFlag) => {
|
||||
if (!hasVaultNudgeFlag) {
|
||||
return of(false);
|
||||
}
|
||||
return this.getNudgeService(nudge)
|
||||
.nudgeStatus$(nudge, userId)
|
||||
.pipe(map((nudgeStatus) => !nudgeStatus.hasSpotlightDismissed));
|
||||
}),
|
||||
);
|
||||
return this.getNudgeService(nudge)
|
||||
.nudgeStatus$(nudge, userId)
|
||||
.pipe(map((nudgeStatus) => !nudgeStatus.hasSpotlightDismissed));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,16 +103,9 @@ export class NudgesService {
|
||||
* @param userId
|
||||
*/
|
||||
showNudgeBadge$(nudge: NudgeType, userId: UserId): Observable<boolean> {
|
||||
return this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge).pipe(
|
||||
switchMap((hasVaultNudgeFlag) => {
|
||||
if (!hasVaultNudgeFlag) {
|
||||
return of(false);
|
||||
}
|
||||
return this.getNudgeService(nudge)
|
||||
.nudgeStatus$(nudge, userId)
|
||||
.pipe(map((nudgeStatus) => !nudgeStatus.hasBadgeDismissed));
|
||||
}),
|
||||
);
|
||||
return this.getNudgeService(nudge)
|
||||
.nudgeStatus$(nudge, userId)
|
||||
.pipe(map((nudgeStatus) => !nudgeStatus.hasBadgeDismissed));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,14 +114,7 @@ export class NudgesService {
|
||||
* @param userId
|
||||
*/
|
||||
showNudgeStatus$(nudge: NudgeType, userId: UserId) {
|
||||
return this.configService.getFeatureFlag$(FeatureFlag.PM8851_BrowserOnboardingNudge).pipe(
|
||||
switchMap((hasVaultNudgeFlag) => {
|
||||
if (!hasVaultNudgeFlag) {
|
||||
return of({ hasBadgeDismissed: true, hasSpotlightDismissed: true } as NudgeStatus);
|
||||
}
|
||||
return this.getNudgeService(nudge).nudgeStatus$(nudge, userId);
|
||||
}),
|
||||
);
|
||||
return this.getNudgeService(nudge).nudgeStatus$(nudge, userId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -47,7 +47,6 @@ export enum FeatureFlag {
|
||||
EventBasedOrganizationIntegrations = "event-based-organization-integrations",
|
||||
|
||||
/* Vault */
|
||||
PM8851_BrowserOnboardingNudge = "pm-8851-browser-onboarding-nudge",
|
||||
PM19941MigrateCipherDomainToSdk = "pm-19941-migrate-cipher-domain-to-sdk",
|
||||
PM22134SdkCipherListView = "pm-22134-sdk-cipher-list-view",
|
||||
PM22136_SdkCipherEncryption = "pm-22136-sdk-cipher-encryption",
|
||||
@@ -92,7 +91,6 @@ export const DefaultFeatureFlagValue = {
|
||||
[FeatureFlag.EventBasedOrganizationIntegrations]: FALSE,
|
||||
|
||||
/* Vault */
|
||||
[FeatureFlag.PM8851_BrowserOnboardingNudge]: FALSE,
|
||||
[FeatureFlag.CipherKeyEncryption]: FALSE,
|
||||
[FeatureFlag.PM19941MigrateCipherDomainToSdk]: FALSE,
|
||||
[FeatureFlag.RemoveCardItemTypePolicy]: FALSE,
|
||||
|
||||
Reference in New Issue
Block a user