From d0b09202c6684fd3b5482baf3abfa49a788908ce Mon Sep 17 00:00:00 2001 From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com> Date: Wed, 25 Sep 2024 10:40:23 -0700 Subject: [PATCH] [PM-12504] - hide create send button and send tab when sends are disabled (#11186) * hide create send button and send tab when sends are disabled * reverse logic * tidy up filter. * fix popup tab navigation filter * fix popup tab nav state * fix popup-layout stories --- .../popup/layout/popup-layout.stories.ts | 26 +++++++ .../layout/popup-tab-navigation.component.ts | 77 ++++++++++++------- .../popup/send-v2/send-v2.component.html | 19 +++-- .../popup/send-v2/send-v2.component.spec.ts | 6 ++ .../tools/popup/send-v2/send-v2.component.ts | 15 +++- 5 files changed, 108 insertions(+), 35 deletions(-) diff --git a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts index affa804cc7..4851541576 100644 --- a/apps/browser/src/platform/popup/layout/popup-layout.stories.ts +++ b/apps/browser/src/platform/popup/layout/popup-layout.stories.ts @@ -3,7 +3,9 @@ import { Component, importProvidersFrom } from "@angular/core"; import { RouterModule } from "@angular/router"; import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service"; +import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; import { AvatarModule, BadgeModule, @@ -318,6 +320,30 @@ export default { }); }, }, + { + provide: PolicyService, + useFactory: () => { + return { + policyAppliesToActiveUser$: () => { + return { + pipe: () => ({ + subscribe: () => ({}), + }), + }; + }, + }; + }, + }, + { + provide: SendService, + useFactory: () => { + return { + sends$: () => { + return { pipe: () => ({}) }; + }, + }; + }, + }, ], }), applicationConfig({ diff --git a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts index ced3f6462e..8463bbe6e9 100644 --- a/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts +++ b/apps/browser/src/platform/popup/layout/popup-tab-navigation.component.ts @@ -1,9 +1,41 @@ import { CommonModule } from "@angular/common"; import { Component } from "@angular/core"; +import { takeUntilDestroyed } from "@angular/core/rxjs-interop"; import { RouterModule } from "@angular/router"; +import { filter, map, switchMap } from "rxjs"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { PolicyType } from "@bitwarden/common/admin-console/enums"; +import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction"; import { LinkModule } from "@bitwarden/components"; +const allNavButtons = [ + { + label: "Vault", + page: "/tabs/vault", + iconKey: "lock", + iconKeyActive: "lock-f", + }, + { + label: "Generator", + page: "/tabs/generator", + iconKey: "generate", + iconKeyActive: "generate-f", + }, + { + label: "Send", + page: "/tabs/send", + iconKey: "send", + iconKeyActive: "send-f", + }, + { + label: "Settings", + page: "/tabs/settings", + iconKey: "cog", + iconKeyActive: "cog-f", + }, +]; + @Component({ selector: "popup-tab-navigation", templateUrl: "popup-tab-navigation.component.html", @@ -14,30 +46,23 @@ import { LinkModule } from "@bitwarden/components"; }, }) export class PopupTabNavigationComponent { - navButtons = [ - { - label: "Vault", - page: "/tabs/vault", - iconKey: "lock", - iconKeyActive: "lock-f", - }, - { - label: "Generator", - page: "/tabs/generator", - iconKey: "generate", - iconKeyActive: "generate-f", - }, - { - label: "Send", - page: "/tabs/send", - iconKey: "send", - iconKeyActive: "send-f", - }, - { - label: "Settings", - page: "/tabs/settings", - iconKey: "cog", - iconKeyActive: "cog-f", - }, - ]; + navButtons = allNavButtons; + constructor( + private policyService: PolicyService, + private sendService: SendService, + ) { + this.policyService + .policyAppliesToActiveUser$(PolicyType.DisableSend) + .pipe( + filter((policyAppliesToActiveUser) => policyAppliesToActiveUser), + switchMap(() => this.sendService.sends$), + map((sends) => sends.length > 1), + takeUntilDestroyed(), + ) + .subscribe((hasSends) => { + this.navButtons = hasSends + ? allNavButtons + : allNavButtons.filter((b) => b.page !== "/tabs/send"); + }); + } } diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.html b/apps/browser/src/tools/popup/send-v2/send-v2.component.html index a8dd3e24f2..698901d846 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.html +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.html @@ -1,12 +1,20 @@ - - + +
+ + {{ "sendDisabledWarning" | i18n }} + + + + + +
{{ "sendsNoItemsTitle" | i18n }} {{ "sendsNoItemsMessage" | i18n }} - +
@@ -31,9 +39,4 @@ - -
- - -
diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts index 50e5531743..63e3c2d2fc 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.spec.ts @@ -7,6 +7,7 @@ import { of, BehaviorSubject } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; import { SearchService } from "@bitwarden/common/abstractions/search.service"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; import { AccountService } from "@bitwarden/common/auth/abstractions/account.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AvatarService } from "@bitwarden/common/auth/abstractions/avatar.service"; @@ -46,6 +47,7 @@ describe("SendV2Component", () => { let sendListFiltersServiceFilters$: BehaviorSubject<{ sendType: SendType | null }>; let sendItemsServiceEmptyList$: BehaviorSubject; let sendItemsServiceNoFilteredResults$: BehaviorSubject; + let policyService: MockProxy; beforeEach(async () => { sendListFiltersServiceFilters$ = new BehaviorSubject({ sendType: null }); @@ -60,6 +62,9 @@ describe("SendV2Component", () => { latestSearchText$: of(""), }); + policyService = mock(); + policyService.policyAppliesToActiveUser$.mockReturnValue(of(true)); // Return `true` by default + sendListFiltersService = new SendListFiltersService(mock(), new FormBuilder()); sendListFiltersService.filters$ = sendListFiltersServiceFilters$; @@ -104,6 +109,7 @@ describe("SendV2Component", () => { { provide: I18nService, useValue: { t: (key: string) => key } }, { provide: SendListFiltersService, useValue: sendListFiltersService }, { provide: PopupRouterCacheService, useValue: mock() }, + { provide: PolicyService, useValue: policyService }, ], }).compileComponents(); diff --git a/apps/browser/src/tools/popup/send-v2/send-v2.component.ts b/apps/browser/src/tools/popup/send-v2/send-v2.component.ts index 5c1ec89fde..19fff402e2 100644 --- a/apps/browser/src/tools/popup/send-v2/send-v2.component.ts +++ b/apps/browser/src/tools/popup/send-v2/send-v2.component.ts @@ -5,8 +5,10 @@ import { RouterLink } from "@angular/router"; import { combineLatest } from "rxjs"; import { JslibModule } from "@bitwarden/angular/jslib.module"; +import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction"; +import { PolicyType } from "@bitwarden/common/admin-console/enums"; import { SendType } from "@bitwarden/common/tools/send/enums/send-type"; -import { ButtonModule, Icons, NoItemsModule } from "@bitwarden/components"; +import { ButtonModule, CalloutModule, Icons, NoItemsModule } from "@bitwarden/components"; import { NoSendsIcon, NewSendDropdownComponent, @@ -31,6 +33,7 @@ export enum SendState { templateUrl: "send-v2.component.html", standalone: true, imports: [ + CalloutModule, PopupPageComponent, PopupHeaderComponent, PopOutComponent, @@ -61,9 +64,12 @@ export class SendV2Component implements OnInit, OnDestroy { protected noResultsIcon = Icons.NoResults; + protected sendsDisabled = false; + constructor( protected sendItemsService: SendItemsService, protected sendListFiltersService: SendListFiltersService, + private policyService: PolicyService, ) { combineLatest([ this.sendItemsService.emptyList$, @@ -90,6 +96,13 @@ export class SendV2Component implements OnInit, OnDestroy { this.listState = null; }); + + this.policyService + .policyAppliesToActiveUser$(PolicyType.DisableSend) + .pipe(takeUntilDestroyed()) + .subscribe((sendsDisabled) => { + this.sendsDisabled = sendsDisabled; + }); } ngOnInit(): void {}