diff --git a/front/src/common/component/async-action-status/async-status-component.html b/front/src/common/component/async-action-status/async-status-component.html
new file mode 100644
index 0000000..0940770
--- /dev/null
+++ b/front/src/common/component/async-action-status/async-status-component.html
@@ -0,0 +1,3 @@
+
+
+
diff --git a/front/src/common/component/async-action-status/async-status-component.less b/front/src/common/component/async-action-status/async-status-component.less
new file mode 100644
index 0000000..e69de29
diff --git a/front/src/common/component/async-action-status/async-status-component.spec.ts b/front/src/common/component/async-action-status/async-status-component.spec.ts
new file mode 100644
index 0000000..0f9ce47
--- /dev/null
+++ b/front/src/common/component/async-action-status/async-status-component.spec.ts
@@ -0,0 +1,68 @@
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
+import { PasswordEntryComponent } from './async-status-component';
+
+describe('PasswordEntryComponent global test', () => {
+ let component: PasswordEntryComponent;
+ let fixture: ComponentFixture;
+ let input: HTMLInputElement;
+ let button: HTMLButtonElement;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ declarations: [PasswordEntryComponent],
+ }).compileComponents();
+ fixture = TestBed.createComponent(PasswordEntryComponent);
+ component = fixture.componentInstance;
+ input = fixture.nativeElement.querySelector('div').querySelector('input');
+ button = fixture.nativeElement.querySelector('div').querySelector('button');
+ });
+
+ it('Test mode password (default)', () => {
+ fixture.detectChanges();
+ expect(input.textContent).toEqual('');
+ expect(button.textContent).toEqual('visibility_off');
+ expect(input.type).toEqual('password');
+ });
+
+ it('Test mode text', () => {
+ component.passwordVisibility = true;
+ fixture.detectChanges();
+ expect(input.textContent).toEqual('');
+ expect(button.textContent).toEqual('visibility');
+ expect(input.type).toEqual('text');
+ });
+
+ it('test click on hide button', fakeAsync(() => {
+ fixture.detectChanges();
+ expect(component.passwordVisibility).toEqual(false);
+ button.click();
+ tick();
+ fixture.detectChanges();
+ expect(component.passwordVisibility).toEqual(true);
+ expect(button.textContent).toEqual('visibility');
+ expect(input.type).toEqual('text');
+ button.click();
+ tick();
+ fixture.detectChanges();
+ expect(component.passwordVisibility).toEqual(false);
+ expect(button.textContent).toEqual('visibility_off');
+ expect(input.type).toEqual('password');
+ }));
+
+ it('Set password', fakeAsync(() => {
+ fixture.detectChanges();
+ expect(component.passwordVisibility).toEqual(false);
+ let tmpData = 'My beautifull Password';
+ input.value = tmpData;
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+ expect(input.textContent).toEqual(tmpData);
+ expect(component.value).toEqual(tmpData);
+ tmpData = '';
+ input.value = tmpData;
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+ expect(input.textContent).toEqual(tmpData);
+ expect(component.value).toEqual(tmpData);
+ }));
+});
diff --git a/front/src/common/component/async-action-status/async-status-component.ts b/front/src/common/component/async-action-status/async-status-component.ts
new file mode 100644
index 0000000..00582f8
--- /dev/null
+++ b/front/src/common/component/async-action-status/async-status-component.ts
@@ -0,0 +1,37 @@
+/** @file
+ * @author Edouard DUPIN
+ * @copyright 2018, Edouard DUPIN, all right reserved
+ * @license PROPRIETARY (see license file)
+ */
+import { Component, Input } from '@angular/core';
+
+export enum AsyncActionState {
+ IDLE = "idle",
+ LOADING = "loading",
+ DONE = "done",
+ FAIL = "fail",
+}
+
+@Component({
+ selector: 'app-async-status-component',
+ templateUrl: 'async-status-component.html',
+ styleUrls: ['async-status-component.less'],
+})
+export class AsyncActionStatusComponent {
+ /// Value of the password
+ @Input() value: AsyncActionState = AsyncActionState.IDLE;
+
+ public getImage(): string {
+ switch(this.value) {
+ case AsyncActionState.IDLE:
+ return '';
+ case AsyncActionState.LOADING:
+ return 'assets/images/load.svg';
+ case AsyncActionState.DONE:
+ return 'assets/images/validate.svg';
+ case AsyncActionState.FAIL:
+ return 'assets/images/validate-not.svg';
+
+ }
+ }
+}