1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-21 11:53:34 +00:00

PM-28183 implemented new sends filter and search design (#17901)

* PM-28183 implemented new sends filter and search design

* PM-28183 resolved table issue fallout from merge conflict

* PM-28183 resolved browser paste url issue

* PM-28183 put new feature behind feature flag

* PM-28183 resolved feature flag

* PM-28183 resolved type-safe approach pr comment

* PM-28183 resolved DesktopSendUIRefresh feature flag is enabled. pr comment

* PM-28183 restored SendUIRefresh

* PM-28183 resolved query parameter subscription pr comment

* PM-28183 resolved pr comment re enum like objects

* PM-28183 resolved remove enum like objects  pr comment

* PM-28183 resolved pr comment re defining filteredSends member variable

* PM-28183 resolved pr comment re Code Duplication in syncCompleted Handler

* PM-28183 resolved pr comment re Floating Promise

* PM-28183 restored feature flag

* PM-28183 resolved pr comment re Dual Binding Pattern

* PM28183 resolved options cell button pr comment

* PM 28183 resolved pr comment re Incorrect CSS Class - Breaking Layout

* PM 28183 resolved pr comment re uery Param Update Causes Redundant Filter Application

* PM-28183 resolved lint issues

* PM 28183 resolved lint issues

* PM-28183 resolved type issue with import

* PM-28183 resolved import in failling test

* chore: rerun web build

* PM-28183 resolved build issues

* PM-28183 resolved build issues

* PM-28183 resolved lint issues
This commit is contained in:
bmbitwarden
2026-01-12 13:26:50 -05:00
committed by GitHub
parent 0aac4cae35
commit 27d43c500f
55 changed files with 276 additions and 148 deletions

View File

@@ -9,9 +9,9 @@ import { map, switchMap } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { SendId } from "@bitwarden/common/types/guid";
import {
AsyncActionsModule,

View File

@@ -11,9 +11,9 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SelfHostedEnvironment } from "@bitwarden/common/platform/services/default-environment.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { ButtonModule, I18nMockService, IconModule, ToastService } from "@bitwarden/components";
import { PopOutComponent } from "../../../../platform/popup/components/pop-out.component";

View File

@@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common";
import { Component, input, OnInit } from "@angular/core";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { CenterPositionStrategy, DialogService } from "@bitwarden/components";
import { SendFormConfig } from "@bitwarden/send-ui";

View File

@@ -17,10 +17,10 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { mockAccountInfoWith } from "@bitwarden/common/spec";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { SearchService } from "@bitwarden/common/vault/abstractions/search.service";
import { ButtonModule, NoItemsModule } from "@bitwarden/components";
import {

View File

@@ -13,7 +13,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
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 { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { SearchService } from "@bitwarden/common/vault/abstractions/search.service";
import { skeletonLoadingDelay } from "@bitwarden/common/vault/utils/skeleton-loading.operator";
@@ -139,7 +139,7 @@ export class SendV2Component implements OnDestroy {
.pipe(takeUntilDestroyed())
.subscribe(([emptyList, noFilteredResults, currentFilter]) => {
if (currentFilter?.sendType !== null) {
this.title = this.sendTypeTitles[currentFilter.sendType] ?? "allSends";
this.title = this.sendTypeTitles[currentFilter.sendType as SendType] ?? "allSends";
} else {
this.title = "allSends";
}

View File

@@ -9,9 +9,9 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { NodeUtils } from "@bitwarden/node/node-utils";
import { Response } from "../../../models/response";

View File

@@ -5,9 +5,9 @@ import { firstValueFrom } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { Response } from "../../../models/response";
import { CliUtils } from "../../../utils";

View File

@@ -13,11 +13,11 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendAccess } from "@bitwarden/common/tools/send/models/domain/send-access";
import { SendAccessRequest } from "@bitwarden/common/tools/send/models/request/send-access.request";
import { SendAccessView } from "@bitwarden/common/tools/send/models/view/send-access.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { KeyService } from "@bitwarden/key-management";
import { NodeUtils } from "@bitwarden/node/node-utils";

View File

@@ -1,4 +1,4 @@
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { Response } from "../../../models/response";
import { TemplateResponse } from "../../../models/response/template.response";

View File

@@ -1,7 +1,7 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendAccessView } from "@bitwarden/common/tools/send/models/view/send-access.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { BaseResponse } from "../../../models/response/base.response";

View File

@@ -1,8 +1,8 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { BaseResponse } from "../../../models/response/base.response";

View File

@@ -7,7 +7,7 @@ import * as chalk from "chalk";
import { program, Command, Option, OptionValues } from "commander";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { BaseProgram } from "../../base-program";
import { Response } from "../../models/response";

View File

@@ -6,7 +6,7 @@ import { BehaviorSubject } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { FakeGlobalStateProvider } from "@bitwarden/common/spec";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { NavigationModule } from "@bitwarden/components";
import { SendListFiltersService } from "@bitwarden/send-ui";
import { GlobalStateProvider } from "@bitwarden/state";

View File

@@ -4,7 +4,7 @@ import { toSignal } from "@angular/core/rxjs-interop";
import { NavigationEnd, Router } from "@angular/router";
import { filter, map, startWith } from "rxjs";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { NavigationModule } from "@bitwarden/components";
import { SendListFiltersService } from "@bitwarden/send-ui";
import { I18nPipe } from "@bitwarden/ui-common";

View File

@@ -16,10 +16,10 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { SearchService } from "@bitwarden/common/vault/abstractions/search.service";
import { DialogService, ToastService } from "@bitwarden/components";
import { SendItemsService, SendListFiltersService } from "@bitwarden/send-ui";

View File

@@ -22,9 +22,9 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { ButtonModule, DialogService, ToastService } from "@bitwarden/components";
import {

View File

@@ -8,9 +8,9 @@ import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abs
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { SendAddEditDialogComponent } from "@bitwarden/send-ui";

View File

@@ -8,7 +8,7 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { ButtonModule, DialogService, MenuModule } from "@bitwarden/components";
import {
DefaultSendFormConfigService,

View File

@@ -11,12 +11,12 @@ import { ErrorResponse } from "@bitwarden/common/models/response/error.response"
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { SymmetricCryptoKey } from "@bitwarden/common/platform/models/domain/symmetric-crypto-key";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendAccess } from "@bitwarden/common/tools/send/models/domain/send-access";
import { SendAccessRequest } from "@bitwarden/common/tools/send/models/request/send-access.request";
import { SendAccessResponse } from "@bitwarden/common/tools/send/models/response/send-access.response";
import { SendAccessView } from "@bitwarden/common/tools/send/models/view/send-access.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { AnonLayoutWrapperDataService, ToastService } from "@bitwarden/components";
import { KeyService } from "@bitwarden/key-management";

View File

@@ -17,100 +17,159 @@
<bit-callout type="warning" title="{{ 'sendDisabled' | i18n }}" *ngIf="disableSend">
{{ "sendDisabledWarning" | i18n }}
</bit-callout>
<div class="tw-grid tw-grid-cols-12 tw-gap-4">
<div class="tw-col-span-3">
<div class="tw-border tw-border-solid tw-border-secondary-300 tw-rounded" data-testid="filters">
<div
class="tw-bg-background-alt tw-border-0 tw-border-b tw-border-solid tw-border-secondary-100 tw-rounded-t tw-px-5 tw-py-2.5 tw-font-medium tw-uppercase"
data-testid="filters-header"
>
{{ "filters" | i18n }}
</div>
<div class="tw-p-5" data-testid="filters-body">
<div class="tw-mb-4">
<bit-search
[(ngModel)]="searchText"
[placeholder]="'searchSends' | i18n"
(input)="searchTextChanged()"
appAutofocus
/>
</div>
<div class="filter">
<ul class="filter-options">
<li class="filter-option" [ngClass]="{ active: selectedAll }">
<span class="filter-buttons">
<button type="button" class="filter-button" appStopClick (click)="selectAll()">
<i class="bwi bwi-fw bwi-filter"></i>{{ "allSends" | i18n }}
</button>
</span>
</li>
</ul>
</div>
<div class="filter">
<div class="filter-heading">
<h3>{{ "types" | i18n }}</h3>
</div>
<ul class="filter-options">
<li class="filter-option" [ngClass]="{ active: selectedType === sendType.Text }">
<span class="filter-buttons">
<button
type="button"
class="filter-button"
appStopClick
(click)="selectType(sendType.Text)"
>
<i class="bwi bwi-fw bwi-file-text"></i>{{ "sendTypeText" | i18n }}
</button>
</span>
</li>
<li class="filter-option" [ngClass]="{ active: selectedType === sendType.File }">
<span class="filter-buttons">
<button
type="button"
class="filter-button"
appStopClick
(click)="selectType(sendType.File)"
>
<i class="bwi bwi-fw bwi-file"></i>{{ "sendTypeFile" | i18n }}
</button>
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="tw-col-span-9">
<tools-send-table
*ngIf="filteredSends && filteredSends.length"
[dataSource]="dataSource"
[disableSend]="disableSend"
(editSend)="editSend($event)"
(copySend)="copy($event)"
(removePassword)="removePassword($event)"
(deleteSend)="delete($event)"
/>
<div *ngIf="filteredSends && !filteredSends.length">
<ng-container *ngIf="!loaded">
<i
class="bwi bwi-spinner bwi-spin tw-text-muted"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
</ng-container>
<ng-container *ngIf="loaded">
<bit-no-items [icon]="noItemIcon" class="tw-text-main">
<ng-container slot="title">{{ "sendsTitleNoItems" | i18n }}</ng-container>
<ng-container slot="description">{{ "sendsBodyNoItems" | i18n }}</ng-container>
<tools-new-send-dropdown
[hideIcon]="true"
*ngIf="!disableSend"
slot="button"
></tools-new-send-dropdown>
</bit-no-items>
</ng-container>
@if (SendUIRefresh$ | async) {
<div class="tw-mb-4 tw-max-w-md">
<bit-search
[(ngModel)]="searchText"
[placeholder]="'searchSends' | i18n"
(input)="searchTextChanged()"
appAutofocus
/>
</div>
<div class="tw-mb-4">
<bit-toggle-group [selected]="selectedToggleValue" (selectedChange)="onToggleChange($event)">
<bit-toggle [value]="'all'">{{ "allSends" | i18n }}</bit-toggle>
<bit-toggle [value]="'text'">{{ "sendTypeText" | i18n }}</bit-toggle>
<bit-toggle [value]="'file'">{{ "sendTypeFile" | i18n }}</bit-toggle>
</bit-toggle-group>
</div>
<div>
<div class="tw-@container/send-table">
<tools-send-table
*ngIf="filteredSends && filteredSends.length"
[dataSource]="dataSource"
[disableSend]="disableSend"
(editSend)="editSend($event)"
(copySend)="copy($event)"
(removePassword)="removePassword($event)"
(deleteSend)="delete($event)"
/>
<div *ngIf="filteredSends && !filteredSends.length">
<ng-container *ngIf="!loaded">
<i
class="bwi bwi-spinner bwi-spin tw-text-muted"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
</ng-container>
<ng-container *ngIf="loaded">
<bit-no-items [icon]="noItemIcon" class="tw-text-main">
<ng-container slot="title">{{ "sendsTitleNoItems" | i18n }}</ng-container>
<ng-container slot="description">{{ "sendsBodyNoItems" | i18n }}</ng-container>
<tools-new-send-dropdown
[hideIcon]="true"
*ngIf="!disableSend"
slot="button"
></tools-new-send-dropdown>
</bit-no-items>
</ng-container>
</div>
</div>
</div>
</div>
} @else {
<div class="tw-grid tw-grid-cols-12 tw-gap-4">
<div class="tw-col-span-3">
<div
class="tw-border tw-border-solid tw-border-secondary-300 tw-rounded"
data-testid="filters"
>
<div
class="tw-bg-background-alt tw-border-0 tw-border-b tw-border-solid tw-border-secondary-100 tw-rounded-t tw-px-5 tw-py-2.5 tw-font-medium tw-uppercase"
data-testid="filters-header"
>
{{ "filters" | i18n }}
</div>
<div class="tw-p-5" data-testid="filters-body">
<div class="tw-mb-4">
<bit-search
[(ngModel)]="searchText"
[placeholder]="'searchSends' | i18n"
(input)="searchTextChanged()"
appAutofocus
/>
</div>
<div class="filter">
<ul class="filter-options">
<li class="filter-option" [ngClass]="{ active: selectedAll }">
<span class="filter-buttons">
<button type="button" class="filter-button" appStopClick (click)="selectAll()">
<i class="bwi bwi-fw bwi-filter"></i>{{ "allSends" | i18n }}
</button>
</span>
</li>
</ul>
</div>
<div class="filter">
<div class="filter-heading">
<h3>{{ "types" | i18n }}</h3>
</div>
<ul class="filter-options">
<li class="filter-option" [ngClass]="{ active: selectedType === sendType.Text }">
<span class="filter-buttons">
<button
type="button"
class="filter-button"
appStopClick
(click)="selectType(sendType.Text)"
>
<i class="bwi bwi-fw bwi-file-text"></i>{{ "sendTypeText" | i18n }}
</button>
</span>
</li>
<li class="filter-option" [ngClass]="{ active: selectedType === sendType.File }">
<span class="filter-buttons">
<button
type="button"
class="filter-button"
appStopClick
(click)="selectType(sendType.File)"
>
<i class="bwi bwi-fw bwi-file"></i>{{ "sendTypeFile" | i18n }}
</button>
</span>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="tw-col-span-9 tw-@container/send-table">
<!--Listing Table-->
<tools-send-table
*ngIf="filteredSends && filteredSends.length"
[dataSource]="dataSource"
[disableSend]="disableSend"
(editSend)="editSend($event)"
(copySend)="copy($event)"
(removePassword)="removePassword($event)"
(deleteSend)="delete($event)"
/>
<div *ngIf="filteredSends && !filteredSends.length">
<ng-container *ngIf="!loaded">
<i
class="bwi bwi-spinner bwi-spin tw-text-muted"
title="{{ 'loading' | i18n }}"
aria-hidden="true"
></i>
<span class="tw-sr-only">{{ "loading" | i18n }}</span>
</ng-container>
<ng-container *ngIf="loaded">
<bit-no-items [icon]="noItemIcon" class="tw-text-main">
<ng-container slot="title">{{ "sendsTitleNoItems" | i18n }}</ng-container>
<ng-container slot="description">{{ "sendsBodyNoItems" | i18n }}</ng-container>
<tools-new-send-dropdown
[hideIcon]="true"
*ngIf="!disableSend"
slot="button"
></tools-new-send-dropdown>
</bit-no-items>
</ng-container>
</div>
</div>
</div>
}

View File

@@ -1,7 +1,9 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Component, NgZone, OnInit, OnDestroy } from "@angular/core";
import { lastValueFrom } from "rxjs";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { ActivatedRoute, Router } from "@angular/router";
import { lastValueFrom, Observable, switchMap, EMPTY } from "rxjs";
import { SendComponent as BaseSendComponent } from "@bitwarden/angular/tools/send/send.component";
import { NoSendsIcon } from "@bitwarden/assets/svg";
@@ -17,6 +19,8 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendFilterType } from "@bitwarden/common/tools/send/types/send-filter-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { SendId } from "@bitwarden/common/types/guid";
import { SearchService } from "@bitwarden/common/vault/abstractions/search.service";
import {
@@ -26,6 +30,7 @@ import {
SearchModule,
TableDataSource,
ToastService,
ToggleGroupModule,
} from "@bitwarden/components";
import {
DefaultSendFormConfigService,
@@ -53,6 +58,7 @@ const BroadcasterSubscriptionId = "SendComponent";
NoItemsModule,
HeaderModule,
NewSendDropdownComponent,
ToggleGroupModule,
SendTableComponent,
],
templateUrl: "send.component.html",
@@ -61,6 +67,8 @@ const BroadcasterSubscriptionId = "SendComponent";
export class SendComponent extends BaseSendComponent implements OnInit, OnDestroy {
private sendItemDialogRef?: DialogRef<SendItemDialogResult> | undefined;
noItemIcon = NoSendsIcon;
selectedToggleValue?: SendFilterType;
SendUIRefresh$: Observable<boolean>;
override set filteredSends(filteredSends: SendView[]) {
super.filteredSends = filteredSends;
@@ -88,6 +96,8 @@ export class SendComponent extends BaseSendComponent implements OnInit, OnDestro
toastService: ToastService,
private addEditFormConfigService: DefaultSendFormConfigService,
accountService: AccountService,
private route: ActivatedRoute,
private router: Router,
private configService: ConfigService,
) {
super(
@@ -104,10 +114,38 @@ export class SendComponent extends BaseSendComponent implements OnInit, OnDestro
toastService,
accountService,
);
this.SendUIRefresh$ = this.configService.getFeatureFlag$(FeatureFlag.SendUIRefresh);
this.SendUIRefresh$.pipe(
switchMap((sendUiRefreshEnabled) => {
if (sendUiRefreshEnabled) {
return this.route.queryParamMap;
}
return EMPTY;
}),
takeUntilDestroyed(),
).subscribe((params) => {
const typeParam = params.get("type");
const value = (
typeParam === SendFilterType.Text || typeParam === SendFilterType.File
? typeParam
: SendFilterType.All
) as SendFilterType;
this.selectedToggleValue = value;
if (this.loaded) {
this.applyTypeFilter(value);
}
});
}
async ngOnInit() {
await super.ngOnInit();
this.onSuccessfulLoad = async () => {
this.applyTypeFilter(this.selectedToggleValue);
};
await this.load();
// Broadcaster subscription - load if sync completes in the background
@@ -194,4 +232,28 @@ export class SendComponent extends BaseSendComponent implements OnInit, OnDestro
});
}
}
private applyTypeFilter(value: SendFilterType) {
if (value === SendFilterType.All) {
this.selectAll();
} else if (value === SendFilterType.Text) {
this.selectType(SendType.Text);
} else if (value === SendFilterType.File) {
this.selectType(SendType.File);
}
}
onToggleChange(value: SendFilterType) {
const queryParams = value === SendFilterType.All ? { type: null } : { type: value };
this.router
.navigate([], {
relativeTo: this.route,
queryParams,
queryParamsHandling: "merge",
})
.catch((err) => {
this.logService.error("Failed to update route query params:", err);
});
}
}

View File

@@ -5,8 +5,8 @@ import { ActiveSendIcon } from "@bitwarden/assets/svg";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { DIALOG_DATA, DialogModule, ToastService, TypographyModule } from "@bitwarden/components";
import { SharedModule } from "@bitwarden/web-vault/app/shared";

View File

@@ -27,13 +27,13 @@ import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/pl
import { StateService } from "@bitwarden/common/platform/abstractions/state.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
import { EncArrayBuffer } from "@bitwarden/common/platform/models/domain/enc-array-buffer";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { Send } from "@bitwarden/common/tools/send/models/domain/send";
import { SendFileView } from "@bitwarden/common/tools/send/models/view/send-file.view";
import { SendTextView } from "@bitwarden/common/tools/send/models/view/send-text.view";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { DialogService, ToastService } from "@bitwarden/components";

View File

@@ -20,10 +20,10 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { SearchService } from "@bitwarden/common/vault/abstractions/search.service";
import { DialogService, ToastService } from "@bitwarden/components";
@@ -78,7 +78,7 @@ export class SendComponent implements OnInit, OnDestroy {
protected ngZone: NgZone,
protected searchService: SearchService,
protected policyService: PolicyService,
private logService: LogService,
protected logService: LogService,
protected sendApiService: SendApiService,
protected dialogService: DialogService,
protected toastService: ToastService,

View File

@@ -1,6 +1,6 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendResponse } from "../response/send.response";
import { SendFileData } from "./send-file.data";

View File

@@ -1,7 +1,7 @@
import { mock } from "jest-mock-extended";
import { mockContainerService, mockEnc } from "../../../../../spec";
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendAccessResponse } from "../response/send-access.response";
import { SendAccess } from "./send-access";

