1
0
mirror of https://github.com/bitwarden/browser.git synced 2024-10-08 05:47:50 +02:00

[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 { RouterModule } from "@angular/router";
import { Meta, StoryObj, applicationConfig, moduleMetadata } from "@storybook/angular"; 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 { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { import {
AvatarModule, AvatarModule,
BadgeModule, BadgeModule,
@ -318,6 +320,30 @@ export default {
}); });
}, },
}, },
{
provide: PolicyService,
useFactory: () => {
return {
policyAppliesToActiveUser$: () => {
return {
pipe: () => ({
subscribe: () => ({}),
}),
};
},
};
},
},
{
provide: SendService,
useFactory: () => {
return {
sends$: () => {
return { pipe: () => ({}) };
},
};
},
},
], ],
}), }),
applicationConfig({ applicationConfig({

View File

@ -1,9 +1,41 @@
import { CommonModule } from "@angular/common"; import { CommonModule } from "@angular/common";
import { Component } from "@angular/core"; import { Component } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { RouterModule } from "@angular/router"; 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"; 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({ @Component({
selector: "popup-tab-navigation", selector: "popup-tab-navigation",
templateUrl: "popup-tab-navigation.component.html", templateUrl: "popup-tab-navigation.component.html",
@ -14,30 +46,23 @@ import { LinkModule } from "@bitwarden/components";
}, },
}) })
export class PopupTabNavigationComponent { export class PopupTabNavigationComponent {
navButtons = [ navButtons = allNavButtons;
{ constructor(
label: "Vault", private policyService: PolicyService,
page: "/tabs/vault", private sendService: SendService,
iconKey: "lock", ) {
iconKeyActive: "lock-f", this.policyService
}, .policyAppliesToActiveUser$(PolicyType.DisableSend)
{ .pipe(
label: "Generator", filter((policyAppliesToActiveUser) => policyAppliesToActiveUser),
page: "/tabs/generator", switchMap(() => this.sendService.sends$),
iconKey: "generate", map((sends) => sends.length > 1),
iconKeyActive: "generate-f", takeUntilDestroyed(),
}, )
{ .subscribe((hasSends) => {
label: "Send", this.navButtons = hasSends
page: "/tabs/send", ? allNavButtons
iconKey: "send", : allNavButtons.filter((b) => b.page !== "/tabs/send");
iconKeyActive: "send-f", });
}, }
{
label: "Settings",
page: "/tabs/settings",
iconKey: "cog",
iconKeyActive: "cog-f",
},
];
} }

View File

