| @@ -1,11 +1,12 @@ | |||
| .container.outer{ | |||
| width:100%; | |||
| background: url('../../assets/img/body_bg.jpg') no-repeat center center fixed; | |||
| max-width:100vw; | |||
| background: url('../../assets/img/body_bg.jpg') no-repeat center center fixed; | |||
| -webkit-background-size: cover; | |||
| -moz-background-size: cover; | |||
| -o-background-size: cover; | |||
| background-size: cover; | |||
| opacity:0.98; | |||
| opacity:0.98; | |||
| } | |||
| .container.inner { | |||
| width: 99%; | |||
| @@ -68,7 +68,7 @@ | |||
| <kendo-label [for]="Settlement" [optional]="false" text="Settlement Date"></kendo-label> | |||
| <kendo-datepicker #Settlement name="Settlement" | |||
| [(ngModel)]="Loan.Settlement" | |||
| [min]="minSettlement" [max]="maxSettlement"> | |||
| [min]="minSettlement" [max]="maxSettlement" required> | |||
| </kendo-datepicker> | |||
| <kendo-formhint>Date settled or expected to be settled</kendo-formhint> | |||
| </kendo-formfield> | |||
| @@ -46,7 +46,7 @@ export class TrailIncomeComponent implements OnInit { | |||
| let balance = -1; | |||
| let offsetBalance = -1; | |||
| if ( this.Loan.PayIn.length >= 0) { | |||
| if ( this.Loan.PayIn.length > 0) { | |||
| const idx = this.Loan.PayIn.length -1; | |||
| balance = this.Loan.PayIn[idx].Balance; | |||
| offsetBalance = this.Loan.PayIn[idx].OffsetBalance; | |||
| @@ -85,6 +85,16 @@ export class TrailIncomeComponent implements OnInit { | |||
| public saveHandler({ sender, rowIndex, formGroup, isNew }): void { | |||
| const v = formGroup.getRawValue(); | |||
| if ( this.Loan.Lender === '') { | |||
| this.errorOccurred.emit('Lender should not be empty'); | |||
| return; | |||
| } | |||
| if ( this.Loan.LenderLoanNumber === '') { | |||
| this.errorOccurred.emit('Lender Identification should not be empty'); | |||
| return; | |||
| } | |||
| if ( !this.showBalance) { v.Balance = -1; } | |||
| if ( !this.showOffsetBalance) { v.OffsetBalance = -1; } | |||
| @@ -1,4 +1,4 @@ | |||
| import { faChartArea, faChartPie, faIdCard, faIdCardAlt, faMoneyCheck, faUniversity, faUserCircle } from '@fortawesome/free-solid-svg-icons'; | |||
| import { faChartArea, faIdCard, faIdCardAlt, faMoneyCheck, faUniversity, faUserCircle } from '@fortawesome/free-solid-svg-icons'; | |||
| export const mainMenuItems: any[] = [ | |||
| { | |||
| @@ -60,3 +60,28 @@ export const mainMenuItems: any[] = [ | |||
| ] | |||
| } | |||
| ]; | |||
| export const brokerMenuItems: any[] = [ | |||
| { | |||
| text: 'broker', | |||
| fa: faUniversity, | |||
| url: './#canvas' | |||
| }, | |||
| ]; | |||
| export const userMenuItems: any[] = [ | |||
| { | |||
| text: 'user', | |||
| fa: faUniversity, | |||
| url: './#canvas' | |||
| }, | |||
| ]; | |||
| export const peopleMenuItems: any[] = [ | |||
| { | |||
| text: 'people', | |||
| fa: faUniversity, | |||
| url: './#canvas' | |||
| }, | |||
| ]; | |||
| @@ -3,13 +3,12 @@ | |||
| // tslint:disable-next-line:class-name | |||
| export class apiV1LoginResponse { | |||
| // tslint:disable-next-line:typedef | |||
| constructor( | |||
| public login: boolean, | |||
| public machineId: string, | |||
| public session: string, | |||
| public sessionExpire: number // unix timestamp | |||
| public sessionExpire: number, // unix timestamp | |||
| public role: string | |||
| ) { | |||
| this.login = login; | |||
| this.machineId = machineId; | |||
| @@ -17,7 +16,12 @@ export class apiV1LoginResponse { | |||
| this.sessionExpire = sessionExpire; | |||
| } | |||
| // tslint:disable-next-line:typedef | |||
| public static EmptyNew(): apiV1LoginResponse{ | |||
| return new apiV1LoginResponse( | |||
| false, '', '', 0, '' | |||
| ); | |||
| } | |||
| public hasValidSession(): boolean { | |||
| if (this.session === undefined || this.session === '') { | |||
| return false; | |||
| @@ -26,7 +30,6 @@ export class apiV1LoginResponse { | |||
| } | |||
| } | |||
| // tslint:disable-next-line:typedef | |||
| public hasValidMachineId(): boolean { | |||
| if (this.machineId === undefined || this.machineId === '') { | |||
| return false; | |||
| @@ -10,7 +10,7 @@ export class AuthService { | |||
| public apiWsUrl = 'wss://svr2021.lawipac.com:8080/api/v1/ws'; | |||
| // public apiUrl = 'https://c5016.biukop.com.au:8080/api/v1/'; | |||
| // public apiWsUrl = 'wss://c5016.biukop.com.au:8080/api/v1/ws'; | |||
| public loggedIn = new apiV1LoginResponse(false, '', '', 0 ); | |||
| public loggedIn = apiV1LoginResponse.EmptyNew(); | |||
| loginSuccess = new EventEmitter <apiV1LoginResponse>(); | |||
| constructor( private http: HttpClient , | |||
| @@ -28,7 +28,8 @@ export class AuthService { | |||
| sfm.login, | |||
| sfm.machineId, | |||
| sfm.session, | |||
| sfm.sessionExpire | |||
| sfm.sessionExpire, | |||
| sfm.role | |||
| ); | |||
| this.loginSuccess.emit(this.loggedIn); | |||
| // console.log ( 'auto login emit events', this.loggedIn); | |||
| @@ -56,11 +57,12 @@ export class AuthService { | |||
| this.loggedIn.login = responseData.login; | |||
| this.loggedIn.machineId = responseData['Biukop-Mid']; | |||
| this.loggedIn.sessionExpire = responseData.sessionExpire; | |||
| this.loggedIn.role = responseData.role; | |||
| this.saveSessionInfo(); | |||
| this.loginSuccess.emit(responseData); | |||
| }, | |||
| error => { | |||
| const fail = new apiV1LoginResponse(false, '', '', 0); | |||
| const fail = apiV1LoginResponse.EmptyNew(); | |||
| this.loggedIn = fail; | |||
| console.log('login error', error); | |||
| this.loginSuccess.emit(this.loggedIn); | |||
| @@ -70,7 +72,7 @@ export class AuthService { | |||
| } | |||
| logout(): void { | |||
| this.loggedIn = new apiV1LoginResponse(false, '', '', 0); | |||
| this.loggedIn = apiV1LoginResponse.EmptyNew(); | |||
| localStorage.removeItem('sfm'); | |||
| this.loginSuccess.emit(this.loggedIn); | |||
| this.router.navigate(['/login']).then(r => { | |||
| @@ -1,4 +1,4 @@ | |||
| <kendo-appbar id='topBar' *ngIf='login' class='appbar' [position]="'top'" [positionMode]="'sticky'"> | |||
| <kendo-appbar id='topBar' *ngIf='login && showMenu' class='appbar' [position]="'top'" [positionMode]="'sticky'"> | |||
| <kendo-appbar-section> | |||
| <kendo-menu [items]="items" (select)="onSelect($event)"> | |||
| <ng-template kendoMenuItemTemplate let-item="item"> | |||
| @@ -10,7 +10,7 @@ | |||
| </kendo-appbar-section> | |||
| <kendo-appbar-spacer></kendo-appbar-spacer> | |||
| <kendo-appbar-section class="actions"> | |||
| <kendo-badge-container> | |||
| <kendo-badge-container *ngIf="false"> | |||
| <button class="k-button k-button-clear"> | |||
| <kendo-icon [name]="'bell'"></kendo-icon> | |||
| </button> | |||
| @@ -20,6 +20,16 @@ | |||
| </kendo-appbar-section> | |||
| <kendo-appbar-section> | |||
| <kendo-avatar [imageSrc]="Avatar" [shape]="'circle'" [width]="'26px'" [height]="'26px'"></kendo-avatar> | |||
| <kendo-avatar [imageSrc]="Avatar" [shape]="'circle'" [width]="'26px'" [height]="'26px'" (click)="logout()"></kendo-avatar> | |||
| </kendo-appbar-section> | |||
| </kendo-appbar> | |||
| <kendo-dialog title="Please confirm" *ngIf="opened" (close)="close('cancel')" [minWidth]="250" [width]="450"> | |||
| <p style="margin: 30px; text-align: center;">Are you sure you want to continue?</p> | |||
| <kendo-dialog-actions> | |||
| <button kendoButton (click)="close('no')">No</button> | |||
| <button kendoButton (click)="close('yes')" primary="true">Yes</button> | |||
| </kendo-dialog-actions> | |||
| </kendo-dialog> | |||
| @@ -1,10 +1,11 @@ | |||
| import {Component, OnDestroy, OnInit} from '@angular/core'; | |||
| import {MenuService} from '../service/menu.service'; | |||
| import {AuthService} from '../service/auth.service'; | |||
| import {mainMenuItems} from '../main-menu-items'; | |||
| import {brokerMenuItems, mainMenuItems, peopleMenuItems, userMenuItems} from '../main-menu-items'; | |||
| import {apiV1LoginResponse} from '../models/api-v1-login-response'; | |||
| import {Subscription} from 'rxjs'; | |||
| @Component({ | |||
| selector: 'app-top-bar', | |||
| templateUrl: './top-bar.component.html', | |||
| @@ -12,11 +13,16 @@ import {Subscription} from 'rxjs'; | |||
| }) | |||
| export class TopBarComponent implements OnInit , OnDestroy { | |||
| login = false; | |||
| Avatar = './assets/img/avatar.png'; | |||
| Avatar = './assets/img/logout.png'; | |||
| public items: any[] = mainMenuItems; | |||
| private loginSub: Subscription; | |||
| public showMenu = true; | |||
| public opened = false; | |||
| constructor(private menuService: MenuService, private authService: AuthService,) { } | |||
| constructor(private menuService: MenuService, | |||
| private authService: AuthService) { | |||
| } | |||
| ngOnInit(): void { | |||
| this.initAndSubLogin(); | |||
| @@ -24,15 +30,39 @@ export class TopBarComponent implements OnInit , OnDestroy { | |||
| public initAndSubLogin(): void{ | |||
| this.login = this.authService.loggedIn.login; | |||
| console.log('subscribe auto login'); | |||
| this.selectMenuShow(this.authService.loggedIn.role); | |||
| // console.log('subscribe auto login', this.authService.loggedIn); | |||
| this.loginSub = this.authService.loginSuccess.subscribe( | |||
| (rsp: apiV1LoginResponse) => { | |||
| this.login = rsp.login; | |||
| this.selectMenuShow(rsp.role); | |||
| console.log ('topbar received auth events', rsp); | |||
| } | |||
| ); | |||
| } | |||
| private selectMenuShow(role: string): void { | |||
| this.showMenu = true; | |||
| switch ( role ){ | |||
| case 'admin': | |||
| this.items = mainMenuItems; | |||
| break; | |||
| case 'broker': | |||
| this.items = brokerMenuItems; | |||
| break; | |||
| case 'user': | |||
| this.items = userMenuItems; | |||
| break; | |||
| case 'people': | |||
| this.items = peopleMenuItems; | |||
| break; | |||
| default: | |||
| this.showMenu = false; | |||
| } | |||
| } | |||
| // check menuItem has fontawesome | |||
| public menuItemHasFontawesome(item: any): boolean { | |||
| return item.hasOwnProperty('fa'); | |||
| @@ -57,4 +87,14 @@ export class TopBarComponent implements OnInit , OnDestroy { | |||
| this.loginSub.unsubscribe(); | |||
| } | |||
| public logout(): void{ | |||
| this.opened = true; | |||
| } | |||
| public close(action: string): void { | |||
| this.opened = false; | |||
| if ( action === 'yes') { | |||
| this.authService.logout(); | |||
| } | |||
| } | |||
| } | |||