View File

@@ -3,7 +3,7 @@
import { EncString } from "../../../../key-management/crypto/models/enc-string";
import Domain from "../../../../platform/models/domain/domain-base";
import { SymmetricCryptoKey } from "../../../../platform/models/domain/symmetric-crypto-key";
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendAccessResponse } from "../response/send-access.response";
import { SendAccessView } from "../view/send-access.view";

View File

@@ -11,7 +11,7 @@ import { EncryptService } from "../../../../key-management/crypto/abstractions/e
import { SymmetricCryptoKey } from "../../../../platform/models/domain/symmetric-crypto-key";
import { ContainerService } from "../../../../platform/services/container.service";
import { UserKey } from "../../../../types/key";
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendData } from "../data/send.data";
import { Send } from "./send";

View File

@@ -8,7 +8,7 @@ import { UserId } from "@bitwarden/common/types/guid";
import { EncString } from "../../../../key-management/crypto/models/enc-string";
import { Utils } from "../../../../platform/misc/utils";
import Domain from "../../../../platform/models/domain/domain-base";
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendData } from "../data/send.data";
import { SendView } from "../view/send.view";

View File

@@ -1,6 +1,6 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendFileApi } from "../api/send-file.api";
import { SendTextApi } from "../api/send-text.api";
import { Send } from "../domain/send";

