forked from hyperledger-archives/composer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract identity card component for use on login screen and (hyperled…
…ger-archives#1612) during identity card import Contributes to #902 Signed-off-by: James Taylor <[email protected]>
- Loading branch information
Showing
9 changed files
with
407 additions
and
135 deletions.
There are no files selected for viewing
47 changes: 47 additions & 0 deletions
47
packages/composer-playground/src/app/login/identity-card/identity-card.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<section class="identity-card"> | ||
<header> | ||
<button *ngIf="preview" type="button" class="icon dismiss" | ||
(click)="dismiss()"> | ||
<svg class="ibm-icon" aria-hidden="true"> | ||
<use xlink:href="#icon-close_new"></use> | ||
</svg> | ||
</button> | ||
</header> | ||
<section class="user-details"> | ||
<div class="image-placeholder"> | ||
<span class="initials">{{getInitials()}}</span> | ||
</div> | ||
<p>{{identity.userId}}</p> | ||
</section> | ||
<section *ngIf="!preview" class="actions"> | ||
<button type="button" class="action circular delete" | ||
(click)="delete()"> | ||
<svg class="ibm-icon vertical-top" aria-hidden="true"> | ||
<use xlink:href="#icon-trash_32"></use> | ||
</svg> | ||
</button> | ||
<button type="button" class="action circular export" | ||
(click)="export()"> | ||
<svg class="ibm-icon vertical-top" aria-hidden="true"> | ||
<use xlink:href="#icon-download_32"></use> | ||
</svg> | ||
</button> | ||
</section> | ||
<section *ngIf="preview" class="connection-profile-details"> | ||
<h3>Connection Profile</h3> | ||
<p>{{identity.profile}}</p> | ||
</section> | ||
<section class="business-network-details"> | ||
<h3>Business Network</h3> | ||
<p>{{identity.businessNetwork}}</p> | ||
</section> | ||
<footer> | ||
<button *ngIf="!preview" type="button" class="action connect" | ||
(click)="connect()"> | ||
<span>Connect now</span> | ||
<svg class="ibm-icon" aria-hidden="true"> | ||
<use xlink:href="#icon-forward_16"></use> | ||
</svg> | ||
</button> | ||
</footer> | ||
</section> |
117 changes: 117 additions & 0 deletions
117
packages/composer-playground/src/app/login/identity-card/identity-card.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
@import '../../../assets/styles/base/_colors.scss'; | ||
@import '../../../assets/styles/base/_variables.scss'; | ||
|
||
.composer { | ||
.identity-card { | ||
position: relative; | ||
background-color: $white; | ||
box-shadow: 3px 6px 15px 0 rgba(0, 0, 0, 0.20); | ||
margin-left: $space-large; | ||
margin-bottom: $space-large; | ||
width: 275px; | ||
|
||
section, footer { | ||
padding: 0 $space-large; | ||
} | ||
|
||
p { | ||
text-align: center; | ||
} | ||
|
||
h3 { | ||
text-align: center; | ||
text-transform: uppercase; | ||
color: $secondary-text; | ||
font-family: $font-stack; | ||
font-weight: 400; | ||
font-size: 0.9rem; | ||
font-size: x-small; | ||
} | ||
|
||
header { | ||
button.dismiss { | ||
position: absolute; | ||
top: 0; | ||
right: $space-smedium; | ||
|
||
svg { | ||
fill: $second-highlight; | ||
} | ||
} | ||
} | ||
|
||
footer { | ||
display: flex; | ||
justify-content: space-around; | ||
background-color: $white; | ||
border-top: 1px solid $fourth-highlight; | ||
|
||
button { | ||
display: flex; | ||
align-items: center; | ||
|
||
span { | ||
color: $second-highlight; | ||
margin-right: $space-smedium; | ||
} | ||
|
||
svg { | ||
// why is the align-self required for Safari?! | ||
align-self: center; | ||
fill: $second-highlight; | ||
} | ||
} | ||
} | ||
|
||
.user-details { | ||
padding-top: $space-large; | ||
|
||
p { | ||
font-weight: 600; | ||
} | ||
|
||
.image-placeholder { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-around; | ||
background-color: $fourth-highlight; | ||
border: 1px solid $fourth-highlight; | ||
border-radius: 50%; | ||
width: 75px; | ||
height: 75px; | ||
margin: 0 auto; | ||
position: relative; | ||
|
||
.initials { | ||
color: $second-highlight; | ||
font-weight: 600; | ||
font-size: xx-large; | ||
text-transform: uppercase; | ||
} | ||
} | ||
} | ||
|
||
.actions { | ||
display: flex; | ||
justify-content: center; | ||
padding-bottom: $space-smedium; | ||
|
||
button.delete { | ||
border-color: transparent; | ||
} | ||
|
||
button:first-child { | ||
margin-right: $space-large; | ||
} | ||
|
||
svg { | ||
fill: $second-highlight; | ||
} | ||
} | ||
|
||
.connection-profile-details, .business-network-details { | ||
padding-top: $space-medium; | ||
border-top: 1px solid $fourth-highlight; | ||
} | ||
} | ||
} |
154 changes: 154 additions & 0 deletions
154
packages/composer-playground/src/app/login/identity-card/identity-card.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; | ||
import { By } from '@angular/platform-browser'; | ||
|
||
import { IdentityCardComponent } from './identity-card.component'; | ||
|
||
import * as chai from 'chai'; | ||
import * as sinon from 'sinon'; | ||
|
||
let should = chai.should(); | ||
|
||
describe(`IdentityCardComponent`, () => { | ||
|
||
let component: IdentityCardComponent; | ||
let fixture: ComponentFixture<IdentityCardComponent>; | ||
|
||
let mockAdminService; | ||
let mockIdentityService; | ||
let mockClientService; | ||
let mockConnectionProfileService; | ||
let mockInitializationService; | ||
let routerStub; | ||
let mockAlertService; | ||
|
||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
declarations: [IdentityCardComponent] | ||
}); | ||
|
||
fixture = TestBed.createComponent(IdentityCardComponent); | ||
|
||
component = fixture.componentInstance; | ||
}); | ||
|
||
describe('#connect', () => { | ||
it('should emit connect event', (done) => { | ||
component.identity = { | ||
userId: 'pedantic-owl' | ||
}; | ||
|
||
component.onConnect.subscribe((e) => { | ||
e.should.equal('pedantic-owl'); | ||
done(); | ||
}); | ||
|
||
fixture.detectChanges(); | ||
let button = fixture.debugElement.query(By.css('button.connect')); | ||
button.nativeElement.click(); | ||
}); | ||
}); | ||
|
||
describe('#dismiss', () => { | ||
it('should emit dismiss event', (done) => { | ||
component.preview = true; | ||
component.identity = { | ||
userId: 'pedantic-owl' | ||
}; | ||
|
||
component.onDismiss.subscribe((e) => { | ||
e.should.equal('pedantic-owl'); | ||
done(); | ||
}); | ||
|
||
fixture.detectChanges(); | ||
let button = fixture.debugElement.query(By.css('button.dismiss')); | ||
button.nativeElement.click(); | ||
}); | ||
}); | ||
|
||
describe('#delete', () => { | ||
it('should emit delete event', (done) => { | ||
component.identity = { | ||
userId: 'pedantic-owl' | ||
}; | ||
|
||
component.onDelete.subscribe((e) => { | ||
e.should.equal('pedantic-owl'); | ||
done(); | ||
}); | ||
|
||
fixture.detectChanges(); | ||
let button = fixture.debugElement.query(By.css('button.delete')); | ||
button.nativeElement.click(); | ||
}); | ||
}); | ||
|
||
describe('#export', () => { | ||
it('should emit export event', (done) => { | ||
component.identity = { | ||
userId: 'pedantic-owl' | ||
}; | ||
|
||
component.onExport.subscribe((e) => { | ||
e.should.equal('pedantic-owl'); | ||
done(); | ||
}); | ||
|
||
fixture.detectChanges(); | ||
let button = fixture.debugElement.query(By.css('button.export')); | ||
button.nativeElement.click(); | ||
}); | ||
}); | ||
|
||
describe('#getInitials', () => { | ||
it('should get one initial', () => { | ||
component.identity = { | ||
userId: 'admin' | ||
}; | ||
|
||
let result = component.getInitials(); | ||
|
||
result.should.equal('a'); | ||
}); | ||
|
||
it('should get two initials', () => { | ||
component.identity = { | ||
userId: 'pedantic owl' | ||
}; | ||
|
||
let result = component.getInitials(); | ||
|
||
result.should.equal('po'); | ||
}); | ||
|
||
it('should get maximum of two initials', () => { | ||
component.identity = { | ||
userId: 'eat conga repeat' | ||
}; | ||
|
||
let result = component.getInitials(); | ||
|
||
result.should.equal('ec'); | ||
}); | ||
|
||
it('should get non-ascii \'initials\'', () => { | ||
component.identity = { | ||
userId: '黄 丽' | ||
}; | ||
|
||
let result = component.getInitials(); | ||
|
||
result.should.equal('黄丽'); | ||
}); | ||
|
||
it('should smile if there are no initials', () => { | ||
component.identity = { | ||
userId: ' ' | ||
}; | ||
|
||
let result = component.getInitials(); | ||
|
||
result.should.equal(':)'); | ||
}); | ||
}); | ||
}); |
59 changes: 59 additions & 0 deletions
59
packages/composer-playground/src/app/login/identity-card/identity-card.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Component, Input, Output, EventEmitter } from '@angular/core'; | ||
|
||
@Component({ | ||
selector: 'identity-card', | ||
templateUrl: './identity-card.component.html', | ||
styleUrls: [ | ||
'./identity-card.component.scss'.toString() | ||
] | ||
}) | ||
|
||
export class IdentityCardComponent { | ||
|
||
@Input() | ||
identity: any; | ||
|
||
@Input() | ||
preview: boolean = false; | ||
|
||
@Output() | ||
onConnect: EventEmitter<string> = new EventEmitter<string>(); | ||
|
||
@Output() | ||
onDismiss: EventEmitter<string> = new EventEmitter<string>(); | ||
|
||
@Output() | ||
onDelete: EventEmitter<string> = new EventEmitter<string>(); | ||
|
||
@Output() | ||
onExport: EventEmitter<string> = new EventEmitter<string>(); | ||
|
||
connect() { | ||
this.onConnect.emit(this.identity.userId); | ||
} | ||
|
||
dismiss() { | ||
this.onDismiss.emit(this.identity.userId); | ||
} | ||
|
||
delete() { | ||
this.onDelete.emit(this.identity.userId); | ||
} | ||
|
||
export() { | ||
this.onExport.emit(this.identity.userId); | ||
} | ||
|
||
getInitials<String>() { | ||
let result; | ||
let userId = this.identity.userId; | ||
let regexp = /^(\S)\S*\s*(\S?)/i; | ||
let matches = regexp.exec(userId); | ||
|
||
if (matches) { | ||
result = matches.slice(1, 3).join(''); | ||
} | ||
|
||
return result ? result : ':)'; | ||
} | ||
} |
1 change: 1 addition & 0 deletions
1
packages/composer-playground/src/app/login/identity-card/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './identity-card.component'; |
Oops, something went wrong.