ui elements for add cipher

This commit is contained in:
Kyle Spearrin 2018-01-25 16:15:47 -05:00
parent 8840f07032
commit f5459f4c85
5 changed files with 323 additions and 18 deletions

View File

@ -8,7 +8,7 @@ import { LoginComponent } from './accounts/login.component';
import { VaultComponent } from './vault/vault.component'; import { VaultComponent } from './vault/vault.component';
const routes: Routes = [ const routes: Routes = [
{ path: '', redirectTo: '/login', pathMatch: 'full' }, { path: '', redirectTo: '/vault', pathMatch: 'full' },
{ path: 'login', component: LoginComponent }, { path: 'login', component: LoginComponent },
{ path: 'vault', component: VaultComponent }, { path: 'vault', component: VaultComponent },
]; ];

View File

@ -1,31 +1,163 @@
<div class="content"> <div class="content">
<div class="inner-content"> <div class="inner-content" *ngIf="cipher">
<div class="box"> <div class="box">
<div class="box-header"> <div class="box-header">
{{'itemInformation' | i18n}} {{'itemInformation' | i18n}}
</div> </div>
<div class="box-content" *ngIf="cipher"> <div class="box-content">
<div class="box-content-row"> <div class="box-content-row">
<span class="row-label">{{'name' | i18n}}</span> <label for="type">{{'type' | i18n}}</label>
{{cipher.name}} <select id="type" name="Type" [(ngModel)]="cipher.type">
<option *ngFor="let o of typeOptions" [ngValue]="o.value">{{o.name}}</option>
</select>
</div> </div>
<div *ngIf="cipher.login"> <div class="box-content-row">
<label for="name">{{'name' | i18n}}</label>
<input id="name" type="text" name="Name" [(ngModel)]="cipher.name">
</div>
<!-- Login -->
<div *ngIf="cipher.type === cipherType.Login">
<div class="box-content-row"> <div class="box-content-row">
<span class="row-label">{{'uri' | i18n}}</span> <label for="loginUri">{{'uri' | i18n}}</label>
{{cipher.login.uri}} <input id="loginUri" type="text" name="Login.Uri" [(ngModel)]="cipher.login.uri">
</div> </div>
<div class="box-content-row"> <div class="box-content-row">
<span class="row-label">{{'username' | i18n}}</span> <label for="loginUsername">{{'username' | i18n}}</label>
{{cipher.login.username}} <input id="loginUsername" type="text" name="Login.Username"
[(ngModel)]="cipher.login.username">
</div> </div>
<div class="box-content-row"> <div class="box-content-row">
<span class="row-label">{{'password' | i18n}}</span> <label for="loginPassword">{{'password' | i18n}}</label>
{{cipher.login.password}} <input id="loginPassword" type="text" name="Login.Password"
[(ngModel)]="cipher.login.password">
</div>
<a class="box-content-row" href="#" appStopClick (click)="generatePassword()">
{{'generatePassword' | i18n}}
<i class="fa fa-chevron-right icon-right"></i>
</a>
</div>
<!-- Card -->
<div *ngIf="cipher.type === cipherType.Card">
<div class="box-content-row">
<label for="cardCardholderName">{{'cardholderName' | i18n}}</label>
<input id="cardCardholderName" type="text" name="Card.CardCardholderName"
[(ngModel)]="cipher.card.cardholderName">
</div>
<div class="box-content-row">
<label for="cardNumber">{{'number' | i18n}}</label>
<input id="cardNumber" type="text" name="Card.Number" [(ngModel)]="cipher.card.number">
</div>
<div class="box-content-row">
<label for="cardBrand">{{'brand' | i18n}}</label>
<select id="cardBrand" name="Card.Brand" [(ngModel)]="cipher.card.brand">
<option *ngFor="let o of cardBrandOptions" [ngValue]="o.value">{{o.name}}</option>
</select>
</div>
<div class="box-content-row">
<label for="cardExpMonth">{{'expirationMonth' | i18n}}</label>
<select id="cardExpMonth" name="Card.ExpMonth" [(ngModel)]="cipher.card.expMonth">
<option *ngFor="let o of cardExpMonthOptions" [ngValue]="o.value">{{o.name}}</option>
</select>
</div>
<div class="box-content-row">
<label for="cardExpYear">{{'expirationYear' | i18n}}</label>
<input id="cardExpYear" type="text" name="Card.ExpYear" [(ngModel)]="cipher.card.expYear"
placeholder="{{'ex' | i18n}} 2019">
</div>
<div class="box-content-row">
<label for="cardCode">{{'securityCode' | i18n}}</label>
<input id="cardCode" type="text" name="Card.Code" [(ngModel)]="cipher.card.code">
</div>
</div>
<!-- Identity -->
<div *ngIf="cipher.type === cipherType.Identity">
<div class="box-content-row">
<label for="idTitle">{{'title' | i18n}}</label>
<select id="idTitle" name="Identity.Title" [(ngModel)]="cipher.identity.title">
<option *ngFor="let o of identityTitleOptions" [ngValue]="o.value">{{o.name}}</option>
</select>
</div>
<div class="box-content-row">
<label for="idFirstName">{{'firstName' | i18n}}</label>
<input id="idFirstName" type="text" name="Identity.FirstName"
[(ngModel)]="cipher.identity.firstName">
</div>
<div class="box-content-row">
<label for="idMiddleName">{{'middleName' | i18n}}</label>
<input id="idMiddleName" type="text" name="Identity.MiddleName"
[(ngModel)]="cipher.identity.middleName">
</div>
<div class="box-content-row">
<label for="idLastName">{{'lastName' | i18n}}</label>
<input id="idLastName" type="text" name="Identity.LastName"
[(ngModel)]="cipher.identity.lastName">
</div>
<div class="box-content-row">
<label for="idUsername">{{'username' | i18n}}</label>
<input id="idUsername" type="text" name="Identity.Username"
[(ngModel)]="cipher.identity.username">
</div>
<div class="box-content-row">
<label for="idCompany">{{'company' | i18n}}</label>
<input id="idCompany" type="text" name="Identity.Company"
[(ngModel)]="cipher.identity.company">
</div>
<div class="box-content-row">
<label for="idSsn">{{'ssn' | i18n}}</label>
<input id="idSsn" type="text" name="Identity.SSN" [(ngModel)]="cipher.identity.ssn">
</div>
<div class="box-content-row">
<label for="idPassportNumber">{{'passportNumber' | i18n}}</label>
<input id="idPassportNumber" type="text" name="Identity.PassportNumber"
[(ngModel)]="cipher.identity.passportNumber">
</div>
<div class="box-content-row">
<label for="idLicenseNumber">{{'licenseNumber' | i18n}}</label>
<input id="idLicenseNumber" type="text" name="Identity.LicenseNumber"
[(ngModel)]="cipher.identity.licenseNumber">
</div>
<div class="box-content-row">
<label for="idEmail">{{'email' | i18n}}</label>
<input id="idEmail" type="text" name="Identity.Email" [(ngModel)]="cipher.identity.email">
</div>
<div class="box-content-row">
<label for="idPhone">{{'phone' | i18n}}</label>
<input id="idPhone" type="text" name="Identity.Phone" [(ngModel)]="cipher.identity.phone">
</div>
<div class="box-content-row">
<label for="idAddress1">{{'address1' | i18n}}</label>
<input id="idAddress1" type="text" name="Identity.Address1"
[(ngModel)]="cipher.identity.address1">
</div>
<div class="box-content-row">
<label for="idAddress2">{{'address2' | i18n}}</label>
<input id="idAddress2" type="text" name="Identity.Address2"
[(ngModel)]="cipher.identity.address2">
</div>
<div class="box-content-row">
<label for="idAddress3">{{'address3' | i18n}}</label>
<input id="idAddress3" type="text" name="Identity.Address3"
[(ngModel)]="cipher.identity.address3">
</div>
<div class="box-content-row">
<label for="idCity">{{'cityTown' | i18n}}</label>
<input id="idCity" type="text" name="Identity.City" [(ngModel)]="cipher.identity.city">
</div>
<div class="box-content-row">
<label for="idState">{{'stateProvince' | i18n}}</label>
<input id="idState" type="text" name="Identity.State" [(ngModel)]="cipher.identity.state">
</div>
<div class="box-content-row">
<label for="idPostalCode">{{'zipPostalCode' | i18n}}</label>
<input id="idPostalCode" type="text" name="Identity.PostalCode"
[(ngModel)]="cipher.identity.postalCode">
</div>
<div class="box-content-row">
<label for="idCountry">{{'country' | i18n}}</label>
<input id="idCountry" type="text" name="Identity.Country"
[(ngModel)]="cipher.identity.country">
</div> </div>
</div> </div>
</div>
<div class="box-footer">
Some footer information for add.
</div> </div>
</div> </div>
</div> </div>

