| { | { | ||||
| "name": "broker", | "name": "broker", | ||||
| "version": "2.0.37", | |||||
| "version": "2.0.39", | |||||
| "lockfileVersion": 2, | "lockfileVersion": 2, | ||||
| "requires": true, | "requires": true, | ||||
| "packages": { | "packages": { | ||||
| "": { | "": { | ||||
| "name": "broker", | "name": "broker", | ||||
| "version": "2.0.37", | |||||
| "version": "2.0.39", | |||||
| "dependencies": { | "dependencies": { | ||||
| "@angular/animations": "^11.2.9", | "@angular/animations": "^11.2.9", | ||||
| "@angular/common": "^11.2.9", | "@angular/common": "^11.2.9", |
| { | { | ||||
| "name": "broker", | "name": "broker", | ||||
| "version": "2.0.37", | |||||
| "version": "2.0.39", | |||||
| "scripts": { | "scripts": { | ||||
| "ng": "ng", | "ng": "ng", | ||||
| "versionIncrease": "npm --no-git-tag-version version patch", | "versionIncrease": "npm --no-git-tag-version version patch", |
| <p>loan-detail-basic-info works!</p> | |||||
| basic info {{ Loan.Id}} | |||||
| <form class="k-form" #basicInfoForm="ngForm" > | |||||
| <div class="row"> | |||||
| <div class="col-md-6"> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="Lender" text="Lender Organization (Funding Agency)"> | |||||
| </kendo-label> | |||||
| <kendo-combobox name="Lender" | |||||
| [(ngModel)] = "Loan.Lender" #Lender | |||||
| [data]="lenderListView | async" | |||||
| [allowCustom]="true" | |||||
| [loading]="lenderNameService.loading"> | |||||
| </kendo-combobox> | |||||
| <kendo-formhint>info determined by trail income info</kendo-formhint> | |||||
| <kendo-formerror>Error: Lender is required (info determined by trail income info) </kendo-formerror> | |||||
| </kendo-formfield> | |||||
| </div> | |||||
| <div class="col-md-6"> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="LenderLoanNumber" text="Lender's Loan identification"> | |||||
| </kendo-label> | |||||
| <kendo-textbox name="LenderLoanNumber" [(ngModel)] = "Loan.LenderLoanNumber" #LenderLoanNumber [clearButton]="true" > </kendo-textbox> | |||||
| <kendo-formhint>Can not be empty especially when having income</kendo-formhint> | |||||
| <kendo-formerror>Error: LenderLoanNumber is required (an not be empty especially when having income) </kendo-formerror> | |||||
| </kendo-formfield> | |||||
| <div class="vertical-spacer"></div> | |||||
| </div> | |||||
| <div class="col-md-6"> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="Amount" text="Loan Limit"> </kendo-label> | |||||
| <kendo-numerictextbox #Amount name="Amount" [min]="100" [max]="1000000000" [format]="'c0'" [(ngModel)]="Loan.Amount"></kendo-numerictextbox> | |||||
| <kendo-formhint>E.g. 80000, cannot be changed after settlement</kendo-formhint> | |||||
| <kendo-formerror>Error: Limit should be between 100 ~ 1,000,000,000</kendo-formerror> | |||||
| </kendo-formfield> | |||||
| </div> | |||||
| <div class="col-md-6"> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="Settlement" [optional]="false" text="Settlement Date"></kendo-label> | |||||
| <kendo-datepicker #Settlement name="Settlement" | |||||
| [(ngModel)]="Loan.Settlement" | |||||
| [format]="'dd/MM/yyyy'" | |||||
| [min]="minSettlement" [max]="maxSettlement"> | |||||
| </kendo-datepicker> | |||||
| <kendo-formhint>Date settled or expected to be settled</kendo-formhint> | |||||
| </kendo-formfield> | |||||
| </div> | |||||
| <div class="col-sm-12"> | |||||
| <kendo-formfield> | |||||
| <kendo-label [for]="Description" [optional]="false" | |||||
| text="Quick notes: ( < 1000 words ) " | |||||
| (click)="showDemoDescription($event)"></kendo-label> | |||||
| <kendo-editor #Description name="description" style="height: 300px;" [(ngModel)]="Loan.Description"></kendo-editor> | |||||
| </kendo-formfield> | |||||
| </div> | |||||
| </div> | |||||
| <div class="row align-items-center"> | |||||
| <div class="col-sm-1 "> | |||||
| <button kendoButton (click)="save(basicInfoForm)">Save</button> | |||||
| </div> | |||||
| <div class="col-sm-11 "> | |||||
| <div *ngIf="errorMessage !== '' " class="text-danger">{{errorMessage}}</div> | |||||
| </div> | |||||
| </div> | |||||
| </form> |
| kendo-label{ | |||||
| font-weight: bold; | |||||
| background: #f9f9f9; | |||||
| } | |||||
| kendo-formhint, | |||||
| kendo-formerror{ | |||||
| background: #f9f9f9; | |||||
| } |
| import { Component, Input, OnInit } from '@angular/core'; | import { Component, Input, OnInit } from '@angular/core'; | ||||
| import {LoanModel} from '../../models/loan.model'; | import {LoanModel} from '../../models/loan.model'; | ||||
| import {NgForm} from '@angular/forms'; | |||||
| import {HttpErrorResponse} from '@angular/common/http'; | |||||
| import {Observable} from 'rxjs'; | |||||
| import {LoanSingleService} from '../../service/loan.single.service'; | |||||
| import {LenderNameService} from '../../service/lender-name.service'; | |||||
| import { NotificationService } from '@progress/kendo-angular-notification'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-loan-detail-basic-info', | selector: 'app-loan-detail-basic-info', | ||||
| }) | }) | ||||
| export class LoanDetailBasicInfoComponent implements OnInit { | export class LoanDetailBasicInfoComponent implements OnInit { | ||||
| @Input() Loan: LoanModel; | @Input() Loan: LoanModel; | ||||
| constructor() { } | |||||
| public lenderListView: Observable<string[]>; | |||||
| public minSettlement: Date = new Date(2015, 0, 1); | |||||
| public maxSettlement: Date = new Date(2030, 4, 31); | |||||
| public errorMessage=''; | |||||
| constructor( private service: LoanSingleService, | |||||
| private notificationService: NotificationService, | |||||
| public lenderNameService: LenderNameService) { | |||||
| } | |||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.lenderListView = this.lenderNameService; | |||||
| this.lenderNameService.query(); | |||||
| } | } | ||||
| public save(basicInfoForm: NgForm): void { | |||||
| if ( ! basicInfoForm.valid ) { | |||||
| basicInfoForm.form.markAllAsTouched(); | |||||
| return ; | |||||
| } | |||||
| this.errorMessage = ''; | |||||
| this.service.updateBasicInfo(this.Loan).subscribe( | |||||
| resp => { | |||||
| if ( this.Loan.Id === '' ) { | |||||
| this.Loan.Id = resp.Id; | |||||
| } | |||||
| this.showSuccess(this.Loan.Id + ' saved successfully'); | |||||
| }, | |||||
| err => { | |||||
| this.errorMessage = err instanceof HttpErrorResponse ? err.statusText : 'unknown error occured'; | |||||
| this.showError(this.errorMessage); | |||||
| } | |||||
| ); | |||||
| } | |||||
| public showDemoDescription($event): void{ | |||||
| let DemoDescription = ` | |||||
| <h1> Rich Text Editing </h1> | |||||
| <table> | |||||
| <tr> <td> | |||||
| <ol> | |||||
| <li>Text formatting</li> | |||||
| <li>Bulleted and numbered lists</li> | |||||
| <li>Hyperlinks</li> | |||||
| <li>Cross-browser support</li> | |||||
| <li>Identical HTML output across browsers</li> | |||||
| </ol> | |||||
| </td> <td width="20%" text-align="right"> | |||||
| <img src="https://edge.alluremedia.com.au/uploads/businessinsider/2015/05/P2P-to-date.jpg" | |||||
| width=300"> | |||||
| </td> | |||||
| </tr> | |||||
| </table> | |||||
| `; | |||||
| this.Loan.Description = DemoDescription; | |||||
| } | |||||
| public showSuccess(msg : string ): void { | |||||
| this.notificationService.show({ | |||||
| content: msg, | |||||
| cssClass: "button-notification", | |||||
| animation: { type: "slide", duration: 400 }, | |||||
| position: { horizontal: "center", vertical: "bottom" }, | |||||
| type: { style: "success", icon: true }, | |||||
| closable: true, | |||||
| }); | |||||
| } | |||||
| public showError(err: string): void { | |||||
| this.notificationService.show({ | |||||
| content: err, | |||||
| cssClass: "button-notification", | |||||
| animation: { type: "slide", duration: 400 }, | |||||
| position: { horizontal: "center", vertical: "bottom" }, | |||||
| type: { style: "error", icon: true }, | |||||
| closable: true, | |||||
| }); | |||||
| } | |||||
| } | } |
| public Lender?: string; | public Lender?: string; | ||||
| public LenderLoanNumber?: string; | public LenderLoanNumber?: string; | ||||
| public Client?: PeopleModel[]; | public Client?: PeopleModel[]; | ||||
| public ClientIds: string[]; | |||||
| public Broker?: BrokerModel[]; | public Broker?: BrokerModel[]; | ||||
| public BrokerIds: string[]; | |||||
| public OtherRewarder?: PeopleModel[]; | public OtherRewarder?: PeopleModel[]; | ||||
| public OtherRewarderIds: string[]; | |||||
| public Reward?: RewardModel[]; | public Reward?: RewardModel[]; | ||||
| public RewardPeople?: PeopleModel[]; | public RewardPeople?: PeopleModel[]; | ||||
| public PayIn?: PayInModel[]; | public PayIn?: PayInModel[]; | ||||
| this.Client = []; | this.Client = []; | ||||
| } | } | ||||
| if ( payload.ClientIds && payload.ClientIds.length > 0 ){ | |||||
| this.ClientIds = payload.ClientIds; | |||||
| } else{ | |||||
| this.ClientIds = []; | |||||
| } | |||||
| if (payload.Broker && payload.Broker.length > 0 ) { | if (payload.Broker && payload.Broker.length > 0 ) { | ||||
| this.setBroker(payload.Broker); | this.setBroker(payload.Broker); | ||||
| }else{ | }else{ | ||||
| this.Broker = []; | this.Broker = []; | ||||
| } | } | ||||
| if ( payload.BrokerIds && payload.BrokerIds.length > 0 ){ | |||||
| this.BrokerIds = payload.BrokerIds; | |||||
| } else{ | |||||
| this.BrokerIds = []; | |||||
| } | |||||
| if (payload.OtherRewarder && payload.OtherRewarder.length > 0 ) { | if (payload.OtherRewarder && payload.OtherRewarder.length > 0 ) { | ||||
| this.setOtherRewarder(payload.OtherRewarder); | this.setOtherRewarder(payload.OtherRewarder); | ||||
| }else{ | }else{ | ||||
| this.OtherRewarder = []; | this.OtherRewarder = []; | ||||
| } | } | ||||
| if ( payload.OtherRewarderIds && payload.OtherRewarderIds.length > 0 ){ | |||||
| this.OtherRewarderIds = payload.OtherRewarderIds; | |||||
| } else{ | |||||
| this.OtherRewarderIds = []; | |||||
| } | |||||
| if (payload.Reward && payload.Reward.length > 0 ) { | if (payload.Reward && payload.Reward.length > 0 ) { | ||||
| this.setReward(payload.Reward); | this.setReward(payload.Reward); | ||||
| }else{ | }else{ | ||||
| ); | ); | ||||
| }); | }); | ||||
| } | } | ||||
| private setOtherRewarder(v: any[]): void{ | private setOtherRewarder(v: any[]): void{ | ||||
| this.OtherRewarder = []; | this.OtherRewarder = []; | ||||
| v.forEach((c) => { | v.forEach((c) => { |
| import { Observable, BehaviorSubject } from 'rxjs'; | import { Observable, BehaviorSubject } from 'rxjs'; | ||||
| import { map, tap } from 'rxjs/operators'; | import { map, tap } from 'rxjs/operators'; | ||||
| import {AuthService} from './auth.service'; | import {AuthService} from './auth.service'; | ||||
| import {LoanModel} from '../models/loan.model'; | |||||
| export abstract class LoanQueryService extends BehaviorSubject<GridDataResult> { | export abstract class LoanQueryService extends BehaviorSubject<GridDataResult> { | ||||
| public loading: boolean; | public loading: boolean; | ||||
| } | } | ||||
| public query(state: any): void { | public query(state: any): void { | ||||
| this.fetch(this.tableName, state) | |||||
| .subscribe(x => super.next(x)); | |||||
| this.fetch(this.tableName, state).subscribe(x => { | |||||
| var ret: GridDataResult = {total: x.total, data:[]}; | |||||
| x.data.forEach( v => { | |||||
| ret.data.push (new LoanModel(v)); //conver to LoanModel | |||||
| }); | |||||
| console.log(ret); | |||||
| super.next(ret); | |||||
| }); | |||||
| } | } | ||||
| protected fetch(tableName: string, state: any): Observable<GridDataResult> { | protected fetch(tableName: string, state: any): Observable<GridDataResult> { |