1
0
mirror of https://github.com/bitwarden/desktop.git synced 2024-12-25 16:47:55 +01:00

combine edit into add/edit component

This commit is contained in:
Kyle Spearrin 2018-01-26 14:56:54 -05:00
parent 298b12bf0d
commit eee5f6ff32
11 changed files with 94 additions and 110 deletions

View File

@ -10,10 +10,9 @@ import { NgModule } from '@angular/core';
import { ServicesModule } from './services/services.module';
import { ToasterModule } from 'angular2-toaster';
import { AddComponent } from './vault/add.component';
import { AddEditComponent } from './vault/add-edit.component';
import { AppComponent } from './app.component';
import { CiphersComponent } from './vault/ciphers.component';
import { EditComponent } from './vault/edit.component';
import { FallbackSrcDirective } from './directives/fallback-src.directive';
import { GroupingsComponent } from './vault/groupings.component';
import { I18nPipe } from './pipes/i18n.pipe';
@ -38,10 +37,9 @@ import { ViewComponent } from './vault/view.component';
ToasterModule,
],
declarations: [
AddComponent,
AddEditComponent,
AppComponent,
CiphersComponent,
EditComponent,
FallbackSrcDirective,
GroupingsComponent,
I18nPipe,

View File

@ -5,7 +5,7 @@
{{'itemInformation' | i18n}}
</div>
<div class="box-content">
<div class="box-content-row">
<div class="box-content-row" *ngIf="!editMode">
<label for="type">{{'type' | i18n}}</label>
<select id="type" name="Type" [(ngModel)]="cipher.type">
<option *ngFor="let o of typeOptions" [ngValue]="o.value">{{o.name}}</option>
@ -176,6 +176,10 @@
<label for="favorite">{{'favorite' | i18n}}</label>
<input id="favorite" type="checkbox" name="Favorite" [(ngModel)]="cipher.favorite">
</div>
<a class="box-content-row" href="#" appStopClick (click)="attachments()" *ngIf="editMode">
{{'attachments' | i18n}}
<i class="fa fa-chevron-right icon-right"></i>
</a>
</div>
</div>
<div class="box">
@ -233,7 +237,7 @@
<button (click)="cancel()" title="{{'cancel' | i18n}}">
{{'cancel' | i18n}}
</button>
<button (click)="delete()" class="danger right" title="{{'delete' | i18n}}">
<button (click)="delete()" class="danger right" title="{{'delete' | i18n}}" *ngIf="editMode">
<i class="fa fa-trash-o fa-lg"></i>
</button>
</div>

View File

@ -1,9 +1,11 @@
import * as template from './add.component.html';
import * as template from './add-edit.component.html';
import {
Component,
EventEmitter,
Input,
OnChanges,
Output,
} from '@angular/core';
import { Angulartics2 } from 'angulartics2';
@ -27,11 +29,17 @@ import { LoginView } from 'jslib/models/view/loginView';
import { SecureNoteView } from 'jslib/models/view/secureNoteView';
@Component({
selector: 'app-vault-add',
selector: 'app-vault-add-edit',
template: template,
})
export class AddComponent implements OnChanges {
export class AddEditComponent implements OnChanges {
@Input() folderId: string;
@Input() cipherId: string;
@Output() onSavedCipher = new EventEmitter<CipherView>();
@Output() onCancelled = new EventEmitter<CipherView>();
@Output() onEditAttachments = new EventEmitter<CipherView>();
editMode: boolean = false;
cipher: CipherView;
folders: FolderView[];
cipherType = CipherType;
@ -94,6 +102,13 @@ export class AddComponent implements OnChanges {
}
async ngOnChanges() {
this.editMode = this.cipherId != null;
if (this.editMode) {
this.editMode = true;
const cipher = await this.cipherService.get(this.cipherId);
this.cipher = await cipher.decrypt();
} else {
this.cipher = new CipherView();
this.cipher.folderId = null; // TODO
this.cipher.type = CipherType.Login;
@ -102,6 +117,7 @@ export class AddComponent implements OnChanges {
this.cipher.identity = new IdentityView();
this.cipher.secureNote = new SecureNoteView();
this.cipher.secureNote.type = SecureNoteType.Generic;
}
this.folders = await this.folderService.getAllDecrypted();
}
@ -115,8 +131,9 @@ export class AddComponent implements OnChanges {
const cipher = await this.cipherService.encrypt(this.cipher);
await this.cipherService.saveWithServer(cipher);
this.analytics.eventTrack.next({ action: 'Added Cipher' });
this.toasterService.popAsync('success', null, this.i18nService.t('addedItem'));
this.analytics.eventTrack.next({ action: this.editMode ? 'Edited Cipher' : 'Added Cipher' });
this.toasterService.popAsync('success', null, this.i18nService.t(this.editMode ? 'editedItem' : 'addedItem'));
this.onSavedCipher.emit(this.cipher);
};
addField() {
@ -135,4 +152,12 @@ export class AddComponent implements OnChanges {
this.cipher.fields.splice(i, 1);
}
};
cancel() {
this.onCancelled.emit(this.cipher);
};
attachments() {
this.onEditAttachments.emit(this.cipher);
};
}

View File

@ -15,11 +15,11 @@ import { CipherView } from 'jslib/models/view/cipherView';
})
export class CiphersComponent {
@Input() ciphers: CipherView[];
@Output() onCipherClicked = new EventEmitter<string>();
@Output() onCipherClicked = new EventEmitter<CipherView>();
@Output() onAddCipher = new EventEmitter();
cipherClicked(cipher: CipherView) {
this.onCipherClicked.emit(cipher.id);
this.onCipherClicked.emit(cipher);
}
addCipher() {

View File

@ -1,32 +0,0 @@
<div class="content">
<div class="inner-content">
<div class="box">
<div class="box-header">
{{'itemInformation' | i18n}}
</div>
<div class="box-content" *ngIf="cipher">
<div class="box-content-row">
<span class="row-label">{{'name' | i18n}}</span>
{{cipher.name}}
</div>
<div *ngIf="cipher.login">
<div class="box-content-row">
<span class="row-label">{{'uri' | i18n}}</span>
{{cipher.login.uri}}
</div>
<div class="box-content-row">
<span class="row-label">{{'username' | i18n}}</span>
{{cipher.login.username}}
</div>
<div class="box-content-row">
<span class="row-label">{{'password' | i18n}}</span>
{{cipher.login.password}}
</div>
</div>
</div>
</div>
</div>
</div>
<div class="footer">
{{'editItem' | i18n}}
</div>

View File

@ -1,35 +0,0 @@
import * as template from './edit.component.html';
import {
Component,
EventEmitter,
Input,
OnChanges,
Output,
} from '@angular/core';
import { CipherService } from 'jslib/abstractions/cipher.service';
import { CipherView } from 'jslib/models/view/cipherView';
@Component({
selector: 'app-vault-edit',
template: template,
})
export class EditComponent implements OnChanges {
@Input() cipherId: string;
@Output() onEditCipherClicked = new EventEmitter<string>();
cipher: CipherView;
constructor(private cipherService: CipherService) {
}
async ngOnChanges() {
const cipher = await this.cipherService.get(this.cipherId);
this.cipher = await cipher.decrypt();
}
editCipherClicked(id: string) {
this.onEditCipherClicked.emit(id);
}
}

View File

@ -11,12 +11,12 @@
[cipherId]="cipherId"
(onEditCipher)="editCipher($event)">
</app-vault-view>
<app-vault-edit id="details"
*ngIf="cipherId && action === 'edit'"
[cipherId]="cipherId">
</app-vault-edit>
<app-vault-add id="details"
*ngIf="action === 'add'"
[folderId]="null">
</app-vault-add>
<app-vault-add-edit id="details"
*ngIf="action === 'add' || action === 'edit'"
[folderId]="null"
[cipherId]="action === 'edit' ? cipherId : null"
(onSavedCipher)="savedCipher($event)"
(onEditAttachments)="editCipherAttachments($event)"
(onCancelled)="cancelledAddEdit($event)">
</app-vault-add-edit>
</div>

View File

@ -34,10 +34,12 @@ export class VaultComponent implements OnInit {
this.route.queryParams.subscribe((params) => {
if (params['cipherId']) {
const cipherView = new CipherView();
cipherView.id = params['cipherId'];
if (params['action'] === 'edit') {
this.editCipher(params['cipherId']);
this.editCipher(cipherView);
} else {
this.viewCipher(params['cipherId']);
this.viewCipher(cipherView);
}
} else if (params['action'] === 'add') {
this.addCipher();
@ -45,24 +47,24 @@ export class VaultComponent implements OnInit {
});
}
viewCipher(id: string) {
if (this.action === 'view' && this.cipherId === id) {
viewCipher(cipher: CipherView) {
if (this.action === 'view' && this.cipherId === cipher.id) {
return;
}
this.cipherId = id;
this.cipherId = cipher.id;
this.action = 'view';
this.go({ action: this.action, cipherId: id });
this.go({ action: this.action, cipherId: this.cipherId });
}
editCipher(id: string) {
if (this.action === 'edit' && this.cipherId === id) {
editCipher(cipher: CipherView) {
if (this.action === 'edit' && this.cipherId === cipher.id) {
return;
}
this.cipherId = id;
this.cipherId = cipher.id;
this.action = 'edit';
this.go({ action: this.action, cipherId: id });
this.go({ action: this.action, cipherId: this.cipherId });
}
addCipher() {
@ -71,7 +73,28 @@ export class VaultComponent implements OnInit {
}
this.action = 'add';
this.go({ action: this.action });
this.cipherId = null;
this.go({ action: this.action, cipherId: this.cipherId });
}
savedCipher(cipher: CipherView) {
this.cipherId = cipher.id;
this.action = 'view';
this.go({ action: this.action, cipherId: this.cipherId });
}
deletedCipher(cipher: CipherView) {
}
editCipherAttachments(cipher: CipherView) {
}
cancelledAddEdit(cipher: CipherView) {
this.cipherId = cipher.id;
this.action = this.cipherId != null ? 'view' : null;
this.go({ action: this.action, cipherId: this.cipherId });
}
private go(queryParams: any) {

View File

@ -32,7 +32,7 @@ import { FieldView } from 'jslib/models/view/fieldView';
})
export class ViewComponent implements OnChanges, OnDestroy {
@Input() cipherId: string;
@Output() onEditCipher = new EventEmitter<string>();
@Output() onEditCipher = new EventEmitter<CipherView>();
cipher: CipherView;
showPassword: boolean;
isPremium: boolean;
@ -75,7 +75,7 @@ export class ViewComponent implements OnChanges, OnDestroy {
}
edit() {
this.onEditCipher.emit(this.cipher.id);
this.onEditCipher.emit(this.cipher);
}
togglePassword() {

View File

@ -47,7 +47,7 @@
border-radius: $border-radius;
}
&:last-child {
&:last-child:not(.box-content-row-cf) {
&:before {
border: none;
height: 0;

View File

@ -73,6 +73,7 @@ a {
input, select, textarea, button {
font-size: $font-size-base;
font-family: $font-family-sans-serif;
}
textarea {