diff --git a/harbor-app/src/app/account/account.module.ts b/harbor-app/src/app/account/account.module.ts index 7ace60143..218981c9c 100644 --- a/harbor-app/src/app/account/account.module.ts +++ b/harbor-app/src/app/account/account.module.ts @@ -1,15 +1,20 @@ import { NgModule } from '@angular/core'; -import { SharedModule } from '../shared/shared.module'; import { RouterModule } from '@angular/router'; +import { CoreModule } from '../core/core.module'; import { SignInComponent } from './sign-in/sign-in.component'; +import { PasswordSettingComponent } from './password/password-setting.component'; + +import { PasswordSettingService } from './password/password-setting.service'; @NgModule({ imports: [ - SharedModule, + CoreModule, RouterModule ], - declarations: [SignInComponent], - exports: [SignInComponent] + declarations: [SignInComponent, PasswordSettingComponent], + exports: [SignInComponent, PasswordSettingComponent], + + providers: [PasswordSettingService] }) export class AccountModule { } \ No newline at end of file diff --git a/harbor-app/src/app/account/forgot-password.component.html b/harbor-app/src/app/account/password/forgot-password.component.html similarity index 100% rename from harbor-app/src/app/account/forgot-password.component.html rename to harbor-app/src/app/account/password/forgot-password.component.html diff --git a/harbor-app/src/app/account/forgot-password.component.ts b/harbor-app/src/app/account/password/forgot-password.component.ts similarity index 100% rename from harbor-app/src/app/account/forgot-password.component.ts rename to harbor-app/src/app/account/password/forgot-password.component.ts diff --git a/harbor-app/src/app/account/password/password-setting.component.html b/harbor-app/src/app/account/password/password-setting.component.html new file mode 100644 index 000000000..6f86779d0 --- /dev/null +++ b/harbor-app/src/app/account/password/password-setting.component.html @@ -0,0 +1,55 @@ + + + + + \ No newline at end of file diff --git a/harbor-app/src/app/account/password/password-setting.component.ts b/harbor-app/src/app/account/password/password-setting.component.ts new file mode 100644 index 000000000..80986a67e --- /dev/null +++ b/harbor-app/src/app/account/password/password-setting.component.ts @@ -0,0 +1,104 @@ +import { Component, ViewChild, AfterViewChecked, Output, EventEmitter } from '@angular/core'; +import { Router } from '@angular/router'; +import { NgForm } from '@angular/forms'; + +import { PasswordSettingService } from './password-setting.service'; +import { SessionService } from '../../shared/session.service'; + +@Component({ + selector: 'password-setting', + templateUrl: "password-setting.component.html" +}) +export class PasswordSettingComponent implements AfterViewChecked { + opened: boolean = false; + oldPwd: string = ""; + newPwd: string = ""; + reNewPwd: string = ""; + + private formValueChanged: boolean = false; + private onCalling: boolean = false; + + pwdFormRef: NgForm; + @ViewChild("changepwdForm") pwdForm: NgForm; + + @Output() private pwdChange = new EventEmitter(); + + constructor(private passwordService: PasswordSettingService, private session: SessionService){} + + //If form is valid + public get isValid(): boolean { + if (this.pwdForm && this.pwdForm.form.get("newPassword")) { + return this.pwdForm.valid && + this.pwdForm.form.get("newPassword").value === this.pwdForm.form.get("reNewPassword").value; + } + return false; + } + + public get valueChanged(): boolean { + return this.formValueChanged; + } + + public get showProgress(): boolean { + return this.onCalling; + } + + ngAfterViewChecked() { + if (this.pwdFormRef != this.pwdForm) { + this.pwdFormRef = this.pwdForm; + if (this.pwdFormRef) { + this.pwdFormRef.valueChanges.subscribe(data => { + this.formValueChanged = true; + }); + } + } + } + + //Open modal dialog + open(): void { + this.opened = true; + this.pwdForm.reset(); + } + + //Close the moal dialog + close(): void { + this.opened = false; + } + + //handle the ok action + doOk(): void { + if (this.onCalling) { + return;//To avoid duplicate click events + } + + if (!this.isValid) { + return;//Double confirm + } + + //Double confirm session is valid + let cUser = this.session.getCurrentUser(); + if(!cUser){ + return; + } + + //Call service + this.onCalling = true; + + this.passwordService.changePassword(cUser.user_id, + { + new_password: this.pwdForm.value.newPassword, + old_password: this.pwdForm.value.oldPassword + }) + .then(() => { + this.onCalling = false; + //Tell shell to reset current view + this.pwdChange.emit(true); + + this.close(); + }) + .catch(error => { + this.onCalling = false; + console.error(error);//TODO: + }); + //TODO:publish the successful message to general messae box + } +} \ No newline at end of file diff --git a/harbor-app/src/app/account/password/password-setting.service.ts b/harbor-app/src/app/account/password/password-setting.service.ts new file mode 100644 index 000000000..94b2af793 --- /dev/null +++ b/harbor-app/src/app/account/password/password-setting.service.ts @@ -0,0 +1,35 @@ +import { Injectable } from '@angular/core'; +import { Headers, Http, RequestOptions } from '@angular/http'; +import 'rxjs/add/operator/toPromise'; + +import { PasswordSetting } from './password-setting'; + +const passwordChangeEndpoint = "/api/users/:user_id/password"; + +@Injectable() +export class PasswordSettingService { + private headers: Headers = new Headers({ + "Accept": 'application/json', + "Content-Type": 'application/json' + }); + private options: RequestOptions = new RequestOptions({ + 'headers': this.headers + }); + + constructor(private http: Http) { } + + changePassword(userId: number, setting: PasswordSetting): Promise { + if(!setting || setting.new_password.trim()==="" || setting.old_password.trim()===""){ + return Promise.reject("Invalid data"); + } + + let putUrl = passwordChangeEndpoint.replace(":user_id", userId+""); + return this.http.put(putUrl, JSON.stringify(setting), this.options) + .toPromise() + .then(() => null) + .catch(error=>{ + return Promise.reject(error); + }); + } + +} diff --git a/harbor-app/src/app/account/password/password-setting.ts b/harbor-app/src/app/account/password/password-setting.ts new file mode 100644 index 000000000..c06e26a49 --- /dev/null +++ b/harbor-app/src/app/account/password/password-setting.ts @@ -0,0 +1,11 @@ +/** + * + * Struct for password change + * + * @export + * @class PasswordSetting + */ +export class PasswordSetting { + old_password: string; + new_password: string; +} \ No newline at end of file diff --git a/harbor-app/src/app/account/reset-password.component.html b/harbor-app/src/app/account/reset-password.component.html deleted file mode 100644 index e69de29bb..000000000 diff --git a/harbor-app/src/app/account/reset-password.component.ts b/harbor-app/src/app/account/reset-password.component.ts deleted file mode 100644 index 868dcd35a..000000000 --- a/harbor-app/src/app/account/reset-password.component.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Component } from '@angular/core'; -import { Router } from '@angular/router'; - -@Component({ - selector: 'reset-password', - templateUrl: "reset-password.component.html" -}) -export class ResetPasswordComponent { - // constructor(private router: Router){} -} \ No newline at end of file diff --git a/harbor-app/src/app/account/sign-in/sign-in.component.ts b/harbor-app/src/app/account/sign-in/sign-in.component.ts index 8c33029d4..848a75337 100644 --- a/harbor-app/src/app/account/sign-in/sign-in.component.ts +++ b/harbor-app/src/app/account/sign-in/sign-in.component.ts @@ -97,8 +97,7 @@ export class SignInComponent implements AfterViewChecked { //Trigger the signin action signIn(): void { //Should validate input firstly - if (!this.validate()) { - console.info("return"); + if (!this.validate() || this.signInStatus === signInStatusOnGoing) { return; } @@ -113,14 +112,18 @@ export class SignInComponent implements AfterViewChecked { //Validate the sign-in session this.session.retrieveUser() - .then(() => { + .then(user => { //Routing to the right location - let nextRoute = ["/harbor", "dashboard"]; + let nextRoute = ["/harbor", "projects"]; this.router.navigate(nextRoute); }) - .catch(this.handleError); + .catch(error => { + this.handleError(error); + }); }) - .catch(this.handleError); + .catch(error => { + this.handleError(error); + }); } //Help user navigate to the sign up diff --git a/harbor-app/src/app/account/sign-up.component.html b/harbor-app/src/app/account/sign-up/sign-up.component.html similarity index 100% rename from harbor-app/src/app/account/sign-up.component.html rename to harbor-app/src/app/account/sign-up/sign-up.component.html diff --git a/harbor-app/src/app/account/sign-up.component.ts b/harbor-app/src/app/account/sign-up/sign-up.component.ts similarity index 100% rename from harbor-app/src/app/account/sign-up.component.ts rename to harbor-app/src/app/account/sign-up/sign-up.component.ts diff --git a/harbor-app/src/app/app.module.ts b/harbor-app/src/app/app.module.ts index c7991e8d2..71f96e112 100644 --- a/harbor-app/src/app/app.module.ts +++ b/harbor-app/src/app/app.module.ts @@ -4,25 +4,23 @@ import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { ClarityModule } from 'clarity-angular'; import { AppComponent } from './app.component'; -import { AccountModule } from './account/account.module'; import { BaseModule } from './base/base.module'; import { HarborRoutingModule } from './harbor-routing.module'; -import { CoreModule } from './core/core.module'; +import { SharedModule } from './shared/shared.module'; @NgModule({ declarations: [ AppComponent, ], imports: [ - CoreModule, - AccountModule, + SharedModule, BaseModule, HarborRoutingModule ], providers: [], - bootstrap: [ AppComponent ] + bootstrap: [AppComponent] }) export class AppModule { } diff --git a/harbor-app/src/app/base/account-settings/account-settings-modal.component.html b/harbor-app/src/app/base/account-settings/account-settings-modal.component.html index fff3ba84e..de47a471b 100644 --- a/harbor-app/src/app/base/account-settings/account-settings-modal.component.html +++ b/harbor-app/src/app/base/account-settings/account-settings-modal.component.html @@ -1,4 +1,4 @@ - +