diff --git a/apps/browser/src/_locales/en/messages.json b/apps/browser/src/_locales/en/messages.json index 22e0eba1b4..5152028d37 100644 --- a/apps/browser/src/_locales/en/messages.json +++ b/apps/browser/src/_locales/en/messages.json @@ -3358,20 +3358,6 @@ "passkeyRemoved": { "message": "Passkey removed" }, - "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in the All Vaults view and only accessible via the Admin Console." - }, - "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in the All Vaults view and will only be accessible via the Admin Console." - }, - "unassignedItemsBannerCTAPartOne": { - "message": "Assign these items to a collection from the", - "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." - }, - "unassignedItemsBannerCTAPartTwo": { - "message": "to make them visible.", - "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." - }, "autofillSuggestions": { "message": "Auto-fill suggestions" }, diff --git a/apps/browser/src/vault/popup/components/vault/current-tab.component.html b/apps/browser/src/vault/popup/components/vault/current-tab.component.html index 0b2e16d09d..bb8a401da6 100644 --- a/apps/browser/src/vault/popup/components/vault/current-tab.component.html +++ b/apps/browser/src/vault/popup/components/vault/current-tab.component.html @@ -36,44 +36,6 @@ - -

- {{ unassignedItemsBannerService.bannerText$ | async | i18n }} - {{ "unassignedItemsBannerCTAPartOne" | i18n }} - {{ "adminConsole" | i18n }} - {{ "unassignedItemsBannerCTAPartTwo" | i18n }} - {{ "learnMore" | i18n }} -

- -

