| @@ -48,6 +48,8 @@ import {WebSocketService} from './websocket'; | |||
| import { ChartTypeOfLoansComponent } from './chart-type-of-loans/chart-type-of-loans.component'; | |||
| import { ChartAmountOfLoansComponent } from './chart-amount-of-loans/chart-amount-of-loans.component'; | |||
| import { ChartPastYearMonthlyPerformanceComponent } from './chart-past-year-monthly-performance/chart-past-year-monthly-performance.component'; | |||
| import { ChartRecentTenLoansComponent } from './chart-recent-ten-loans/chart-recent-ten-loans.component'; | |||
| import { ChartTopBrokersComponent } from './chart-top-brokers/chart-top-brokers.component'; | |||
| @@ -68,7 +70,9 @@ import { ChartPastYearMonthlyPerformanceComponent } from './chart-past-year-mont | |||
| TransTailsComponent, | |||
| ChartTypeOfLoansComponent, | |||
| ChartAmountOfLoansComponent, | |||
| ChartPastYearMonthlyPerformanceComponent | |||
| ChartPastYearMonthlyPerformanceComponent, | |||
| ChartRecentTenLoansComponent, | |||
| ChartTopBrokersComponent | |||
| ], | |||
| imports: [ | |||
| BrowserModule, | |||
| @@ -0,0 +1,60 @@ | |||
| <kendo-grid [data]="gridData | async " [scrollable]="'none'"> | |||
| <kendo-grid-column field="Rank" title="ID" width="40"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Amount" title="Amount ($)" width="130"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <span [ngClass]="{'green text-bold': dataItem.Amount > 50000000}">{{ dataItem.Amount | currency }}</span> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Item" title="Loan Property Description"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Settlement" title="Settlement ↓" width="120"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| {{dataItem.Settlement | date: 'yyyy-MM-dd'}} | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Rating" title="Rating" width="110" [resizable]="false" filter="numeric"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <kendo-rating | |||
| [value]="dataItem.Rating" | |||
| [max]="5" | |||
| ></kendo-rating> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Balance" title="Balance($)" width="130"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <span [ngClass]="{'green text-bold': dataItem.Balance < 500000}">{{ dataItem.Balance | currency }}</span> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="OffsetBalance" title="Offset Balance" width="130"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <span [ngClass]="{'red text-bold': dataItem.Percentage > 60}"> | |||
| {{ dataItem.OffsetBalance | currency }} | |||
| </span> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column | |||
| field="OffsetBalance" | |||
| title="Repayment Progress" | |||
| [width]="230" | |||
| [resizable]="false" | |||
| filter="numeric" | |||
| > | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <kendo-sparkline type="bar" | |||
| [data]="dataItem.Percentage" | |||
| [tooltip]="{visible: false}" | |||
| [transitions]="true" | |||
| [seriesDefaults]="{labels: {background: 'none', visible: true, format: '{0}%'}}" | |||
| > | |||
| <kendo-chart-area opacity="0" [width]="200"></kendo-chart-area> | |||
| <kendo-chart-value-axis> | |||
| <kendo-chart-value-axis-item [min]="0" [max]="130"> | |||
| </kendo-chart-value-axis-item> | |||
| </kendo-chart-value-axis> | |||
| </kendo-sparkline> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| </kendo-grid> | |||
| @@ -0,0 +1,23 @@ | |||
| .customer-name { | |||
| display: inline-block; | |||
| vertical-align: middle; | |||
| line-height: 32px; | |||
| padding-left: 10px; | |||
| } | |||
| .red { | |||
| color: #d9534f; | |||
| } | |||
| .green { | |||
| color: #06580f; | |||
| } | |||
| .text-bold { | |||
| font-weight: 600; | |||
| } | |||
| .fullheight_grid { | |||
| height: calc(100vh - 48px) !important; | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { ChartRecentTenLoansComponent } from './chart-recent-ten-loans.component'; | |||
| describe('ChartRecentTenLoansComponent', () => { | |||
| let component: ChartRecentTenLoansComponent; | |||
| let fixture: ComponentFixture<ChartRecentTenLoansComponent>; | |||
| beforeEach(async () => { | |||
| await TestBed.configureTestingModule({ | |||
| declarations: [ ChartRecentTenLoansComponent ] | |||
| }) | |||
| .compileComponents(); | |||
| }); | |||
| beforeEach(() => { | |||
| fixture = TestBed.createComponent(ChartRecentTenLoansComponent); | |||
| component = fixture.componentInstance; | |||
| fixture.detectChanges(); | |||
| }); | |||
| it('should create', () => { | |||
| expect(component).toBeTruthy(); | |||
| }); | |||
| }); | |||
| @@ -0,0 +1,29 @@ | |||
| import { Component, OnInit } from '@angular/core'; | |||
| import {Observable} from 'rxjs'; | |||
| import {Recent10LoansData} from '../models/recent-ten-loans.model'; | |||
| import {HttpClient} from '@angular/common/http'; | |||
| import {AuthService} from '../service/auth.service'; | |||
| import {map} from 'rxjs/operators'; | |||
| @Component({ | |||
| selector: 'app-chart-recent-ten-loans', | |||
| templateUrl: './chart-recent-ten-loans.component.html', | |||
| styleUrls: ['./chart-recent-ten-loans.component.scss'] | |||
| }) | |||
| export class ChartRecentTenLoansComponent implements OnInit { | |||
| gridData: Observable<Recent10LoansData[]>; | |||
| constructor(private http: HttpClient, private auth: AuthService) { } | |||
| ngOnInit(): void { | |||
| this.gridData = this.http.get<Recent10LoansData[]>(this.auth.getUrl('chart/recent-10-loans')).pipe(map( | |||
| data => { | |||
| data.forEach((value, index) => { | |||
| const strPercentage = (100 * value.OffsetBalance / value.Balance).toFixed(1); | |||
| value.Percentage = parseFloat(strPercentage); | |||
| }); | |||
| return data; | |||
| } | |||
| )); | |||
| } | |||
| } | |||
| @@ -0,0 +1,26 @@ | |||
| <kendo-grid [data]="gridData | async " [scrollable]="'none'"> | |||
| <kendo-grid-column field="Rank" title="ID" width="40"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="First" title="First" width="250"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <div class="customer-photo" [ngStyle]="{'background-image' : photoURL(dataItem)}"></div> | |||
| <div class="customer-name"> {{ dataItem.First }} , {{ dataItem.Last }} </div> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="NumOfLoans" title="NumOfLoans"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="NumOfSettledLoans" title="NumOfSettledLoans" width="80"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="NumOfUnSettledLoans" title="NumOfUnSettledLoans" width="80"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="TotalReward" title="TotalReward" width="120"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <span [ngClass]="{'red text-bold': dataItem.TotalReward < 1000000}">{{ dataItem.TotalReward | currency }}</span> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="TotalLoanValue" title="TotalLoanValue" width="120"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <span [ngClass]="{'green text-bold': dataItem.TotalLoanValue < 500000}">{{ dataItem.TotalLoanValue | currency }}</span> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| </kendo-grid> | |||
| @@ -0,0 +1,31 @@ | |||
| .customer-photo { | |||
| display: inline-block; | |||
| width: 32px; | |||
| height: 32px; | |||
| border-radius: 50%; | |||
| background-size: 32px 35px; | |||
| background-position: center center; | |||
| vertical-align: middle; | |||
| line-height: 32px; | |||
| box-shadow: inset 0 0 1px #999, inset 0 0 10px rgba(0,0,0,.2); | |||
| margin-left: 5px; | |||
| } | |||
| .customer-name { | |||
| display: inline-block; | |||
| vertical-align: middle; | |||
| line-height: 32px; | |||
| padding-left: 10px; | |||
| } | |||
| .red { | |||
| color: #d9534f; | |||
| } | |||
| .text-bold { | |||
| font-weight: 600; | |||
| } | |||
| .fullheight_grid { | |||
| height: calc(100vh - 48px) !important; | |||
| } | |||
| @@ -0,0 +1,25 @@ | |||
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||
| import { ChartTopBrokersComponent } from './chart-top-brokers.component'; | |||
| describe('ChartTopBrokersComponent', () => { | |||
| let component: ChartTopBrokersComponent; | |||
| let fixture: ComponentFixture<ChartTopBrokersComponent>; | |||
| beforeEach(async () => { | |||
| await TestBed.configureTestingModule({ | |||
| declarations: [ ChartTopBrokersComponent ] | |||
| }) | |||
| .compileComponents(); | |||
| }); | |||
| beforeEach(() => { | |||
| fixture = TestBed.createComponent(ChartTopBrokersComponent); | |||
| component = fixture.componentInstance; | |||
| fixture.detectChanges(); | |||
| }); | |||
| it('should create', () => { | |||
| expect(component).toBeTruthy(); | |||
| }); | |||
| }); | |||
| @@ -26,27 +26,11 @@ | |||
| </div> | |||
| <bkp-divider-shadow-bottom></bkp-divider-shadow-bottom> | |||
| <bkp-divider><kendo-icon [name]="'clip'"> </kendo-icon> Recent | |||
| Transactions </bkp-divider> | |||
| Settlement </bkp-divider> | |||
| <div class="row"> | |||
| <div class="col-sm-12"> | |||
| <kendo-grid [data]="gridData"> | |||
| <kendo-grid-column field="ProductID" title="ID" width="40"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="ProductName" title="Name" width="250"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Category.CategoryName" title="Category"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="UnitPrice" title="Price" width="80"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="UnitsInStock" title="In stock" width="80"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Discontinued" title="Discontinued" width="120"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <input type="checkbox" [checked]="dataItem.Discontinued" disabled /> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| </kendo-grid> | |||
| <app-chart-recent-ten-loans></app-chart-recent-ten-loans> | |||
| </div> | |||
| </div> | |||
| @@ -55,23 +39,7 @@ | |||
| <div class="row"> | |||
| <div class="col-sm-12"> | |||
| <kendo-grid [data]="gridData"> | |||
| <kendo-grid-column field="ProductID" title="ID" width="40"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="ProductName" title="Name" width="250"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Category.CategoryName" title="Category"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="UnitPrice" title="Price" width="80"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="UnitsInStock" title="In stock" width="80"> | |||
| </kendo-grid-column> | |||
| <kendo-grid-column field="Discontinued" title="Discontinued" width="120"> | |||
| <ng-template kendoGridCellTemplate let-dataItem> | |||
| <input type="checkbox" [checked]="dataItem.Discontinued" disabled /> | |||
| </ng-template> | |||
| </kendo-grid-column> | |||
| </kendo-grid> | |||
| <app-chart-top-brokers></app-chart-top-brokers> | |||
| </div> | |||
| </div> | |||
| @@ -0,0 +1,13 @@ | |||
| export class Recent10LoansData { | |||
| Rank: number; | |||
| Id: string; | |||
| Amount: number; | |||
| Item: string; | |||
| Settlement: Date; | |||
| Rating: number; | |||
| Balance: number; | |||
| OffsetBalance: number; | |||
| Percentage?:number; | |||
| } | |||
| @@ -0,0 +1,15 @@ | |||
| export class TopBrokerModel { | |||
| Rank: number; | |||
| Id: string; | |||
| First: string; | |||
| Last: string; | |||
| NumOfLoans: number; | |||
| NumOfSettledLoans: number; | |||
| NumOfUnSettledLoans: number; | |||
| TotalReward: number; | |||
| TotalLoanValue: number; | |||
| } | |||