| } | } | ||||
| } | } | ||||
| }, | }, | ||||
| "@progress/kendo-angular-upload": { | |||||
| "version": "7.1.0", | |||||
| "resolved": "https://registry.npmjs.org/@progress/kendo-angular-upload/-/kendo-angular-upload-7.1.0.tgz", | |||||
| "integrity": "sha512-oezUH2BWZguJ6YunBHs5J4SLGWcbt87RTWp6AHlwaopgSALsu5VXpptoLjcrkVXska+nkiyuLY9zpT4HBoGgfQ==", | |||||
| "requires": { | |||||
| "@progress/kendo-schematics": "^1.0.0", | |||||
| "tslib": "^1.9.0" | |||||
| }, | |||||
| "dependencies": { | |||||
| "tslib": { | |||||
| "version": "1.14.1", | |||||
| "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", | |||||
| "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" | |||||
| } | |||||
| } | |||||
| }, | |||||
| "@progress/kendo-charts": { | "@progress/kendo-charts": { | ||||
| "version": "1.17.1", | "version": "1.17.1", | ||||
| "resolved": "https://registry.npmjs.org/@progress/kendo-charts/-/kendo-charts-1.17.1.tgz", | "resolved": "https://registry.npmjs.org/@progress/kendo-charts/-/kendo-charts-1.17.1.tgz", |
| "@progress/kendo-angular-progressbar": "^2.0.0", | "@progress/kendo-angular-progressbar": "^2.0.0", | ||||
| "@progress/kendo-angular-toolbar": "^4.0.0", | "@progress/kendo-angular-toolbar": "^4.0.0", | ||||
| "@progress/kendo-angular-treeview": "^5.1.0", | "@progress/kendo-angular-treeview": "^5.1.0", | ||||
| "@progress/kendo-angular-upload": "^7.1.0", | |||||
| "@progress/kendo-data-query": "^1.5.4", | "@progress/kendo-data-query": "^1.5.4", | ||||
| "@progress/kendo-drawing": "^1.9.4", | "@progress/kendo-drawing": "^1.9.4", | ||||
| "@progress/kendo-licensing": "^1.1.3", | |||||
| "@progress/kendo-licensing": "^1.0.2", | |||||
| "@progress/kendo-svg-icons": "^0.1.2", | "@progress/kendo-svg-icons": "^0.1.2", | ||||
| "@progress/kendo-theme-default": "latest", | "@progress/kendo-theme-default": "latest", | ||||
| "bootstrap": "^4.6.0", | "bootstrap": "^4.6.0", |
| import { ClientLoanListComponent } from './client-loan-list/client-loan-list.component'; | import { ClientLoanListComponent } from './client-loan-list/client-loan-list.component'; | ||||
| import { ClientProfileComponent } from './client-profile/client-profile.component'; | import { ClientProfileComponent } from './client-profile/client-profile.component'; | ||||
| import { E403Component } from './e403/e403.component'; | import { E403Component } from './e403/e403.component'; | ||||
| import {FileSelectModule, UploadModule} from '@progress/kendo-angular-upload'; | |||||
| DateInputsModule, | DateInputsModule, | ||||
| DropDownsModule, | DropDownsModule, | ||||
| ExcelExportModule, | ExcelExportModule, | ||||
| EditorModule | |||||
| EditorModule, | |||||
| UploadModule, | |||||
| FileSelectModule | |||||
| ], | ], | ||||
| providers: [ | providers: [ | ||||
| MenuService, | MenuService, |
| import { NotificationService } from '@progress/kendo-angular-notification'; | import { NotificationService } from '@progress/kendo-angular-notification'; | ||||
| import { Subscription } from 'rxjs'; | import { Subscription } from 'rxjs'; | ||||
| import { AuthService } from '../service/auth.service'; | import { AuthService } from '../service/auth.service'; | ||||
| import {apiV1LoginResponse} from '../models/api-v1-login-response'; | |||||
| import {ApiV1LoginResponse} from '../models/api-v1-login-response'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-auth', | selector: 'app-auth', | ||||
| this.authService.login(this.userForm.value.email, this.userForm.value.password); | this.authService.login(this.userForm.value.email, this.userForm.value.password); | ||||
| } | } | ||||
| public onLogin(rsp: apiV1LoginResponse): void { | |||||
| public onLogin(rsp: ApiV1LoginResponse): void { | |||||
| this.loading = false; | this.loading = false; | ||||
| // console.log ('found login ' , rsp ); | // console.log ('found login ' , rsp ); | ||||
| if (rsp.login) { | if (rsp.login) { |
| <p>broker-profile works!</p> | |||||
| <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> | |||||
| <div class="vertical-spacer"></div> | |||||
| <div class="container"> | |||||
| <div class="row justify-content-center"> | |||||
| <div class="col-sm-12"> | |||||
| <h5> Edit : {{broker.First + ' ' + broker.Last}} </h5> | |||||
| <div class="dropzone-wrapper"> | |||||
| <div class="fileselect-wrapper"> | |||||
| <div class="row justify-content-center"> | |||||
| <div #brokerPhoto class="broker-photo" [ngStyle]="{'background-image' : avatarUrl }" ></div> | |||||
| </div> | |||||
| <kendo-fileselect | |||||
| #fileSelect | |||||
| zoneId="myZone" | |||||
| [restrictions]="myRestrictions" | |||||
| [showFileList]="false" | |||||
| (select)="onSelect($event)" | |||||
| > | |||||
| </kendo-fileselect> | |||||
| only jpg and png are allowed | |||||
| </div> | |||||
| </div> | |||||
| <div class="vertical-spacer"></div> | |||||
| <form class="k-form" #brokerForm="ngForm" (submit)="save(brokerForm)"> | |||||
| <ng-container > | |||||
| <fieldset class="k-form-fieldset"> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="First" text="First Name (only Admin can change)"></kendo-label> | |||||
| <kendo-textbox kendoTextBox #First name="First" [(ngModel)]="broker.First" | |||||
| [showSuccessIcon]="broker.Display.length >= 3 && broker.Display.length <=44 "> </kendo-textbox> | |||||
| <kendo-formerror>First name is required</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="Last" text="Last Name (only Admin can change)"></kendo-label> | |||||
| <kendo-textbox kendoTextBox #Last name="Last" [(ngModel)]="broker.Last" | |||||
| [showSuccessIcon]="broker.Display.length >= 3 && broker.Display.length <=44 "></kendo-textbox> | |||||
| <kendo-formerror>Last Name is required</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="Display" text="Display As"></kendo-label> | |||||
| <kendo-textbox #Display name="Display" [(ngModel)]="broker.Display" required [minlength]="3" [maxlength]="120" | |||||
| [showSuccessIcon]="broker.Display.length >= 3 && broker.Display.length <=100 "> </kendo-textbox> | |||||
| <kendo-formerror>Display name cannot empty</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="License" text="License"></kendo-label> | |||||
| <kendo-textbox #License name="License" [(ngModel)]="broker.License" required [minlength]="3" [maxlength]="120" | |||||
| [showSuccessIcon]="broker.License.length >= 0 && broker.License.length <=20 "> </kendo-textbox> | |||||
| <kendo-formerror>license is required, key in unknown if have one</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="BSB" text="BSB"></kendo-label> | |||||
| <kendo-textbox #BSB name="BSB" [(ngModel)]="broker.BSB" required [minlength]="3" [maxlength]="7" | |||||
| [showSuccessIcon]="broker.BSB.length >= 0 && broker.BSB.length <=7"> </kendo-textbox> | |||||
| <kendo-formerror>BSB required for accepting payment</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="ACC" text="ACC"></kendo-label> | |||||
| <kendo-textbox #ACC name="ACC" [(ngModel)]="broker.ACC" required [minlength]="3" [maxlength]="11" | |||||
| [showSuccessIcon]="broker.ACC.length >= 0 && broker.ACC.length <=11 "> </kendo-textbox> | |||||
| <kendo-formerror>ACC is required for accepting payment</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="Organization" text="Organization"></kendo-label> | |||||
| <kendo-textbox #Organization name="Organization" [(ngModel)]="broker.Organization" required | |||||
| [disabled]="true" [minlength]="3" [maxlength]="25" | |||||
| [showSuccessIcon]="broker.Organization.length >= 1 && broker.Organization.length <=25 "> | |||||
| </kendo-textbox> | |||||
| <kendo-formerror>Organization is required, (only changed by admin)</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| </fieldset> | |||||
| </ng-container> | |||||
| <div class="k-form-buttons k-buttons-end"> | |||||
| <div> | |||||
| <button kendoButton class="k-button k-primary" type="submit" icon="save" | |||||
| [disabled]="brokerForm.form.status !=='VALID'"> Save </button> | |||||
| </div> | |||||
| </div> | |||||
| </form> | |||||
| <kendo-switch [(ngModel)]="changePassword" ngModelOptions="{standalone: true}"> </kendo-switch> Change Password | |||||
| <div class="vertical-spacer"></div> | |||||
| <form *ngIf="changePassword" [formGroup]="ChangePassForm" class="k-form" (submit)="savePassword()"> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="OldPassword" text="Current Password"></kendo-label> | |||||
| <input kendoTextBox #OldPassword name="OldPassword" formControlName="OldPassword" | |||||
| type="password" [minlength]="3" [maxlength]="25" /> | |||||
| <kendo-formerror>Current password is needed (3-20 chars)</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="NewPass" text="New Password"></kendo-label> | |||||
| <input kendoTextBox #NewPass name="NewPass" formControlName="NewPass" | |||||
| [minlength]="3" [maxlength]="25" type="password" /> | |||||
| <kendo-formerror>New password is needed (3-20 chars)</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="NewPass1" text="New Password (repeat) "></kendo-label> | |||||
| <input kendoTextBox #NewPass1 name="NewPass1" formControlName="NewPass1" | |||||
| [minlength]="3" [maxlength]="25" type="password" /> | |||||
| <kendo-formerror>New password repeat is needed (3-20 chars) </kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| <button *ngIf="passEqual() && ! ChangePassForm.invalid" kendoButton class="k-button k-primary" type="submit" icon="save"> Change Password </button> | |||||
| </form> | |||||
| </div> | |||||
| </div> | |||||
| </div> | |||||
| <div class="vertical-spacer"></div> | |||||
| <kendo-dialog title="Message " *ngIf="opened" (close)="close('cancel')" [minWidth]="250" [width]="450"> | |||||
| <p style="margin: 30px; text-align: center;">{{ Message }}</p> | |||||
| <kendo-dialog-actions> | |||||
| <button kendoButton (click)="close('Ok, I got it')" primary="true">Yes</button> | |||||
| </kendo-dialog-actions> | |||||
| </kendo-dialog> |
| div.container { | |||||
| max-width: 500px; | |||||
| } | |||||
| div.vertical-spacer { | |||||
| height:1px; | |||||
| margin-bottom: 30px; | |||||
| } | |||||
| .dropzoneInvisible{ | |||||
| opacity:0.1; | |||||
| } | |||||
| .avatar { | |||||
| width: 100%; | |||||
| } | |||||
| .broker-photo { | |||||
| display: inline-block; | |||||
| width: 256px; | |||||
| height: 256px; | |||||
| border-radius: 50%; | |||||
| background-size: 256px 256px; | |||||
| background-position: center center; | |||||
| vertical-align: middle; | |||||
| line-height: 132px; | |||||
| box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2); | |||||
| margin-left: 5px; | |||||
| margin-bottom: 10px; | |||||
| background-repeat: no-repeat; | |||||
| box-shadow: 1px 1px 10px black; | |||||
| } |
| import { Component, OnInit } from '@angular/core'; | |||||
| import {Component, Input, OnInit, ViewChild} from '@angular/core'; | |||||
| import {PeopleModel} from '../models/people.model'; | |||||
| import {LoanSummaryService} from '../service/loan_summary.service'; | |||||
| import {AuthService} from '../service/auth.service'; | |||||
| import {FormControl, FormGroup, NgForm} from '@angular/forms'; | |||||
| import {FileInfo, FileRestrictions, FileSelectComponent, SelectEvent} from '@progress/kendo-angular-upload'; | |||||
| import {PeopleService} from '../service/people.service'; | |||||
| import {BrokerModel} from '../models/broker.model'; | |||||
| import {ConfirmedValidator} from '../validator/confirmed.validator'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-broker-profile', | selector: 'app-broker-profile', | ||||
| }) | }) | ||||
| export class BrokerProfileComponent implements OnInit { | export class BrokerProfileComponent implements OnInit { | ||||
| constructor() { } | |||||
| @Input() public broker: BrokerModel = BrokerModel.EmptyNew(); | |||||
| @ViewChild('fileSelect', {static: true}) fs: FileSelectComponent; | |||||
| public avatarUrl = 'url(https://svr2021.lawipac.com:8080/api/v1/avatar/1000)' ; | |||||
| public myRestrictions: FileRestrictions = { | |||||
| allowedExtensions: ['.jpg', '.png', '.jpeg'], | |||||
| maxFileSize: 2194304 | |||||
| }; | |||||
| public opened = false; // dialog box | |||||
| public Message = ''; // dialog message | |||||
| public changePassword = false; | |||||
| public ChangePassForm: FormGroup = new FormGroup({ | |||||
| OldPassword: new FormControl(), | |||||
| NewPass: new FormControl(), | |||||
| NewPass1: new FormControl(), | |||||
| }); | |||||
| constructor( private auth: AuthService, private ps: PeopleService) { } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.broker = BrokerModel.getFromUserAndExtra(this.auth.loggedIn.user, this.auth.loggedIn.userExtra); | |||||
| this.avatarUrl = 'url(' + this.auth.getUrl('avatar/' + this.broker.Id) + ')'; | |||||
| } | |||||
| public save(brokerForm: NgForm): void{ | |||||
| if (! brokerForm.touched || brokerForm.form.pristine) { | |||||
| return; | |||||
| } | |||||
| this.ps.saveBroker(this.broker).subscribe( () => { | |||||
| this.showDialog('updated successfully '); | |||||
| brokerForm.form.markAsPristine(); | |||||
| }, err => { | |||||
| this.showDialog('Failed to Update: ' + err.toString()); | |||||
| }); | |||||
| } | |||||
| public savePassword(): void{ | |||||
| this.ps.savePassword(this.broker.Id, this.ChangePassForm.value).subscribe( | |||||
| () => { | |||||
| this.showDialog('Password Changed'); | |||||
| }, err => { | |||||
| this.showDialog('Failed to Change Password :' + err.toString()); | |||||
| } | |||||
| ); | |||||
| } | } | ||||
| public passEqual(): boolean{ | |||||
| const v = this.ChangePassForm.value; | |||||
| if ( this.ChangePassForm.valid && v.NewPass === v.NewPass1 && this.ChangePassForm.touched) { | |||||
| return true; | |||||
| }else{ | |||||
| this.ChangePassForm.controls['NewPass1'].setErrors({'incorrect': true}); | |||||
| } | |||||
| return false; | |||||
| } | |||||
| public onSelect(ev: SelectEvent): void { | |||||
| if (ev.files) { | |||||
| ev.files.every((file: FileInfo) => { | |||||
| if (file.rawFile && !file.validationErrors) { | |||||
| const reader = new FileReader(); | |||||
| reader.onloadend = () => { | |||||
| const str = reader.result as string; | |||||
| this.ps.updateAvatar(str, this.broker.Id).subscribe( resp => { | |||||
| this.avatarUrl = 'url(' + str + ' )'; | |||||
| }, err => { | |||||
| this.showDialog('Failed to Update Avatar: ' + err.toString()); | |||||
| }); | |||||
| this.fs.clearFiles(); | |||||
| }; | |||||
| reader.readAsDataURL(file.rawFile); | |||||
| }else{ | |||||
| this.showDialog('Only jpg, and png are supported (max 2MB)'); | |||||
| setTimeout(() => { this.fs.clearFiles(); }, 10); | |||||
| } | |||||
| return false; // we only take first file | |||||
| }); | |||||
| } | |||||
| } | |||||
| public showDialog(msg: string): void { | |||||
| this.Message = msg; | |||||
| this.opened = true; // open dialog | |||||
| } | |||||
| public close(status): void { | |||||
| this.opened = false; | |||||
| } | |||||
| } | } |
| <span >{{ dataItem.Amount | currency }}</span> | <span >{{ dataItem.Amount | currency }}</span> | ||||
| </ng-template> | </ng-template> | ||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| <kendo-grid-column field="Description" title="(∑) Description" ></kendo-grid-column> | |||||
| <kendo-grid-column field="Description" title="✅ Description" ></kendo-grid-column> | |||||
| <kendo-grid-column field="Item" title="(∑) From Loan"></kendo-grid-column> | |||||
| <kendo-grid-column field="Status" title="(∑) Loan Status"> | |||||
| <kendo-grid-column field="Item" title="✅ From Loan"></kendo-grid-column> | |||||
| <kendo-grid-column field="Status" title="✅ Loan Status"> | |||||
| <ng-template kendoGridCellTemplate let-dataItem> | <ng-template kendoGridCellTemplate let-dataItem> | ||||
| <span *ngIf="dataItem.Status != 'none'" class="badge badge-success">{{dataItem.Status}}</span> | <span *ngIf="dataItem.Status != 'none'" class="badge badge-success">{{dataItem.Status}}</span> | ||||
| </ng-template> | </ng-template> | ||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| <kendo-grid-column field="Paid" title="(∑) Paid"> </kendo-grid-column> | |||||
| <kendo-grid-column field="Paid" title="✅ Paid"> </kendo-grid-column> | |||||
| </kendo-grid> | </kendo-grid> |
| /* background-color:chartreuse; */ | /* background-color:chartreuse; */ | ||||
| } | } | ||||
| // tslint:disable-next-line:class-name | // tslint:disable-next-line:class-name | ||||
| import {PeopleModel} from './people.model'; | import {PeopleModel} from './people.model'; | ||||
| import {UserExtraModel} from './user-extra.model'; | |||||
| export class apiV1LoginResponse { | |||||
| export class ApiV1LoginResponse { | |||||
| constructor( | constructor( | ||||
| public login: boolean, | public login: boolean, | ||||
| public session: string, | public session: string, | ||||
| public sessionExpire: number, // unix timestamp | public sessionExpire: number, // unix timestamp | ||||
| public role: string, | public role: string, | ||||
| public user: PeopleModel | |||||
| public user: PeopleModel, | |||||
| public userExtra?: UserExtraModel // extra user informaiton | |||||
| ) { | ) { | ||||
| this.login = login; | this.login = login; | ||||
| this.machineId = machineId; | this.machineId = machineId; | ||||
| this.sessionExpire = sessionExpire; | this.sessionExpire = sessionExpire; | ||||
| } | } | ||||
| public static EmptyNew(): apiV1LoginResponse{ | |||||
| return new apiV1LoginResponse( | |||||
| public static EmptyNew(): ApiV1LoginResponse{ | |||||
| return new ApiV1LoginResponse( | |||||
| false, '', '', 0, '', PeopleModel.EmptyNew() ); | false, '', '', 0, '', PeopleModel.EmptyNew() ); | ||||
| } | } | ||||
| import {PeopleModel} from './people.model'; | import {PeopleModel} from './people.model'; | ||||
| import {UserExtraModel} from './user-extra.model'; | |||||
| export class BrokerModel{ | export class BrokerModel{ | ||||
| constructor( | constructor( | ||||
| return new BrokerModel('', '', '', '', '', '', '', | return new BrokerModel('', '', '', '', '', '', '', | ||||
| '', false, '', '', '', ''); | '', false, '', '', '', ''); | ||||
| } | } | ||||
| public static getFromUserAndExtra(u: PeopleModel, ex: UserExtraModel): BrokerModel { | |||||
| return new BrokerModel( | |||||
| u.Id, u.First, u.Last, u.Middle, u.Title, u.Display, u.Nick, ex.Login, ex.Enabled, ex.BSB, ex.ACC, ex.License, ex.Organization | |||||
| ); | |||||
| } | |||||
| } | } |
| export class ChangePassword { | |||||
| public OldPassword: string; | |||||
| public NewPass: string; | |||||
| public NewPass1: string; | |||||
| } |
| export class UserExtraModel { | |||||
| public BSB: string; | |||||
| public ACC: string; | |||||
| public License: string; | |||||
| public Organization: string; | |||||
| public Enabled: boolean; | |||||
| public Login: string; | |||||
| constructor(payload: Partial<UserExtraModel>) { | |||||
| Object.assign(this, payload); | |||||
| } | |||||
| } | |||||
| import {EventEmitter, Injectable, OnDestroy, OnInit} from '@angular/core'; | import {EventEmitter, Injectable, OnDestroy, OnInit} from '@angular/core'; | ||||
| import {HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpParams, HttpRequest} from '@angular/common/http'; | import {HttpClient, HttpEvent, HttpHandler, HttpInterceptor, HttpParams, HttpRequest} from '@angular/common/http'; | ||||
| import {apiV1LoginResponse} from '../models/api-v1-login-response'; | |||||
| import {ApiV1LoginResponse} from '../models/api-v1-login-response'; | |||||
| import {Router} from '@angular/router'; | import {Router} from '@angular/router'; | ||||
| import {PeopleModel} from '../models/people.model'; | import {PeopleModel} from '../models/people.model'; | ||||
| import {UserExtraModel} from '../models/user-extra.model'; | |||||
| @Injectable() | @Injectable() | ||||
| export class AuthService { | export class AuthService { | ||||
| public apiWsUrl = 'wss://svr2021.lawipac.com:8080/api/v1/ws'; | public apiWsUrl = 'wss://svr2021.lawipac.com:8080/api/v1/ws'; | ||||
| // public apiUrl = 'https://c5016.biukop.com.au:8080/api/v1/'; | // public apiUrl = 'https://c5016.biukop.com.au:8080/api/v1/'; | ||||
| // public apiWsUrl = 'wss://c5016.biukop.com.au:8080/api/v1/ws'; | // public apiWsUrl = 'wss://c5016.biukop.com.au:8080/api/v1/ws'; | ||||
| public loggedIn = apiV1LoginResponse.EmptyNew(); | |||||
| loginSuccess = new EventEmitter <apiV1LoginResponse>(); | |||||
| public loggedIn = ApiV1LoginResponse.EmptyNew(); | |||||
| loginSuccess = new EventEmitter <ApiV1LoginResponse>(); | |||||
| constructor( private http: HttpClient , | constructor( private http: HttpClient , | ||||
| private router: Router) { | private router: Router) { | ||||
| public AutoLogin(): void { | public AutoLogin(): void { | ||||
| const sfm: apiV1LoginResponse = JSON.parse(localStorage.getItem('sfm')); | |||||
| const sfm: ApiV1LoginResponse = JSON.parse(localStorage.getItem('sfm')); | |||||
| if (!sfm) { | if (!sfm) { | ||||
| console.log('no auto login'); | console.log('no auto login'); | ||||
| return; | return; | ||||
| } | } | ||||
| this.loggedIn = new apiV1LoginResponse( | |||||
| this.loggedIn = new ApiV1LoginResponse( | |||||
| sfm.login, | sfm.login, | ||||
| sfm.machineId, | sfm.machineId, | ||||
| sfm.session, | sfm.session, | ||||
| sfm.sessionExpire, | sfm.sessionExpire, | ||||
| sfm.role, | sfm.role, | ||||
| new PeopleModel( | |||||
| sfm.user.Id, sfm.user.First, sfm.user.Last, sfm.user.Middle, sfm.user.Title, sfm.user.Display, sfm.user.Nick | |||||
| ) | |||||
| new PeopleModel(sfm.user.Id, sfm.user.First, sfm.user.Last, sfm.user.Middle, sfm.user.Title, sfm.user.Display, sfm.user.Nick) | |||||
| ); | ); | ||||
| if ( sfm.userExtra !== undefined ) { | |||||
| this.loggedIn.userExtra = new UserExtraModel(sfm.userExtra); | |||||
| } | |||||
| this.loginSuccess.emit(this.loggedIn); | this.loginSuccess.emit(this.loggedIn); | ||||
| // console.log ( 'auto login emit events', this.loggedIn); | // console.log ( 'auto login emit events', this.loggedIn); | ||||
| } | } | ||||
| login(email: string, password: string): void { | login(email: string, password: string): void { | ||||
| this.http.post<apiV1LoginResponse>(this.apiUrl + 'login', {u: email, p: password}).subscribe( | |||||
| this.http.post<ApiV1LoginResponse>(this.apiUrl + 'login', {u: email, p: password}).subscribe( | |||||
| responseData => { | responseData => { | ||||
| this.loggedIn.session = responseData['Biukop-Session']; | this.loggedIn.session = responseData['Biukop-Session']; | ||||
| this.loggedIn.login = responseData.login; | this.loggedIn.login = responseData.login; | ||||
| responseData.user.Display, | responseData.user.Display, | ||||
| responseData.user.Nick | responseData.user.Nick | ||||
| ); | ); | ||||
| if (responseData.userExtra !== undefined ) { | |||||
| this.loggedIn.userExtra = new UserExtraModel(responseData.userExtra); | |||||
| } | |||||
| }else{ | }else{ | ||||
| this.loggedIn.user = PeopleModel.EmptyNew(); | this.loggedIn.user = PeopleModel.EmptyNew(); | ||||
| } | } | ||||
| this.saveSessionInfo(); | this.saveSessionInfo(); | ||||
| this.loginSuccess.emit(responseData); | this.loginSuccess.emit(responseData); | ||||
| }, | }, | ||||
| error => { | error => { | ||||
| const fail = apiV1LoginResponse.EmptyNew(); | |||||
| const fail = ApiV1LoginResponse.EmptyNew(); | |||||
| this.loggedIn = fail; | this.loggedIn = fail; | ||||
| console.log('login error', error); | console.log('login error', error); | ||||
| this.loginSuccess.emit(this.loggedIn); | this.loginSuccess.emit(this.loggedIn); | ||||
| } | } | ||||
| logout(): void { | logout(): void { | ||||
| this.loggedIn = apiV1LoginResponse.EmptyNew(); | |||||
| this.loggedIn = ApiV1LoginResponse.EmptyNew(); | |||||
| localStorage.removeItem('sfm'); | localStorage.removeItem('sfm'); | ||||
| this.loginSuccess.emit(this.loggedIn); | this.loginSuccess.emit(this.loggedIn); | ||||
| this.router.navigate(['/login']).then(r => { | this.router.navigate(['/login']).then(r => { |
| import {PeopleModel} from '../models/people.model'; | import {PeopleModel} from '../models/people.model'; | ||||
| import {BrokerModel} from '../models/broker.model'; | import {BrokerModel} from '../models/broker.model'; | ||||
| import {LoanModel} from '../models/loan.model'; | import {LoanModel} from '../models/loan.model'; | ||||
| import {ChangePassword} from '../models/change-password.model'; | |||||
| @Injectable({providedIn: 'root'}) | @Injectable({providedIn: 'root'}) | ||||
| export class PeopleService { | export class PeopleService { | ||||
| return this.http.post<boolean>(this.auth.getUrl('sync-people/'), loan); | return this.http.post<boolean>(this.auth.getUrl('sync-people/'), loan); | ||||
| } | } | ||||
| public updateAvatar(avatar: string, id: string ): Observable<boolean> { | |||||
| return this.http.post<boolean>(this.auth.getUrl('avatar/' + id), avatar); | |||||
| } | |||||
| public savePassword(id: string, change: ChangePassword): Observable<boolean>{ | |||||
| return this.http.post<boolean>(this.auth.getUrl('change-pass/' + id), change); | |||||
| } | |||||
| public saveBroker(broker: BrokerModel): Observable<BrokerModel>{ | |||||
| return this.http.post<BrokerModel>(this.auth.getUrl('broker/' + broker.Id), broker); | |||||
| } | |||||
| } | } |
| import {MenuService} from '../service/menu.service'; | import {MenuService} from '../service/menu.service'; | ||||
| import {AuthService} from '../service/auth.service'; | import {AuthService} from '../service/auth.service'; | ||||
| import {brokerMenuItems, mainMenuItems, peopleMenuItems, userMenuItems} from '../main-menu-items'; | import {brokerMenuItems, mainMenuItems, peopleMenuItems, userMenuItems} from '../main-menu-items'; | ||||
| import {apiV1LoginResponse} from '../models/api-v1-login-response'; | |||||
| import {ApiV1LoginResponse} from '../models/api-v1-login-response'; | |||||
| import {Subscription} from 'rxjs'; | import {Subscription} from 'rxjs'; | ||||
| import {PeopleModel} from '../models/people.model'; | import {PeopleModel} from '../models/people.model'; | ||||
| this.selectMenuShow(this.authService.loggedIn.role); | this.selectMenuShow(this.authService.loggedIn.role); | ||||
| this.loginSub = this.authService.loginSuccess.subscribe( | this.loginSub = this.authService.loginSuccess.subscribe( | ||||
| (rsp: apiV1LoginResponse) => { | |||||
| (rsp: ApiV1LoginResponse) => { | |||||
| this.login = rsp.login; | this.login = rsp.login; | ||||
| this.LoggedInUser = this.authService.loggedIn.user; | this.LoggedInUser = this.authService.loggedIn.user; | ||||
| this.selectMenuShow(rsp.role); | this.selectMenuShow(rsp.role); |
| import { FormGroup } from '@angular/forms'; | |||||
| export function ConfirmedValidator(controlName: string, matchingControlName: string) { | |||||
| return (formGroup: FormGroup) => { | |||||
| const control = formGroup.controls[controlName]; | |||||
| const matchingControl = formGroup.controls[matchingControlName]; | |||||
| if (matchingControl.errors && !matchingControl.errors.confirmedValidator) { | |||||
| return; | |||||
| } | |||||
| if (control.value !== matchingControl.value) { | |||||
| matchingControl.setErrors({ confirmedValidator: true }); | |||||
| } else { | |||||
| matchingControl.setErrors(null); | |||||
| } | |||||
| }; | |||||
| } |