{{ "typeLogins" | i18n }} diff --git a/apps/browser/src/vault/popup/components/vault/current-tab.component.ts b/apps/browser/src/vault/popup/components/vault/current-tab.component.ts index 97856a952c..ec69330745 100644 --- a/apps/browser/src/vault/popup/components/vault/current-tab.component.ts +++ b/apps/browser/src/vault/popup/components/vault/current-tab.component.ts @@ -3,14 +3,11 @@ import { Router } from "@angular/router"; import { Subject, firstValueFrom, from, Subscription } from "rxjs"; import { debounceTime, switchMap, takeUntil } from "rxjs/operators"; -import { UnassignedItemsBannerService } from "@bitwarden/angular/services/unassigned-items-banner.service"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; import { AutofillOverlayVisibility } from "@bitwarden/common/autofill/constants"; import { AutofillSettingsServiceAbstraction } from "@bitwarden/common/autofill/services/autofill-settings.service"; -import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum"; import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service"; -import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service"; import { Utils } from "@bitwarden/common/platform/misc/utils"; @@ -58,10 +55,6 @@ export class CurrentTabComponent implements OnInit, OnDestroy { private loadedTimeout: number; private searchTimeout: number; - protected unassignedItemsBannerEnabled$ = this.configService.getFeatureFlag$( - FeatureFlag.UnassignedItemsBanner, - ); - constructor( private platformUtilsService: PlatformUtilsService, private cipherService: CipherService, @@ -78,8 +71,6 @@ export class CurrentTabComponent implements OnInit, OnDestroy { private organizationService: OrganizationService, private vaultFilterService: VaultFilterService, private vaultSettingsService: VaultSettingsService, - private configService: ConfigService, - protected unassignedItemsBannerService: UnassignedItemsBannerService, ) {} async ngOnInit() { diff --git a/apps/web/src/app/layouts/header/web-header.component.html b/apps/web/src/app/layouts/header/web-header.component.html index e2b3e7910a..5b55eede77 100644 --- a/apps/web/src/app/layouts/header/web-header.component.html +++ b/apps/web/src/app/layouts/header/web-header.component.html @@ -1,31 +1,3 @@ - - {{ unassignedItemsBannerService.bannerText$ | async | i18n }} - {{ "unassignedItemsBannerCTAPartOne" | i18n }} - {{ "adminConsole" | i18n }} - {{ "unassignedItemsBannerCTAPartTwo" | i18n }} - {{ "learnMore" | i18n }} -
; protected selfHosted: boolean; protected hostname = location.hostname; - protected unassignedItemsBannerEnabled$ = this.configService.getFeatureFlag$( - FeatureFlag.UnassignedItemsBanner, - ); constructor( private route: ActivatedRoute, private platformUtilsService: PlatformUtilsService, private vaultTimeoutSettingsService: VaultTimeoutSettingsService, private messagingService: MessagingService, - protected unassignedItemsBannerService: UnassignedItemsBannerService, - private configService: ConfigService, private accountService: AccountService, ) { this.routeData$ = this.route.data.pipe( diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index f587560118..0f9e334fea 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -8161,23 +8161,6 @@ "restrictedGroupAccessDesc": { "message": "You cannot add yourself to a group." }, - "unassignedItemsBannerSelfHost": { - "message": "Notice: On May 2, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console. Assign these items to a collection from the Admin Console to make them visible." - }, - "unassignedItemsBannerNotice": { - "message": "Notice: Unassigned organization items are no longer visible in your All Vaults view across devices and are now only accessible via the Admin Console." - }, - "unassignedItemsBannerSelfHostNotice": { - "message": "Notice: On May 16, 2024, unassigned organization items will no longer be visible in your All Vaults view across devices and will only be accessible via the Admin Console." - }, - "unassignedItemsBannerCTAPartOne": { - "message": "Assign these items to a collection from the", - "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." - }, - "unassignedItemsBannerCTAPartTwo": { - "message": "to make them visible.", - "description": "This will be part of a larger sentence, which will read like so: Assign these items to a collection from the Admin Console to make them visible." - }, "deleteProvider": { "message": "Delete provider" }, diff --git a/libs/angular/src/services/unassigned-items-banner.api.service.ts b/libs/angular/src/services/unassigned-items-banner.api.service.ts deleted file mode 100644 index 69b74f8c7f..0000000000 --- a/libs/angular/src/services/unassigned-items-banner.api.service.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Injectable } from "@angular/core"; - -import { ApiService } from "@bitwarden/common/abstractions/api.service"; - -@Injectable({ providedIn: "root" }) -export class UnassignedItemsBannerApiService { - constructor(private apiService: ApiService) {} - - async getShowUnassignedCiphersBanner(): Promise { - const r = await this.apiService.send( - "GET", - "/ciphers/has-unassigned-ciphers", - null, - true, - true, - ); - return r; - } -} diff --git a/libs/angular/src/services/unassigned-items-banner.service.spec.ts b/libs/angular/src/services/unassigned-items-banner.service.spec.ts deleted file mode 100644 index bf0fb23881..0000000000 --- a/libs/angular/src/services/unassigned-items-banner.service.spec.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { MockProxy, mock } from "jest-mock-extended"; -import { firstValueFrom, of } from "rxjs"; - -import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service"; -import { FakeStateProvider, mockAccountServiceWith } from "@bitwarden/common/spec"; -import { UserId } from "@bitwarden/common/types/guid"; - -import { UnassignedItemsBannerApiService } from "./unassigned-items-banner.api.service"; -import { SHOW_BANNER_KEY, UnassignedItemsBannerService } from "./unassigned-items-banner.service"; - -describe("UnassignedItemsBanner", () => { - let stateProvider: FakeStateProvider; - let apiService: MockProxy; - let environmentService: MockProxy; - let organizationService: MockProxy; - - const sutFactory = () => - new UnassignedItemsBannerService( - stateProvider, - apiService, - environmentService, - organizationService, - ); - - beforeEach(() => { - const fakeAccountService = mockAccountServiceWith("userId" as UserId); - stateProvider = new FakeStateProvider(fakeAccountService); - apiService = mock(); - environmentService = mock(); - environmentService.environment$ = of(null); - organizationService = mock(); - organizationService.organizations$ = of([]); - }); - - it("shows the banner if showBanner local state is true", async () => { - const showBanner = stateProvider.activeUser.getFake(SHOW_BANNER_KEY); - showBanner.nextState(true); - - const sut = sutFactory(); - expect(await firstValueFrom(sut.showBanner$)).toBe(true); - expect(apiService.getShowUnassignedCiphersBanner).not.toHaveBeenCalled(); - }); - - it("does not show the banner if showBanner local state is false", async () => { - const showBanner = stateProvider.activeUser.getFake(SHOW_BANNER_KEY); - showBanner.nextState(false); - - const sut = sutFactory(); - expect(await firstValueFrom(sut.showBanner$)).toBe(false); - expect(apiService.getShowUnassignedCiphersBanner).not.toHaveBeenCalled(); - }); - - it("fetches from server if local state has not been set yet", async () => { - apiService.getShowUnassignedCiphersBanner.mockResolvedValue(true); - - const showBanner = stateProvider.activeUser.getFake(SHOW_BANNER_KEY); - showBanner.nextState(undefined); - - const sut = sutFactory(); - - expect(await firstValueFrom(sut.showBanner$)).toBe(true); - expect(apiService.getShowUnassignedCiphersBanner).toHaveBeenCalledTimes(1); - }); -}); diff --git a/libs/angular/src/services/unassigned-items-banner.service.ts b/libs/angular/src/services/unassigned-items-banner.service.ts deleted file mode 100644 index db93d4c4fc..0000000000 --- a/libs/angular/src/services/unassigned-items-banner.service.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { Injectable } from "@angular/core"; -import { combineLatest, concatMap, map, startWith } from "rxjs"; - -import { - OrganizationService, - canAccessOrgAdmin, -} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction"; -import { - EnvironmentService, - Region, -} from "@bitwarden/common/platform/abstractions/environment.service"; -import { - StateProvider, - UNASSIGNED_ITEMS_BANNER_DISK, - UserKeyDefinition, -} from "@bitwarden/common/platform/state"; - -import { UnassignedItemsBannerApiService } from "./unassigned-items-banner.api.service"; - -export const SHOW_BANNER_KEY = new UserKeyDefinition( - UNASSIGNED_ITEMS_BANNER_DISK, - "showBanner", - { - deserializer: (b) => b, - clearOn: [], - }, -); - -/** Displays a banner that tells users how to move their unassigned items into a collection. */ -@Injectable({ providedIn: "root" }) -export class UnassignedItemsBannerService { - private _showBanner = this.stateProvider.getActive(SHOW_BANNER_KEY); - - showBanner$ = this._showBanner.state$.pipe( - concatMap(async (showBannerState) => { - // null indicates that the user has not seen or dismissed the banner yet - get the flag from server - if (showBannerState == null) { - const showBannerResponse = await this.apiService.getShowUnassignedCiphersBanner(); - await this._showBanner.update(() => showBannerResponse); - return showBannerResponse; - } - - return showBannerState; - }), - ); - - private adminConsoleOrg$ = this.organizationService.organizations$.pipe( - map((orgs) => orgs.find((o) => canAccessOrgAdmin(o))), - ); - - adminConsoleUrl$ = combineLatest([ - this.adminConsoleOrg$, - this.environmentService.environment$, - ]).pipe( - map(([org, environment]) => { - if (org == null || environment == null) { - return "#"; - } - - return environment.getWebVaultUrl() + "/#/organizations/" + org.id; - }), - ); - - bannerText$ = this.environmentService.environment$.pipe( - map((e) => - e?.getRegion() == Region.SelfHosted - ? "unassignedItemsBannerSelfHostNotice" - : "unassignedItemsBannerNotice", - ), - ); - - loading$ = combineLatest([this.adminConsoleUrl$, this.bannerText$]).pipe( - startWith(true), - map(() => false), - ); - - constructor( - private stateProvider: StateProvider, - private apiService: UnassignedItemsBannerApiService, - private environmentService: EnvironmentService, - private organizationService: OrganizationService, - ) {} - - async hideBanner() { - await this._showBanner.update(() => false); - } -} diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 3f451e38b1..e9b154d2f4 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -11,7 +11,6 @@ export enum FeatureFlag { ShowPaymentMethodWarningBanners = "show-payment-method-warning-banners", EnableConsolidatedBilling = "enable-consolidated-billing", AC1795_UpdatedSubscriptionStatusSection = "AC-1795_updated-subscription-status-section", - UnassignedItemsBanner = "unassigned-items-banner", EnableDeleteProvider = "AC-1218-delete-provider", ExtensionRefresh = "extension-refresh", RestrictProviderAccess = "restrict-provider-access", @@ -45,7 +44,6 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.ShowPaymentMethodWarningBanners]: FALSE, [FeatureFlag.EnableConsolidatedBilling]: FALSE, [FeatureFlag.AC1795_UpdatedSubscriptionStatusSection]: FALSE, - [FeatureFlag.UnassignedItemsBanner]: FALSE, [FeatureFlag.EnableDeleteProvider]: FALSE, [FeatureFlag.ExtensionRefresh]: FALSE, [FeatureFlag.RestrictProviderAccess]: FALSE,