Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,18 @@ <h1>{{headerMessage}}</h1>
</div>
<section class="modal-body">
<section class="information">
<p><b>You are about to delete:</b></p>
<p>You are about to remove the {{ fileType }} <b>{{ fileName }}</b>{{ deleteFrom ? ' from ' + deleteFrom + '.' : '.'}}</p>
<!--
<section class="items">
<div class="item"><b>{{fileType}}</b></div>
<div class="item"><i>{{fileName}}</i></div>
</section>
-->
<p>{{deleteMessage}}</p>
</section>
</section>
<footer>
<button type="button" class="secondary" (click)="activeModal.dismiss()">Cancel</button>
<button type="button" class="delete" (click)="activeModal.close(true)">Delete File</button>
<button type="button" class="delete" (click)="activeModal.close(true)">{{ confirmButtonText || 'Delete File' }}</button>
</footer>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ export class DeleteComponent implements OnInit {
}

ngOnInit() {
this.fileName = this.deleteFile.displayID;
if (!this.fileName) {
this.fileName = this.deleteFile.displayID;

if (this.deleteFile.model) {
this.fileType = 'Model File';
} else if (this.deleteFile.script) {
this.fileType = 'Script File';
} else {
this.fileType = 'File';
if (this.deleteFile.model) {
this.fileType = 'Model File';
} else if (this.deleteFile.script) {
this.fileType = 'Script File';
} else {
this.fileType = 'File';
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ <h2>Identities for {{connectionProfile.name === '$default' ? 'Web Browser' : con
{{identity.userId}}
</div>
<div class="action-buttons">
<button type="button" class="action">
<button type="button" class="action circular" (click)="removeIdentity(connectionProfile.name, identity.userId)">
<svg class="ibm-icon vertical-top" aria-hidden="true">
<use xlink:href="#icon-trash_32"></use>
</svg>
</button>
<button type="button" class="action">
<button type="button" class="action circular">
<svg class="ibm-icon vertical-top" aria-hidden="true">
<use xlink:href="#icon-upload_32"></use>
</svg>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ app-login {
}

.userId-image {
background-color: $keyline-highlight;
border: 1px solid $keyline-highlight;
background-color: $fourth-highlight;
border: 1px solid $fourth-highlight;
border-radius: 50%;
width: 75px;
height: 75px;
Expand Down
94 changes: 90 additions & 4 deletions packages/composer-playground/src/app/login/login.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import { InitializationService } from '../services/initialization.service';

import { LoginComponent } from './login.component';
import { AlertService } from '../basic-modals/alert.service';
import { WalletService } from '../services/wallet.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

let should = chai.should();

Expand Down Expand Up @@ -86,6 +88,8 @@ describe(`LoginComponent`, () => {
let mockInitializationService;
let routerStub;
let mockAlertService;
let mockWalletService;
let mockModal;

beforeEach(() => {

Expand All @@ -95,12 +99,16 @@ describe(`LoginComponent`, () => {
mockAdminService = sinon.createStubInstance(AdminService);
mockInitializationService = sinon.createStubInstance(InitializationService);
mockAlertService = sinon.createStubInstance(AlertService);
mockWalletService = sinon.createStubInstance(WalletService);
mockModal = sinon.createStubInstance(NgbModal);

routerStub = new RouterStub();

mockAlertService.errorStatus$ = {
next: sinon.stub()
};
mockAlertService.successStatus$ = {next: sinon.stub()};
mockAlertService.busyStatus$ = {next: sinon.stub()};
mockAlertService.errorStatus$ = {next: sinon.stub()};

mockWalletService.removeFromWallet = sinon.stub().returns(Promise.resolve(true));

TestBed.configureTestingModule({
declarations: [
Expand All @@ -114,7 +122,9 @@ describe(`LoginComponent`, () => {
{provide: Router, useValue: routerStub},
{provide: AdminService, useValue: mockAdminService},
{provide: InitializationService, useValue: mockInitializationService},
{provide: AlertService, useValue: mockAlertService}
{provide: AlertService, useValue: mockAlertService},
{provide: WalletService, useValue: mockWalletService},
{provide: NgbModal, useValue: mockModal}
]
});

Expand Down Expand Up @@ -222,4 +232,80 @@ describe(`LoginComponent`, () => {
loadConnectionProfilesStub.should.have.been.called;
});
});

describe('removeIdentity', () => {
it('should open the delete-confirm modal', fakeAsync(() => {
mockModal.open = sinon.stub().returns({
componentInstance: {},
result: Promise.resolve(0)
});

component.removeIdentity('profile', 'name');
tick();
mockModal.open.should.have.been.called;
}));

it('should open delete-confirm modal and handle error', fakeAsync(() => {
mockModal.open = sinon.stub().returns({
componentInstance: {},
result: Promise.reject('some error')
});

component.removeIdentity('profile', 'name');
tick();
mockAlertService.busyStatus$.next.should.have.been.called;
mockAlertService.errorStatus$.next.should.have.been.called;
}));

it('should open delete-confirm modal and handle cancel', fakeAsync(() => {
mockModal.open = sinon.stub().returns({
componentInstance: {},
result: Promise.reject(null)
});

component.removeIdentity('profile', 'name');
tick();
mockAlertService.busyStatus$.next.should.not.have.been.called;
mockAlertService.errorStatus$.next.should.not.have.been.called;
}));

it('should refresh the connection profiles after successfully calling walletService.removeFromWallet()', fakeAsync(() => {
mockModal.open = sinon.stub().returns({
componentInstance: {},
result: Promise.resolve(true)
});

component.loadConnectionProfiles = sinon.stub();

component.removeIdentity('profile', 'name');
tick();

// check services called
component.loadConnectionProfiles.should.have.been.called;
mockAlertService.busyStatus$.next.should.have.been.called;
mockAlertService.successStatus$.next.should.have.been.called;

mockAlertService.errorStatus$.next.should.not.have.been.called;
}));

it('should handle errors when calling walletService.removeFromWallet()', fakeAsync(() => {
mockModal.open = sinon.stub().returns({
componentInstance: {},
result: Promise.resolve(true)
});

component.loadConnectionProfiles = sinon.stub();
mockWalletService.removeFromWallet = sinon.stub().returns(Promise.reject('some error'));

component.removeIdentity('profile', 'name');
tick();

// check services called
mockAlertService.busyStatus$.next.should.have.been.called;
mockAlertService.errorStatus$.next.should.have.been.called;

mockAlertService.successStatus$.next.should.not.have.been.called;
component.loadConnectionProfiles.should.not.have.been.called;
}));
});
});
48 changes: 48 additions & 0 deletions packages/composer-playground/src/app/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { ConnectionProfileService } from '../services/connectionprofile.service'
import { ClientService } from '../services/client.service';
import { InitializationService } from '../services/initialization.service';
import { AlertService } from '../basic-modals/alert.service';
import { DeleteComponent } from '../basic-modals/delete-confirm/delete-confirm.component';
import { WalletService } from '../services/wallet.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
selector: 'app-login',
Expand All @@ -25,6 +28,8 @@ export class LoginComponent implements OnInit {
private connectionProfileService: ConnectionProfileService,
private clientService: ClientService,
private initializationService: InitializationService,
private walletService: WalletService,
private modalService: NgbModal,
private alertService: AlertService) {

}
Expand Down Expand Up @@ -91,4 +96,47 @@ export class LoginComponent implements OnInit {
delete this.editingConectionProfile;
return this.loadConnectionProfiles();
}

removeIdentity(connectionProfile, userId): void {
const confirmModalRef = this.modalService.open(DeleteComponent);
confirmModalRef.componentInstance.headerMessage = 'Remove ID Card';
confirmModalRef.componentInstance.fileName = userId;
confirmModalRef.componentInstance.fileType = 'ID Card';
confirmModalRef.componentInstance.deleteMessage = 'Are you sure you want to do this?';
confirmModalRef.componentInstance.deleteFrom = 'My Wallet';
confirmModalRef.componentInstance.confirmButtonText = 'Remove';

confirmModalRef.result
.then((result) => {
if (result) {
this.alertService.busyStatus$.next({
title: 'Removing ID card',
text: 'removing the ID card ' + userId
});
this.walletService.removeFromWallet(connectionProfile, userId)
.then(() => {
this.loadConnectionProfiles();
this.alertService.busyStatus$.next(null);
this.alertService.successStatus$.next({
title: 'ID Card Removed',
text: 'The ID card was successfully removed from My Wallet.',
icon: '#icon-trash_32'
});
})
.catch((error) => {
this.alertService.busyStatus$.next(null);
this.alertService.errorStatus$.next(error);
});
}
}, (reason) => {
if (reason && reason !== 1) {
this.alertService.busyStatus$.next(null);
this.alertService.errorStatus$.next(reason);
}
})
.catch((error) => {
this.alertService.busyStatus$.next(null);
this.alertService.errorStatus$.next(error);
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,20 @@
}
}

&.action.circular {
border-radius: 50%;
width: 42px;
box-sizing: border-box;
padding-top: 1px;
height: 42px;
}

&.action.circular:hover,
&.action.circular:focus {
background-color: $fourth-highlight;
border-bottom: 2px solid transparent;
}

&.icon {
background-color: transparent;
min-width: 0;
Expand Down