@ -1,12 +1,20 @@
<popup-page> <popup-page>
<popup-header slot="header" [pageTitle]="'send' | i18n"> <popup-header slot="header" [pageTitle]="'send' | i18n">
<ng-container slot="end"> <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-pop-out></app-pop-out>
<app-current-account></app-current-account> <app-current-account></app-current-account>
</ng-container> </ng-container>
</popup-header> </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 <div
*ngIf="listState === sendState.Empty" *ngIf="listState === sendState.Empty"
@ -15,7 +23,7 @@
<bit-no-items [icon]="noItemIcon" class="tw-text-main"> <bit-no-items [icon]="noItemIcon" class="tw-text-main">
<ng-container slot="title">{{ "sendsNoItemsTitle" | i18n }}</ng-container> <ng-container slot="title">{{ "sendsNoItemsTitle" | i18n }}</ng-container>
<ng-container slot="description">{{ "sendsNoItemsMessage" | 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> </bit-no-items>
</div> </div>
@ -31,9 +39,4 @@
</div> </div>
<app-send-list-items-container [headerText]="title | i18n" [sends]="sends$ | async" /> <app-send-list-items-container [headerText]="title | i18n" [sends]="sends$ | async" />
</ng-container> </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> </popup-page>

View File

@ -7,6 +7,7 @@ import { of, BehaviorSubject } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module"; import { JslibModule } from "@bitwarden/angular/jslib.module";
import { SearchService } from "@bitwarden/common/abstractions/search.service"; 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 { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service"; import { AuthService } from "@bitwarden/common/auth/abstractions/auth.service";
import { AvatarService } from "@bitwarden/common/auth/abstractions/avatar.service"; import { AvatarService } from "@bitwarden/common/auth/abstractions/avatar.service";
@ -46,6 +47,7 @@ describe("SendV2Component", () => {
let sendListFiltersServiceFilters$: BehaviorSubject<{ sendType: SendType | null }>; let sendListFiltersServiceFilters$: BehaviorSubject<{ sendType: SendType | null }>;
let sendItemsServiceEmptyList$: BehaviorSubject<boolean>; let sendItemsServiceEmptyList$: BehaviorSubject<boolean>;
let sendItemsServiceNoFilteredResults$: BehaviorSubject<boolean>; let sendItemsServiceNoFilteredResults$: BehaviorSubject<boolean>;
let policyService: MockProxy<PolicyService>;
beforeEach(async () => { beforeEach(async () => {
sendListFiltersServiceFilters$ = new BehaviorSubject({ sendType: null }); sendListFiltersServiceFilters$ = new BehaviorSubject({ sendType: null });
@ -60,6 +62,9 @@ describe("SendV2Component", () => {
latestSearchText$: of(""), latestSearchText$: of(""),
}); });
policyService = mock<PolicyService>();
policyService.policyAppliesToActiveUser$.mockReturnValue(of(true)); // Return `true` by default
sendListFiltersService = new SendListFiltersService(mock(), new FormBuilder()); sendListFiltersService = new SendListFiltersService(mock(), new FormBuilder());
sendListFiltersService.filters$ = sendListFiltersServiceFilters$; sendListFiltersService.filters$ = sendListFiltersServiceFilters$;
@ -104,6 +109,7 @@ describe("SendV2Component", () => {
{ provide: I18nService, useValue: { t: (key: string) => key } }, { provide: I18nService, useValue: { t: (key: string) => key } },
{ provide: SendListFiltersService, useValue: sendListFiltersService }, { provide: SendListFiltersService, useValue: sendListFiltersService },
{ provide: PopupRouterCacheService, useValue: mock<PopupRouterCacheService>() }, { provide: PopupRouterCacheService, useValue: mock<PopupRouterCacheService>() },
{ provide: PolicyService, useValue: policyService },
], ],
}).compileComponents(); }).compileComponents();

View File

@ -5,8 +5,10 @@ import { RouterLink } from "@angular/router";
import { combineLatest } from "rxjs"; import { combineLatest } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module"; 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 { 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 { import {
NoSendsIcon, NoSendsIcon,
NewSendDropdownComponent, NewSendDropdownComponent,
@ -31,6 +33,7 @@ export enum SendState {
templateUrl: "send-v2.component.html", templateUrl: "send-v2.component.html",
standalone: true, standalone: true,
imports: [ imports: [
CalloutModule,
PopupPageComponent, PopupPageComponent,
PopupHeaderComponent, PopupHeaderComponent,
PopOutComponent, PopOutComponent,
@ -61,9 +64,12 @@ export class SendV2Component implements OnInit, OnDestroy {
protected noResultsIcon = Icons.NoResults; protected noResultsIcon = Icons.NoResults;
protected sendsDisabled = false;
constructor( constructor(
protected sendItemsService: SendItemsService, protected sendItemsService: SendItemsService,
protected sendListFiltersService: SendListFiltersService, protected sendListFiltersService: SendListFiltersService,
private policyService: PolicyService,
) { ) {
combineLatest([ combineLatest([
this.sendItemsService.emptyList$, this.sendItemsService.emptyList$,
@ -90,6 +96,13 @@ export class SendV2Component implements OnInit, OnDestroy {
this.listState = null; this.listState = null;
}); });
this.policyService
.policyAppliesToActiveUser$(PolicyType.DisableSend)
.pipe(takeUntilDestroyed())
.subscribe((sendsDisabled) => {
this.sendsDisabled = sendsDisabled;
});
} }
ngOnInit(): void {} ngOnInit(): void {}