mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-21 21:11:35 +01:00
[PM-2804] Migrate Send List to Component Library (#5796)
* Migrate Send list html to use Component Library and TailWind * Added ComponentLibrary search module to Send * Updated the No-Items on Send List to the new CL * Added missing type on button at send.component.html * Changed send to standalone component on web * Moved no send icon to the consuming component * removed unnecessary href on send component html * Added sort to send list * Removed SendComponent from loose-components module and added on app module * Removed unnecessary click handler on send name button * Created own file for no-send icon * set icons folder as lowercase * Corrected no-send.icon import * Setting name as default sort on send list * Added extra height to no-send.icon and removed classes from bit-no-items title container * Removed the size small from options button
This commit is contained in:
parent
49549cc150
commit
7ef2acc11a
@ -9,6 +9,7 @@ import { AppComponent } from "./app.component";
|
||||
import { CoreModule } from "./core";
|
||||
import { OssRoutingModule } from "./oss-routing.module";
|
||||
import { OssModule } from "./oss.module";
|
||||
import { SendComponent } from "./tools/send/send.component";
|
||||
import { WildcardRoutingModule } from "./wildcard-routing.module";
|
||||
|
||||
@NgModule({
|
||||
@ -21,6 +22,7 @@ import { WildcardRoutingModule } from "./wildcard-routing.module";
|
||||
DragDropModule,
|
||||
LayoutModule,
|
||||
OssRoutingModule,
|
||||
SendComponent,
|
||||
WildcardRoutingModule, // Needs to be last to catch all non-existing routes
|
||||
],
|
||||
declarations: [AppComponent],
|
||||
|
@ -95,7 +95,6 @@ import { PasswordGeneratorHistoryComponent } from "../tools/password-generator-h
|
||||
import { AccessComponent } from "../tools/send/access.component";
|
||||
import { AddEditComponent as SendAddEditComponent } from "../tools/send/add-edit.component";
|
||||
import { EffluxDatesComponent as SendEffluxDatesComponent } from "../tools/send/efflux-dates.component";
|
||||
import { SendComponent } from "../tools/send/send.component";
|
||||
import { ToolsComponent } from "../tools/tools.component";
|
||||
import { PasswordRepromptComponent } from "../vault/components/password-reprompt.component";
|
||||
import { PremiumBadgeComponent } from "../vault/components/premium-badge.component";
|
||||
@ -199,7 +198,6 @@ import { SharedModule } from "./shared.module";
|
||||
SecurityKeysComponent,
|
||||
SelectableAvatarComponent,
|
||||
SendAddEditComponent,
|
||||
SendComponent,
|
||||
SendEffluxDatesComponent,
|
||||
SetPasswordComponent,
|
||||
SettingsComponent,
|
||||
@ -304,7 +302,6 @@ import { SharedModule } from "./shared.module";
|
||||
SecurityKeysComponent,
|
||||
SelectableAvatarComponent,
|
||||
SendAddEditComponent,
|
||||
SendComponent,
|
||||
SendEffluxDatesComponent,
|
||||
SetPasswordComponent,
|
||||
SettingsComponent,
|
||||
|
13
apps/web/src/app/tools/send/icons/no-send.icon.ts
Normal file
13
apps/web/src/app/tools/send/icons/no-send.icon.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { svgIcon } from "@bitwarden/components";
|
||||
|
||||
export const NoSend = svgIcon`
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="125" fill="none">
|
||||
<path class="tw-stroke-secondary-500" stroke-width="3" d="M13.425 11.994H5.99a4.311 4.311 0 0 0-4.311 4.312v62.09a4.311 4.311 0 0 0 4.311 4.311h40.09"/>
|
||||
<path class="tw-stroke-secondary-500" stroke-width="3" d="M66.27 75.142h-49.9a3.234 3.234 0 0 1-3.233-3.234V9.818a3.234 3.234 0 0 1 3.234-3.233h35.764a3.233 3.233 0 0 1 2.293.953l14.134 14.216c.602.605.94 1.425.94 2.28v47.874a3.233 3.233 0 0 1-3.233 3.234Z"/>
|
||||
<path class="tw-stroke-secondary-500" stroke-width="2" d="M47.021 35.586c0-3.818-2.728-6.915-6.095-6.915-3.367 0-6.096 3.097-6.096 6.915"/>
|
||||
<path class="tw-stroke-secondary-500 tw-fill-secondary-100" stroke-width="2" d="M47.38 35.335H34.058a3.593 3.593 0 0 0-3.593 3.592v9.817a3.593 3.593 0 0 0 3.593 3.593H47.38a3.593 3.593 0 0 0 3.593-3.593v-9.817a3.593 3.593 0 0 0-3.593-3.592Z"/>
|
||||
<path class="tw-stroke-secondary-500" stroke-linecap="round" stroke-width="2" d="M40.72 44.34v2.618"/>
|
||||
<path class="tw-stroke-secondary-500" stroke-linecap="round" stroke-width="4" d="M40.72 42.7v-.373"/>
|
||||
<path class="tw-stroke-secondary-500 tw-fill-secondary-100" stroke-width="3" d="M89.326 64.022s1.673-.73 2.252.572c.512 1.138-.822 2.033-.822 2.033L56.757 88.133a3.886 3.886 0 0 0-1.583 2.188l-4.732 16.705a2.665 2.665 0 0 0 .059 1.611 2.596 2.596 0 0 0 1.891 1.663c.331.07.673.071 1.004.004.402-.077.78-.25 1.102-.503l10.11-7.88a3.138 3.138 0 0 1 1.92-.663 3.08 3.08 0 0 1 1.905.662l13.926 10.948a2.556 2.556 0 0 0 3.162 0 2.71 2.71 0 0 0 .727-.879l31.777-61.762c.231-.448.33-.952.284-1.455a2.606 2.606 0 0 0-1.721-2.226 2.499 2.499 0 0 0-1.457-.06l-81.18 20.418c-.465.12-.888.364-1.223.708a2.672 2.672 0 0 0-.632 2.676c.146.46.417.865.78 1.174L46.2 83.1a4.463 4.463 0 0 0 2.565 1.572 4.489 4.489 0 0 0 2.984-.413l37.578-20.237Z"/>
|
||||
</svg>
|
||||
`;
|
@ -1,24 +1,22 @@
|
||||
<div class="container page-content">
|
||||
<app-callout type="warning" title="{{ 'sendDisabled' | i18n }}" *ngIf="disableSend">
|
||||
<span>{{ "sendDisabledWarning" | i18n }}</span>
|
||||
</app-callout>
|
||||
<div class="row">
|
||||
<div class="col-3 groupings">
|
||||
<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="groupings tw-col-span-3">
|
||||
<div class="card vault-filters">
|
||||
<div class="card-header d-flex">
|
||||
{{ "filters" | i18n }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<input
|
||||
type="search"
|
||||
placeholder="{{ searchPlaceholder || ('searchSends' | i18n) }}"
|
||||
id="search"
|
||||
class="form-control"
|
||||
[(ngModel)]="searchText"
|
||||
(input)="searchTextChanged()"
|
||||
autocomplete="off"
|
||||
appAutofocus
|
||||
/>
|
||||
<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 }">
|
||||
@ -64,9 +62,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-9">
|
||||
<div class="page-header d-flex">
|
||||
<h1>
|
||||
<div class="tw-col-span-9">
|
||||
<div class="tw-flex">
|
||||
<h1 bitTypography="h1">
|
||||
{{ "send" | i18n }}
|
||||
<small #actionSpinner [appApiAction]="actionPromise">
|
||||
<ng-container *ngIf="$any(actionSpinner).loading">
|
||||
@ -79,29 +77,38 @@
|
||||
</ng-container>
|
||||
</small>
|
||||
</h1>
|
||||
<div class="ml-auto d-flex">
|
||||
<div class="tw-ml-auto">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-outline-primary btn-sm"
|
||||
bitButton
|
||||
buttonType="primary"
|
||||
(click)="addSend()"
|
||||
[disabled]="disableSend"
|
||||
>
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>{{ "createSend" | i18n }}
|
||||
<i class="bwi bwi-plus bwi-fw" aria-hidden="true"></i>
|
||||
{{ "createSend" | i18n }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!--Listing Table-->
|
||||
<table class="table table-hover table-list" *ngIf="filteredSends && filteredSends.length">
|
||||
<tbody>
|
||||
<tr *ngFor="let s of filteredSends">
|
||||
<td class="table-list-icon">
|
||||
<div class="icon" aria-hidden="true">
|
||||
<bit-table [dataSource]="dataSource" *ngIf="filteredSends && filteredSends.length">
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell bitSortable="name" default>{{ "name" | i18n }}</th>
|
||||
<th bitCell bitSortable="deletionDate">{{ "deletionDate" | i18n }}</th>
|
||||
<th bitCell>{{ "options" | i18n }}</th>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<ng-template body let-rows$>
|
||||
<tr bitRow *ngFor="let s of rows$ | async">
|
||||
<td bitCell (click)="editSend(s)" class="tw-cursor-pointer">
|
||||
<span class="tw-mr-2" aria-hidden="true">
|
||||
<i class="bwi bwi-fw bwi-lg bwi-file" *ngIf="s.type == sendType.File"></i>
|
||||
<i class="bwi bwi-fw bwi-lg bwi-file-text" *ngIf="s.type == sendType.Text"></i>
|
||||
</div>
|
||||
</td>
|
||||
<td class="reduced-lh wrap">
|
||||
<a href="#" appStopClick appStopProp (click)="editSend(s)">{{ s.name }}</a>
|
||||
</span>
|
||||
<button type="button" bitLink>
|
||||
{{ s.name }}
|
||||
</button>
|
||||
<ng-container *ngIf="s.disabled">
|
||||
<i
|
||||
class="bwi bwi-exclamation-triangle"
|
||||
@ -147,19 +154,19 @@
|
||||
></i>
|
||||
<span class="sr-only">{{ "pendingDeletion" | i18n }}</span>
|
||||
</ng-container>
|
||||
<br />
|
||||
<small appStopProp>{{ s.deletionDate | date : "medium" }}</small>
|
||||
</td>
|
||||
<td class="table-list-options">
|
||||
<td bitCell class="tw-text-muted" (click)="editSend(s)" class="tw-cursor-pointer">
|
||||
<small bitTypography="body2" appStopProp>{{
|
||||
s.deletionDate | date : "medium"
|
||||
}}</small>
|
||||
</td>
|
||||
<td bitCell class="tw-w-0 tw-text-right">
|
||||
<button
|
||||
type="button"
|
||||
[bitMenuTriggerFor]="sendOptions"
|
||||
class="tw-border-none tw-bg-transparent tw-text-main"
|
||||
type="button"
|
||||
bitIconButton="bwi-ellipsis-v"
|
||||
appA11yTitle="{{ 'options' | i18n }}"
|
||||
>
|
||||
<i class="bwi bwi-ellipsis-v bwi-lg" aria-hidden="true"></i>
|
||||
</button>
|
||||
></button>
|
||||
<bit-menu #sendOptions>
|
||||
<button type="button" bitMenuItem (click)="copy(s)">
|
||||
<i class="bwi bwi-fw bwi-clone" aria-hidden="true"></i>
|
||||
@ -183,8 +190,8 @@
|
||||
</bit-menu>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
<div class="no-items" *ngIf="filteredSends && !filteredSends.length">
|
||||
<ng-container *ngIf="!loaded">
|
||||
<i
|
||||
@ -195,16 +202,20 @@
|
||||
<span class="sr-only">{{ "loading" | i18n }}</span>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="loaded">
|
||||
<bit-icon [icon]="noItemIcon" aria-hidden="true"></bit-icon>
|
||||
<p>{{ "noSendsInList" | i18n }}</p>
|
||||
<button
|
||||
type="button"
|
||||
(click)="addSend()"
|
||||
class="btn btn-outline-primary"
|
||||
[disabled]="disableSend"
|
||||
>
|
||||
<i class="bwi bwi-plus bwi-fw"></i>{{ "createSend" | i18n }}
|
||||
</button>
|
||||
<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>
|
||||
<button
|
||||
slot="button"
|
||||
type="button"
|
||||
bitButton
|
||||
buttonType="secondary"
|
||||
(click)="addSend()"
|
||||
>
|
||||
<i class="bwi bwi-plus" aria-hidden="true"></i>
|
||||
{{ "createSend" | i18n }}
|
||||
</button>
|
||||
</bit-no-items>
|
||||
</ng-container>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -13,20 +13,36 @@ 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 { Icons } from "@bitwarden/components";
|
||||
import { NoItemsModule, SearchModule, TableDataSource } from "@bitwarden/components";
|
||||
|
||||
import { SharedModule } from "../../shared";
|
||||
|
||||
import { AddEditComponent } from "./add-edit.component";
|
||||
import { NoSend } from "./icons/no-send.icon";
|
||||
|
||||
const BroadcasterSubscriptionId = "SendComponent";
|
||||
|
||||
@Component({
|
||||
selector: "app-send",
|
||||
standalone: true,
|
||||
imports: [SharedModule, SearchModule, NoItemsModule],
|
||||
templateUrl: "send.component.html",
|
||||
})
|
||||
export class SendComponent extends BaseSendComponent {
|
||||
@ViewChild("sendAddEdit", { read: ViewContainerRef, static: true })
|
||||
sendAddEditModalRef: ViewContainerRef;
|
||||
noItemIcon = Icons.Search;
|
||||
noItemIcon = NoSend;
|
||||
|
||||
override set filteredSends(filteredSends: SendView[]) {
|
||||
super.filteredSends = filteredSends;
|
||||
this.dataSource.data = filteredSends;
|
||||
}
|
||||
|
||||
override get filteredSends() {
|
||||
return super.filteredSends;
|
||||
}
|
||||
|
||||
protected dataSource = new TableDataSource<SendView>();
|
||||
|
||||
constructor(
|
||||
sendService: SendService,
|
||||
|
@ -6955,6 +6955,14 @@
|
||||
"selectedRegionFlag": {
|
||||
"message": "Selected region flag"
|
||||
},
|
||||
"sendsNoItemsTitle": {
|
||||
"message": "No active Sends",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"sendsNoItemsMessage": {
|
||||
"message": "Use Send to securely share encrypted information with anyone.",
|
||||
"description": "'Send' is a noun and the name of a feature called 'Bitwarden Send'. It should not be translated."
|
||||
},
|
||||
"inviteUsers": {
|
||||
"message": "Invite Users"
|
||||
},
|
||||
|
@ -25,11 +25,9 @@ export class SendComponent implements OnInit, OnDestroy {
|
||||
expired = false;
|
||||
type: SendType = null;
|
||||
sends: SendView[] = [];
|
||||
filteredSends: SendView[] = [];
|
||||
searchText: string;
|
||||
selectedType: SendType;
|
||||
selectedAll: boolean;
|
||||
searchPlaceholder: string;
|
||||
filter: (cipher: SendView) => boolean;
|
||||
searchPending = false;
|
||||
hasSearched = false; // search() function called - returns true if text qualifies for search
|
||||
@ -41,6 +39,15 @@ export class SendComponent implements OnInit, OnDestroy {
|
||||
|
||||
private searchTimeout: any;
|
||||
private destroy$ = new Subject<void>();
|
||||
private _filteredSends: SendView[];
|
||||
|
||||
get filteredSends(): SendView[] {
|
||||
return this._filteredSends;
|
||||
}
|
||||
|
||||
set filteredSends(filteredSends: SendView[]) {
|
||||
this._filteredSends = filteredSends;
|
||||
}
|
||||
|
||||
constructor(
|
||||
protected sendService: SendService,
|
||||
|
Loading…
Reference in New Issue
Block a user