| @@ -1,33 +1,41 @@ | |||
| <h5 *ngIf="canEditUser()" > <kendo-icon [name]="'ascx'" > </kendo-icon> Login Related </h5> | |||
| <form *ngIf="canEditUser()" class="k-form" #userForm="ngForm" (submit)="save(userForm)"> | |||
| <form *ngIf="canEditUser()" class="k-form" [formGroup]="UserForm" (submit)="save()"> | |||
| <ng-container > | |||
| <fieldset class="k-form-fieldset"> | |||
| <kendo-formfield> | |||
| <kendo-label [for]="Login" text="Unique Login id:"></kendo-label> | |||
| <kendo-textbox kendoTextBox #Login name="Login" [(ngModel)]="UserExtra.Login" | |||
| [disabled] = "!showAdmin" | |||
| [showSuccessIcon]="UserExtra.Login.length >= 3 && UserExtra.Login.length <=44 "> </kendo-textbox> | |||
| <kendo-formerror>First name is required</kendo-formerror> | |||
| <kendo-label [for]=login text="Unique Login id: "> | |||
| <kendo-loader *ngIf="UserForm.get('Login').status === 'PENDING'" | |||
| [type]="'pulsing'" | |||
| [themeColor]="'primary'" | |||
| [size]="'medium'" | |||
| ></kendo-loader> | |||
| </kendo-label> | |||
| <kendo-textbox #login kendoTextBox name="Login" formControlName="Login" (valueChange)="onChangeLogin()"> | |||
| </kendo-textbox> | |||
| <kendo-formerror *ngIf="UserForm.get('Login').hasError('required')" >Login is required</kendo-formerror> | |||
| <kendo-formerror *ngIf="UserForm.get('Login').hasError('loginAvailable')" >Login is used by someone else </kendo-formerror> | |||
| <kendo-formerror *ngIf="UserForm.get('Login').hasError('email')" >Login should be email format</kendo-formerror> | |||
| </kendo-formfield> | |||
| <div class="vertical-spacer"></div> | |||
| <kendo-formfield *ngIf="showAdmin "> | |||
| <label class="k-label">Allow Login | |||
| <input type="checkbox" name="enabled" kendoCheckBox | |||
| [(ngModel)]="UserExtra.Enabled" [disabled]="isCurrentUser"/> | |||
| <input type="checkbox" name="enabled" kendoCheckBox formControlName="Enabled"/> | |||
| </label> | |||
| </kendo-formfield> | |||
| <div class="vertical-spacer"></div> | |||
| </fieldset> | |||
| </ng-container> | |||
| <div class="k-form-buttons k-buttons-end"> | |||
| <div class="k-form-buttons k-buttons-end" *ngIf="UserForm.get('Login').status !== 'PENDING'"> | |||
| <div> | |||
| <button kendoButton class="k-button k-primary" type="submit" icon="save" | |||
| [disabled]="userForm.form.status !=='VALID'"> Modify Login</button> | |||
| > Modify Login</button> | |||
| </div> | |||
| </div> | |||
| </form> | |||
| <app-message-box #messageBox ></app-message-box> | |||
| @@ -1,11 +1,12 @@ | |||
| import {Component, Input, OnInit, ViewChild} from '@angular/core'; | |||
| import {UserExtraModel} from '../../models/user-extra.model'; | |||
| import {NgForm} from '@angular/forms'; | |||
| import {FormControl, FormGroup, NgForm, Validators} from '@angular/forms'; | |||
| import {AuthService} from '../../service/auth.service'; | |||
| import {HttpClient} from '@angular/common/http'; | |||
| import {MessageBoxComponent} from '../../message-box/message-box.component'; | |||
| import {BrokerModel} from '../../models/broker.model'; | |||
| import {PeopleService} from '../../service/people.service'; | |||
| import {asyncValidatorLoginAvailable} from '../../validator/unique.login.validator'; | |||
| @Component({ | |||
| selector: 'app-user-profile', | |||
| @@ -19,17 +20,24 @@ export class UserProfileComponent implements OnInit { | |||
| public showAdmin = false; | |||
| public isCurrentUser = false; | |||
| public UserForm: FormGroup; | |||
| constructor(private auth: AuthService, private http: HttpClient, private ps: PeopleService) { } | |||
| ngOnInit(): void { | |||
| this.showAdmin = this.auth.isAdmin(); | |||
| this.isCurrentUser = this.auth.isCurrentUser(this.PeopleId); | |||
| if (this.auth.isAdmin() && !this.auth.isCurrentUser(this.PeopleId)) { | |||
| // edit other people, | |||
| if ( this.PeopleId !== '' && this.UserExtra.Login === '' ){ // we need to load by ourself | |||
| this.ps.getPeopleExtraById(this.PeopleId).subscribe( | |||
| resp => { | |||
| this.UserExtra = new UserExtraModel(resp); | |||
| this.UserForm.get('Login').setValue(this.UserExtra.Login); | |||
| this.UserForm.get('Enabled').setValue(this.UserExtra.Enabled); | |||
| } | |||
| ); | |||
| } | |||
| @@ -37,10 +45,17 @@ export class UserProfileComponent implements OnInit { | |||
| this.PeopleId = this.auth.loggedIn.User.Id; | |||
| this.UserExtra = this.auth.loggedIn.UserExtra; | |||
| } | |||
| this.UserForm = new FormGroup({ | |||
| Login: new FormControl({value: this.UserExtra.Login, disabled: ! this.showAdmin }, | |||
| [Validators.required, Validators.email], | |||
| [asyncValidatorLoginAvailable(this.auth, this.UserExtra.Login)] ), | |||
| Enabled: new FormControl({value: this.UserExtra.Enabled, disabled: this.isCurrentUser}), | |||
| }); | |||
| } | |||
| public save(userForm: NgForm): void { | |||
| const expected = userForm.form.get('Login').value; | |||
| public save(): void { | |||
| const expected = this.UserForm.get('Login').value; | |||
| this.http.post<string>(this.auth.getUrl('user/' + this.PeopleId), this.UserExtra).subscribe( | |||
| resp => { | |||
| if ( resp === expected ) { | |||
| @@ -62,4 +77,8 @@ export class UserProfileComponent implements OnInit { | |||
| return this.UserExtra !== undefined && this.UserExtra.Login !== undefined; | |||
| } | |||
| public onChangeLogin(): void { | |||
| console.log(this); | |||
| } | |||
| } | |||
| @@ -4,6 +4,7 @@ import {ApiV1LoginResponse} from '../models/api-v1-login-response'; | |||
| import {Router} from '@angular/router'; | |||
| import {PeopleModel} from '../models/people.model'; | |||
| import {UserExtraModel} from '../models/user-extra.model'; | |||
| import {Observable} from 'rxjs'; | |||
| @Injectable() | |||
| export class AuthService { | |||
| @@ -138,19 +139,23 @@ export class AuthService { | |||
| this.saveSessionInfo(); | |||
| } | |||
| public isAdmin(): boolean { | |||
| return this.loggedIn.role === 'admin'; | |||
| } | |||
| public LoginAvailable(v: string): Observable<boolean> { | |||
| return this.http.get<boolean>(this.getUrl('login-available/' + v)); | |||
| } | |||
| public isAdmin(): boolean { | |||
| return this.loggedIn.role === 'admin'; | |||
| } | |||
| public isBroker(): boolean { | |||
| return this.loggedIn.role === 'broker'; | |||
| } | |||
| public isBroker(): boolean { | |||
| return this.loggedIn.role === 'broker'; | |||
| } | |||
| public isUser(): boolean { | |||
| return this.loggedIn.login === true; | |||
| } | |||
| public isUser(): boolean { | |||
| return this.loggedIn.login === true; | |||
| } | |||
| public isCurrentUser(id: string): boolean { | |||
| return this.loggedIn.login === true && this.loggedIn.User !== undefined && this.loggedIn.User.Id === id; | |||
| } | |||
| public isCurrentUser(id: string): boolean { | |||
| return this.loggedIn.login === true && this.loggedIn.User !== undefined && this.loggedIn.User.Id === id; | |||
| } | |||
| } | |||
| @@ -29,7 +29,6 @@ export class TopBarComponent implements OnInit , OnDestroy { | |||
| ngOnInit(): void { | |||
| this.initAndSubLogin(); | |||
| console.log(this); | |||
| } | |||
| public initAndSubLogin(): void{ | |||
| @@ -0,0 +1,25 @@ | |||
| import {AbstractControl, AsyncValidatorFn, ValidationErrors} from '@angular/forms'; | |||
| import { Observable, of } from 'rxjs'; | |||
| import {AuthService} from '../service/auth.service'; | |||
| import {delay, map, switchMap} from 'rxjs/operators'; | |||
| export function asyncValidatorLoginAvailable(auth: AuthService, existing: string): AsyncValidatorFn { | |||
| return (control: AbstractControl): Observable<ValidationErrors> | null => { | |||
| const v: string = control.value; | |||
| if (v === existing && v !== '') { | |||
| return of(null); | |||
| } | |||
| return of(control.value).pipe( | |||
| delay(500), | |||
| switchMap( () => auth.LoginAvailable(v).pipe( | |||
| map((result: boolean) => result ? null : {loginAvailable: true}) | |||
| ) | |||
| ) | |||
| ); | |||
| }; | |||
| } | |||