[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
This commit is contained in:
Jordan Aasen 2024-09-25 10:40:23 -07:00 committed by GitHub
parent 742900a663
commit d0b09202c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 108 additions and 35 deletions

View File

@ -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({

View File

@ -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");
});
}
}

View File

@ -1,12 +1,20 @@
<popup-page>
<popup-header slot="header" [pageTitle]="'send' | i18n">
<ng-container slot="end">
<tools-new-send-dropdown></tools-new-send-dropdown>
<tools-new-send-dropdown *ngIf="!sendsDisabled"></tools-new-send-dropdown>
<app-pop-out></app-pop-out>
<app-current-account></app-current-account>
</ng-container>
</popup-header>
<div slot="above-scroll-area" class="tw-p-4">
<bit-callout *ngIf="sendsDisabled" [title]="'sendDisabled' | i18n">
{{ "sendDisabledWarning" | i18n }}
</bit-callout>
<ng-container *ngIf="!sendsDisabled">
<tools-send-search></tools-send-search>
<app-send-list-filters></app-send-list-filters>
</ng-container>
</div>
<div
*ngIf="listState === sendState.Empty"
@ -15,7 +23,7 @@
<bit-no-items [icon]="noItemIcon" class="tw-text-main">
<ng-container slot="title">{{ "sendsNoItemsTitle" | i18n }}</ng-container>
<ng-container slot="description">{{ "sendsNoItemsMessage" | i18n }}</ng-container>
<tools-new-send-dropdown slot="button"></tools-new-send-dropdown>
<tools-new-send-dropdown *ngIf="!sendsDisabled" slot="button"></tools-new-send-dropdown>
</bit-no-items>
</div>
@ -31,9 +39,4 @@
</div>
<app-send-list-items-container [headerText]="title | i18n" [sends]="sends$ | async" />
</ng-container>
<div slot="above-scroll-area" class="tw-p-4" *ngIf="listState !== sendState.Empty">
<tools-send-search></tools-send-search>
<app-send-list-filters></app-send-list-filters>
</div>
</popup-page>

View File

@ -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<boolean>;
let sendItemsServiceNoFilteredResults$: BehaviorSubject<boolean>;
let policyService: MockProxy<PolicyService>;
beforeEach(async () => {
sendListFiltersServiceFilters$ = new BehaviorSubject({ sendType: null });
@ -60,6 +62,9 @@ describe("SendV2Component", () => {
latestSearchText$: of(""),
});
policyService = mock<PolicyService>();
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<PopupRouterCacheService>() },
{ provide: PolicyService, useValue: policyService },
],
}).compileComponents();

View File

@ -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 {}