1
0
mirror of https://github.com/bitwarden/desktop.git synced 2024-11-24 11:55:50 +01:00

search ciphers and cleanup ciphers header

This commit is contained in:
Kyle Spearrin 2018-01-29 21:41:00 -05:00
parent ae37dc63ea
commit 6fbe640d15
5 changed files with 45 additions and 86 deletions

View File

@ -21,6 +21,7 @@ import { IconComponent } from './vault/icon.component';
import { LoginComponent } from './accounts/login.component'; import { LoginComponent } from './accounts/login.component';
import { ModalComponent } from './modal.component'; import { ModalComponent } from './modal.component';
import { PasswordGeneratorComponent } from './vault/password-generator.component'; import { PasswordGeneratorComponent } from './vault/password-generator.component';
import { SearchCiphersPipe } from './pipes/search-ciphers.pipe';
import { StopClickDirective } from './directives/stop-click.directive'; import { StopClickDirective } from './directives/stop-click.directive';
import { StopPropDirective } from './directives/stop-prop.directive'; import { StopPropDirective } from './directives/stop-prop.directive';
import { VaultComponent } from './vault/vault.component'; import { VaultComponent } from './vault/vault.component';
@ -51,6 +52,7 @@ import { ViewComponent } from './vault/view.component';
LoginComponent, LoginComponent,
ModalComponent, ModalComponent,
PasswordGeneratorComponent, PasswordGeneratorComponent,
SearchCiphersPipe,
StopClickDirective, StopClickDirective,
StopPropDirective, StopPropDirective,
VaultComponent, VaultComponent,

View File

@ -0,0 +1,36 @@
import {
Pipe,
PipeTransform,
} from '@angular/core';
import { CipherView } from 'jslib/models/view/cipherView';
@Pipe({
name: 'searchCiphers',
})
export class SearchCiphersPipe implements PipeTransform {
transform(ciphers: CipherView[], searchText: string): CipherView[] {
if (ciphers == null || ciphers.length === 0) {
return [];
}
if (searchText == null || searchText.length < 2) {
return ciphers;
}
searchText = searchText.toLowerCase();
return ciphers.filter(c => {
if (c.name != null && c.name.toLowerCase().indexOf(searchText) > -1) {
return true;
}
if (c.subTitle != null && c.subTitle.toLowerCase().indexOf(searchText) > -1) {
return true;
}
if (c.login && c.login.uri != null && c.login.uri.toLowerCase().indexOf(searchText) > -1) {
return true;
}
return false;
});
}
}

View File

@ -1,17 +1,12 @@
<div class="header header-search"> <div class="header header-search">
<div class="search"> <div class="search">
<input type="search" placeholder="{{'searchVault' | i18n}}" id="search" /> <input type="search" placeholder="{{'searchVault' | i18n}}" id="search" [(ngModel)]="searchText" />
<i class="fa fa-search"></i> <i class="fa fa-search"></i>
</div> </div>
<div class="right">
<a href="" title="{{'addItem' | i18n}}" appBlurClick appStopClick (click)="addCipher()">
<i class="fa fa-plus fa-lg"></i>
</a>
</div>
</div> </div>
<div class="content"> <div class="content">
<div class="list"> <div class="list">
<a *ngFor="let c of ciphers" appStopClick (click)="cipherClicked(c)" <a *ngFor="let c of ciphers | searchCiphers: searchText" appStopClick (click)="cipherClicked(c)"
href="#" title="{{'viewItem' | i18n}}" [ngClass]="{'active': c.id === activeCipherId}"> href="#" title="{{'viewItem' | i18n}}" [ngClass]="{'active': c.id === activeCipherId}">
<app-vault-icon [cipher]="c"></app-vault-icon> <app-vault-icon [cipher]="c"></app-vault-icon>
<span class="text"> <span class="text">

View File

@ -22,6 +22,7 @@ export class CiphersComponent implements OnInit {
@Output() onAddCipher = new EventEmitter(); @Output() onAddCipher = new EventEmitter();
ciphers: CipherView[] = []; ciphers: CipherView[] = [];
searchText: string;
private filter: (cipher: CipherView) => boolean = null; private filter: (cipher: CipherView) => boolean = null;
constructor(private cipherService: CipherService) { constructor(private cipherService: CipherService) {

View File

@ -140,90 +140,21 @@
min-height: 44px; min-height: 44px;
max-height: 44px; max-height: 44px;
background-color: $brand-primary; background-color: $brand-primary;
color: white;
text-align: center;
overflow: hidden;
flex: 0 0 auto; flex: 0 0 auto;
border-bottom: 1px solid darken($brand-primary, 7%); border-bottom: 1px solid darken($brand-primary, 7%);
display: flex;
a, button { align-items: center;
color: white !important;
text-decoration: none;
background: none;
&:hover, &:focus {
background-color: rgba(255, 255, 255, 0.1);
}
&:hover {
text-decoration: none;
}
&:focus {
text-decoration: underline;
}
}
.title {
font-weight: bold;
display: block;
padding: 12px 0;
text-align: center;
}
.left {
display: block;
position: absolute;
left: 0;
text-align: left;
a, button {
padding: 12px 10px;
display: block;
float: left;
}
.fa-spinner {
padding: 15px;
display: block;
float: left;
}
}
.right {
display: block;
right: 0;
position: absolute;
z-index: 99999;
a, button {
padding: 12px 10px;
display: block;
float: right;
}
.fa-spinner {
padding: 15px;
display: block;
float: right;
}
}
&.header-search { &.header-search {
.left, .right, .search {
display: table-cell;
position: relative;
}
.search { .search {
padding: 0 7px; padding: 0 7px;
width: 100%; width: 100%;
text-align: left; text-align: left;
position: relative; position: relative;
.fa-search { .fa {
position: absolute; position: absolute;
top: 15px; top: 7px;
left: 15px; left: 15px;
color: lighten($brand-primary, 30%); color: lighten($brand-primary, 30%);
} }
@ -231,7 +162,6 @@
input { input {
width: 100%; width: 100%;
margin: 0; margin: 0;
float: none;
background: darken($brand-primary, 8%); background: darken($brand-primary, 8%);
border: none; border: none;
color: white; color: white;
@ -249,11 +179,6 @@
} }
} }
} }
a {
white-space: nowrap;
float: none;
}
} }
} }