View File

@@ -1,7 +1,7 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { BaseResponse } from "../../../../models/response/base.response";
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendFileApi } from "../api/send-file.api";
import { SendTextApi } from "../api/send-text.api";

View File

@@ -1,7 +1,7 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { BaseResponse } from "../../../../models/response/base.response";
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendFileApi } from "../api/send-file.api";
import { SendTextApi } from "../api/send-text.api";

View File

@@ -1,7 +1,7 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { View } from "../../../../models/view/view";
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { SendAccess } from "../domain/send-access";
import { SendFileView } from "./send-file.view";

View File

@@ -4,7 +4,7 @@ import { View } from "../../../../models/view/view";
import { Utils } from "../../../../platform/misc/utils";
import { SymmetricCryptoKey } from "../../../../platform/models/domain/symmetric-crypto-key";
import { DeepJsonify } from "../../../../types/deep-jsonify";
import { SendType } from "../../enums/send-type";
import { SendType } from "../../types/send-type";
import { Send } from "../domain/send";
import { SendFileView } from "./send-file.view";

View File

@@ -6,7 +6,6 @@ import {
FileUploadService,
} from "../../../platform/abstractions/file-upload/file-upload.service";
import { EncArrayBuffer } from "../../../platform/models/domain/enc-array-buffer";
import { SendType } from "../enums/send-type";
import { SendData } from "../models/data/send.data";
import { Send } from "../models/domain/send";
import { SendAccessRequest } from "../models/request/send-access.request";
@@ -16,6 +15,7 @@ import { SendFileDownloadDataResponse } from "../models/response/send-file-downl
import { SendFileUploadDataResponse } from "../models/response/send-file-upload-data.response";
import { SendResponse } from "../models/response/send.response";
import { SendAccessView } from "../models/view/send-access.view";
import { SendType } from "../types/send-type";
import { SendApiService as SendApiServiceAbstraction } from "./send-api.service.abstraction";
import { InternalSendService } from "./send.service.abstraction";