View File

@ -7,12 +7,16 @@ import {
} from '@angular/core'; } from '@angular/core';
import { CipherType } from 'jslib/enums/cipherType'; import { CipherType } from 'jslib/enums/cipherType';
import { FieldType } from 'jslib/enums/fieldType';
import { SecureNoteType } from 'jslib/enums/secureNoteType'; import { SecureNoteType } from 'jslib/enums/secureNoteType';
import { CipherService } from 'jslib/abstractions/cipher.service'; import { CipherService } from 'jslib/abstractions/cipher.service';
import { FolderService } from 'jslib/abstractions/folder.service';
import { I18nService } from 'jslib/abstractions/i18n.service';
import { CardView } from 'jslib/models/view/cardView'; import { CardView } from 'jslib/models/view/cardView';
import { CipherView } from 'jslib/models/view/cipherView'; import { CipherView } from 'jslib/models/view/cipherView';
import { FolderView } from 'jslib/models/view/folderView';
import { IdentityView } from 'jslib/models/view/identityView'; import { IdentityView } from 'jslib/models/view/identityView';
import { LoginView } from 'jslib/models/view/loginView'; import { LoginView } from 'jslib/models/view/loginView';
import { SecureNoteView } from 'jslib/models/view/secureNoteView'; import { SecureNoteView } from 'jslib/models/view/secureNoteView';
@ -24,8 +28,56 @@ import { SecureNoteView } from 'jslib/models/view/secureNoteView';
export class AddComponent implements OnChanges { export class AddComponent implements OnChanges {
@Input() folderId: string; @Input() folderId: string;
cipher: CipherView; cipher: CipherView;
folders: FolderView[];
cipherType = CipherType;
fieldType = FieldType;
typeOptions: any[];
cardBrandOptions: any[];
cardExpMonthOptions: any[];
identityTitleOptions: any[];
constructor(private cipherService: CipherService) { constructor(private cipherService: CipherService, private folderService: FolderService,
private i18nService: I18nService) {
this.typeOptions = [
{ name: i18nService.t('typeLogin'), value: CipherType.Login },
{ name: i18nService.t('typeCard'), value: CipherType.Card },
{ name: i18nService.t('typeIdentity'), value: CipherType.Identity },
{ name: i18nService.t('typeSecureNote'), value: CipherType.SecureNote },
];
this.cardBrandOptions = [
{ name: '-- ' + i18nService.t('select') + ' --', value: null },
{ name: 'Visa', value: 'Visa' },
{ name: 'Mastercard', value: 'Mastercard' },
{ name: 'American Express', value: 'Amex' },
{ name: 'Discover', value: 'Discover' },
{ name: 'Diners Club', value: 'Diners Club' },
{ name: 'JCB', value: 'JCB' },
{ name: 'Maestro', value: 'Maestro' },
{ name: 'UnionPay', value: 'UnionPay' },
{ name: i18nService.t('other'), value: 'Other' },
];
this.cardExpMonthOptions = [
{ name: '-- ' + i18nService.t('select') + ' --', value: null },
{ name: '01 - ' + i18nService.t('january'), value: '1' },
{ name: '02 - ' + i18nService.t('february'), value: '2' },
{ name: '03 - ' + i18nService.t('march'), value: '3' },
{ name: '04 - ' + i18nService.t('april'), value: '4' },
{ name: '05 - ' + i18nService.t('may'), value: '5' },
{ name: '06 - ' + i18nService.t('june'), value: '6' },
{ name: '07 - ' + i18nService.t('july'), value: '7' },
{ name: '08 - ' + i18nService.t('august'), value: '8' },
{ name: '09 - ' + i18nService.t('september'), value: '9' },
{ name: '10 - ' + i18nService.t('october'), value: '10' },
{ name: '11 - ' + i18nService.t('november'), value: '11' },
{ name: '12 - ' + i18nService.t('december'), value: '12' },
];
this.identityTitleOptions = [
{ name: '-- ' + i18nService.t('select') + ' --', value: null },
{ name: i18nService.t('mr'), value: i18nService.t('mr') },
{ name: i18nService.t('mrs'), value: i18nService.t('mrs') },
{ name: i18nService.t('ms'), value: i18nService.t('ms') },
{ name: i18nService.t('dr'), value: i18nService.t('dr') },
];
} }
async ngOnChanges() { async ngOnChanges() {
@ -37,5 +89,7 @@ export class AddComponent implements OnChanges {
this.cipher.identity = new IdentityView(); this.cipher.identity = new IdentityView();
this.cipher.secureNote = new SecureNoteView(); this.cipher.secureNote = new SecureNoteView();
this.cipher.secureNote.type = SecureNoteType.Generic; this.cipher.secureNote.type = SecureNoteType.Generic;
this.folders = await this.folderService.getAllDecrypted();
} }
} }

View File

@ -142,5 +142,107 @@
}, },
"error": { "error": {
"message": "Error" "message": "Error"
},
"january": {
"message": "January"
},
"february": {
"message": "February"
},
"march": {
"message": "March"
},
"april": {
"message": "April"
},
"may": {
"message": "May"
},
"june": {
"message": "June"
},
"july": {
"message": "July"
},
"august": {
"message": "August"
},
"september": {
"message": "September"
},
"october": {
"message": "October"
},
"november": {
"message": "November"
},
"december": {
"message": "December"
},
"ex": {
"message": "ex."
},
"title": {
"message": "Title"
},
"mr": {
"message": "Mr"
},
"mrs": {
"message": "Mrs"
},
"ms": {
"message": "Ms"
},
"dr": {
"message": "Dr"
},
"expirationMonth": {
"message": "Expiration Month"
},
"expirationYear": {
"message": "Expiration Year"
},
"select": {
"message": "Select"
},
"other": {
"message": "Other"
},
"generatePassword": {
"message": "Generate Password"
},
"type": {
"message": "Type"
},
"firstName": {
"message": "First Name"
},
"middleName": {
"message": "Middle Name"
},
"lastName": {
"message": "Last Name"
},
"address1": {
"message": "Address 1"
},
"address2": {
"message": "Address 2"
},
"address3": {
"message": "Address 3"
},
"cityTown": {
"message": "City / Town"
},
"stateProvince": {
"message": "State / Province"
},
"zipPostalCode": {
"message": "Zip / Postal Code"
},
"country": {
"message": "Country"
} }
} }

View File

@ -635,7 +635,7 @@ a {
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.row-label { .row-label, label {
font-size: $font-size-small; font-size: $font-size-small;
color: $text-muted; color: $text-muted;
display: block; display: block;
@ -644,7 +644,24 @@ a {
margin-bottom: 5px; margin-bottom: 5px;
} }
input { input:not([type="checkbox"]), select, textarea {
border: none;
width: 100%;
background-color: transparent;
font-size: $font-size-base;
&::-webkit-input-placeholder {
color: lighten($gray-light, 35%);
}
&:focus {
outline: none;
}
}
input[type="checkbox"] {
float: right;
display: inline-block;
} }
.action-buttons { .action-buttons {