import {Component, EventEmitter, Input, OnInit, Output, ViewChild, ViewContainerRef, ViewEncapsulation} from '@angular/core'; import { CellCloseEvent, DataStateChangeEvent, GridComponent, GridDataResult, SelectableSettings, SelectionEvent } from '@progress/kendo-angular-grid'; import {CompositeFilterDescriptor, SortDescriptor, toODataString} from '@progress/kendo-data-query'; import {LoanSummaryService} from '../service/loan_summary.service'; import {AuthService} from '../service/auth.service'; import {Observable} from 'rxjs'; import {Router} from '@angular/router'; import {LoanModel} from '../models/loan.model'; import {LoanSelectComponent} from '../loan-select/loan-select.component'; import {NotificationService, Type} from '@progress/kendo-angular-notification'; import {animate, style, transition, trigger} from '@angular/animations'; @Component({ selector: 'app-list-all-loans', templateUrl: './list-all-loans.component.html', styleUrls: ['./list-all-loans.component.scss'], encapsulation: ViewEncapsulation.Emulated, animations: [ trigger('fadeIn', [ transition(':enter', [ style({ opacity: '0' }), animate('.5s ease-out', style({ opacity: '1'})), ]), ]), trigger('slideOutUp', [ transition(':leave', [ style({ opacity: '1' }), animate('.5s ease-out', style({ opacity: '0' })), ]), ]), ], }) export class ListAllLoansComponent implements OnInit { public view: LoanSummaryService; public sort: Array = [{dir: 'desc', field: 'Settlement'}]; public filter: CompositeFilterDescriptor; public pageSize = 20; public skip = 0; @Output() LoanSelected: EventEmitter = new EventEmitter(); @Output() Cancelled: EventEmitter = new EventEmitter(); @Output() LoanClicked: EventEmitter = new EventEmitter(); @Input() EnableExportExcel = false; @Input() EnableExportPdf = false; @Input() EnableSelectButton = false; @Input() FinishButtonText = 'Finish Select'; @Input() MaxSelect = 1; @Input() Preselect: LoanModel[] = []; public SelectedLoans: LoanModel[] = []; public selectableSettings: SelectableSettings|boolean; private privateSingleSelection = true; public gridSelection: string[] = []; @ViewChild(GridComponent, { static: true }) public grid: GridComponent; @ViewChild(GridComponent, { read: ViewContainerRef }) public gridVR: ViewContainerRef; constructor(private service: LoanSummaryService, private auth: AuthService, private router: Router, private notificationService: NotificationService) { } public ngOnInit(): void { // Bind directly to the service as it is a Subject this.view = this.service; // Fetch the data with the initial state this.loadData(); // selectable this.setSelectableSettings(); // Preselect on Init only this.Preselect.forEach( v => { if ( v !== undefined && v !== null && v.Id !== '' ){ this.AddLoanToSelection(v); this.gridSelection.unshift(v.Id); } }); } @Input() set SingleSelection(single: boolean) { this.privateSingleSelection = single; this.setSelectableSettings(); } get SingleSelection(): boolean{ return this.privateSingleSelection; } public setSelectableSettings(): void { this.privateSingleSelection = this.MaxSelect === 1; if ( this.EnableSelectButton ){ this.selectableSettings = { checkboxOnly: true, mode: this.privateSingleSelection ? 'single' : 'multiple', drag: false, }; }else{ this.selectableSettings = false; } } public dataStateChange({ skip, take, sort, filter }: DataStateChangeEvent): void { // Save the current state of the Grid component this.skip = skip; this.pageSize = take; this.sort = sort; this.filter = filter; // Reload the data with the new state this.loadData(); // Expand the first row initially // this.grid.expandRow(0); } public filterChange(filter: CompositeFilterDescriptor): void { this.filter = filter; console.log(filter); } private loadData(): void { this.service.queryAsLoanModel({ skip: this.skip, take: this.pageSize, sort: this.sort, filter: this.filter}); } private photoURL(peopleId: any): string { const url = this.auth.getUrl('avatar/') + peopleId; return 'url("' + url + '")'; } public allData = (): Observable => { return this.service.queryAll({skip: 0, take: 999999, sort: this.sort, filter: this.filter}); } public onCellClick(event: CellCloseEvent): void { this.LoanClicked.emit(event.dataItem); } public AddLoanToSelection(loan: LoanModel): void{ const idx = this.SelectedLoans.findIndex( v => { return v.Id === loan.Id; }); if ( idx === -1 ) { // not found this.SelectedLoans.unshift(loan); } } public onFinishSelection(): void{ if ( this.MaxSelect === 1 ){ this.LoanSelected.emit(this.SelectedLoans[0]); }else{ this.LoanSelected.emit(this.SelectedLoans); } this.notifyUser('try to save'); } public onCancelSelection(): void{ if ( this.MaxSelect === 1 ){ this.Cancelled.emit(this.SelectedLoans[0]); }else{ this.Cancelled.emit(this.SelectedLoans); } this.notifyUser('cancel saving'); } public RemoveFromSelection(l: LoanModel): void{ this.SelectedLoans = this.SelectedLoans.filter( v => l.Id !== v.Id ); this.gridSelection = this.gridSelection.filter( v => v !== l.Id ); } public onSelectionChange(sel: SelectionEvent): void { // to avoid race condition, we do action after 200ms setTimeout( () => { sel.deselectedRows.forEach(v => { this.RemoveFromSelection(v.dataItem); }); sel.selectedRows.forEach(v => { if ( this.SelectedLoans.length < this.MaxSelect) { this.AddLoanToSelection(v.dataItem); }else{ // remove those that was added by grid selection this.gridSelection = this.gridSelection.filter( existing => existing !== v.dataItem.Id ); this.notifyUser('Maximum selection reached', { style: 'warning', icon: true }); } }); }, 200); } public notifyUser( msg: string, lookAndFeel?: Type): void { if (lookAndFeel === undefined ){ lookAndFeel = { style: 'success', icon: true }; } this.notificationService.show({ appendTo: this.gridVR, content: msg, cssClass: 'button-notification', animation: { type: 'slide', duration: 400 }, position: { horizontal: 'right', vertical: 'top' }, type: lookAndFeel, closable: false, hideAfter: 5000, }); } public getMileStone( di: LoanModel) : any { let ret = [ { text: 'ApplicationReceived :' + this.dateToText(di.ApplicationReceived) }, { text: 'Lodgement : ' + this.dateToText(di.Lodgement)}, { text: 'ValuationOrdered : ' + this.dateToText(di.ValuationOrdered)}, { text: 'ValuationCompleted: ' + this.dateToText(di.ValuationCompleted)}, { text: 'ConditionalApproved: ' + this.dateToText(di.ConditionalApproved)}, { text: 'OutstandingReturned: ' + this.dateToText(di.OutstandingReturned)}, { text: 'FormalApproved: ' + this.dateToText(di.FormalApproved)}, { text: 'SettlementBooked: ' + this.dateToText(di.SettlementBooked)}, { text: 'SettlementCompleted: ' + this.dateToText(di.SettlementCompleted)}, ]; return ret ; } private dateToText(d: Date): string { if ( !d ) { return " ----- "; } if (d.getFullYear() < 1900 ) { return "----" }else{ return d.toLocaleDateString("en-US") } } }