View File

@@ -24,13 +24,13 @@ import { ContainerService } from "../../../platform/services/container.service";
import { SelfHostedEnvironment } from "../../../platform/services/default-environment.service";
import { UserId } from "../../../types/guid";
import { UserKey } from "../../../types/key";
import { SendType } from "../enums/send-type";
import { SendFileApi } from "../models/api/send-file.api";
import { SendTextApi } from "../models/api/send-text.api";
import { SendFileData } from "../models/data/send-file.data";
import { SendTextData } from "../models/data/send-text.data";
import { SendData } from "../models/data/send.data";
import { SendView } from "../models/view/send.view";
import { SendType } from "../types/send-type";
import { SEND_USER_DECRYPTED, SEND_USER_ENCRYPTED } from "./key-definitions";
import { SendStateProvider } from "./send-state.provider";

View File

@@ -16,7 +16,6 @@ import { EncArrayBuffer } from "../../../platform/models/domain/enc-array-buffer
import { SymmetricCryptoKey } from "../../../platform/models/domain/symmetric-crypto-key";
import { UserId } from "../../../types/guid";
import { UserKey } from "../../../types/key";
import { SendType } from "../enums/send-type";
import { SendData } from "../models/data/send.data";
import { Send } from "../models/domain/send";
import { SendFile } from "../models/domain/send-file";
@@ -24,6 +23,7 @@ import { SendText } from "../models/domain/send-text";
import { SendWithIdRequest } from "../models/request/send-with-id.request";
import { SendView } from "../models/view/send.view";
import { SEND_KDF_ITERATIONS } from "../send-kdf";
import { SendType } from "../types/send-type";
import { SendStateProvider } from "./send-state.provider.abstraction";
import { InternalSendService as InternalSendServiceAbstraction } from "./send.service.abstraction";

View File

@@ -1,12 +1,12 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { EncString } from "../../../../key-management/crypto/models/enc-string";
import { SendType } from "../../enums/send-type";
import { SendTextApi } from "../../models/api/send-text.api";
import { SendTextData } from "../../models/data/send-text.data";
import { SendData } from "../../models/data/send.data";
import { Send } from "../../models/domain/send";
import { SendView } from "../../models/view/send.view";
import { SendType } from "../../types/send-type";
export function testSendViewData(id: string, name: string) {
const data = new SendView({} as any);

View File

@@ -0,0 +1,7 @@
export const SendFilterType = Object.freeze({
All: "all",
Text: "text",
File: "file",
} as const);
export type SendFilterType = (typeof SendFilterType)[keyof typeof SendFilterType];

View File

@@ -6,9 +6,9 @@ import { FormsModule } from "@angular/forms";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import {
DIALOG_DATA,
DialogRef,

View File

@@ -5,7 +5,7 @@ import { BehaviorSubject, of } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { NewSendDropdownV2Component } from "./new-send-dropdown-v2.component";

View File

@@ -6,7 +6,7 @@ import { PremiumBadgeComponent } from "@bitwarden/angular/billing/components/pre
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { ButtonModule, ButtonType, MenuModule } from "@bitwarden/components";

View File

@@ -7,7 +7,7 @@ import { PremiumBadgeComponent } from "@bitwarden/angular/billing/components/pre
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { ButtonModule, ButtonType, MenuModule } from "@bitwarden/components";

View File

@@ -1,5 +1,5 @@
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { Send } from "@bitwarden/common/tools/send/models/domain/send";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { SendId } from "@bitwarden/common/types/guid";
/**

View File

@@ -6,9 +6,9 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
import { Account, AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { DialogService, ToastService } from "@bitwarden/components";
import { CredentialGeneratorService } from "@bitwarden/generator-core";

View File

@@ -9,8 +9,8 @@ import { firstValueFrom } from "rxjs";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { EnvironmentService } from "@bitwarden/common/platform/abstractions/environment.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import {
SectionComponent,
SectionHeaderComponent,

View File

@@ -4,9 +4,9 @@ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { FormBuilder, Validators, ReactiveFormsModule, FormsModule } from "@angular/forms";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendFileView } from "@bitwarden/common/tools/send/models/view/send-file.view";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import {
ButtonModule,
FormFieldModule,

View File

@@ -18,8 +18,8 @@ import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { FormBuilder, ReactiveFormsModule } from "@angular/forms";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import {
AsyncActionsModule,
BitSubmitDirective,

View File

@@ -7,8 +7,8 @@ import { PolicyService } from "@bitwarden/common/admin-console/abstractions/poli
import { PolicyType } from "@bitwarden/common/admin-console/enums";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendService } from "@bitwarden/common/tools/send/services/send.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { SendId } from "@bitwarden/common/types/guid";
import {

View File

@@ -10,9 +10,9 @@ import { EnvironmentService } from "@bitwarden/common/platform/abstractions/envi
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendApiService } from "@bitwarden/common/tools/send/services/send-api.service.abstraction";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import {
BadgeModule,
ButtonModule,

View File

@@ -1,8 +1,8 @@
import { Meta, StoryObj, moduleMetadata } from "@storybook/angular";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { TableDataSource, I18nMockService } from "@bitwarden/components";
import { SendTableComponent } from "./send-table.component";

View File

@@ -2,8 +2,8 @@ import { CommonModule } from "@angular/common";
import { ChangeDetectionStrategy, Component, input, output } from "@angular/core";
import { JslibModule } from "@bitwarden/angular/jslib.module";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import {
BadgeModule,
ButtonModule,

View File

@@ -4,8 +4,8 @@ import { BehaviorSubject } from "rxjs";
import { PolicyService } from "@bitwarden/common/admin-console/abstractions/policy/policy.service.abstraction";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { SendListFiltersService } from "./send-list-filters.service";

View File

@@ -5,8 +5,8 @@ import { FormBuilder } from "@angular/forms";
import { map, Observable, startWith } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { SendType } from "@bitwarden/common/tools/send/enums/send-type";
import { SendView } from "@bitwarden/common/tools/send/models/view/send.view";
import { SendType } from "@bitwarden/common/tools/send/types/send-type";
import { ITreeNodeObject, TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
import { ChipSelectOption } from "@bitwarden/components";