| import { UploadDetailComponent } from './upload-detail/upload-detail.component'; | import { UploadDetailComponent } from './upload-detail/upload-detail.component'; | ||||
| import {SafeUrlPipe} from './pipe/safe.url.pipe'; | import {SafeUrlPipe} from './pipe/safe.url.pipe'; | ||||
| import { ImagePopupDialogComponent } from './image-popup-dialog/image-popup-dialog.component'; | import { ImagePopupDialogComponent } from './image-popup-dialog/image-popup-dialog.component'; | ||||
| import { PopupIncomeFilterComponent } from './popup-income-filter/popup-income-filter.component'; | |||||
| UploadCardsComponent, | UploadCardsComponent, | ||||
| UploadDetailComponent, | UploadDetailComponent, | ||||
| SafeUrlPipe, | SafeUrlPipe, | ||||
| ImagePopupDialogComponent | |||||
| ImagePopupDialogComponent, | |||||
| PopupIncomeFilterComponent | |||||
| ], | ], | ||||
| imports: [ | imports: [ | ||||
| BrowserModule, | BrowserModule, |
| import {SortDescriptor} from '@progress/kendo-data-query'; | |||||
| export class PayInListFilterModel { | export class PayInListFilterModel { | ||||
| LoanIds: string[]; | LoanIds: string[]; | ||||
| Uploads: string[]; | |||||
| UploadIds: string[]; | |||||
| Take: number; | Take: number; | ||||
| Skip: number; | Skip: number; | ||||
| TsFrom: Date; | TsFrom: Date; | ||||
| TsTo: Date; | TsTo: Date; | ||||
| IdFrom: number; | IdFrom: number; | ||||
| IdTo: number; | IdTo: number; | ||||
| IncomeFrom: number; | |||||
| IncomeTo: number; | |||||
| TrailFrom: number; | |||||
| TrailTo: number; | |||||
| BalanceFrom: number; | |||||
| BalanceTo: number; | |||||
| AmountFrom: number; | |||||
| AmountTo: number; | |||||
| Sort?: SortDescriptor[]; | |||||
| constructor(payload: Partial<PayInListFilterModel>) { | |||||
| this.LoanIds = []; | |||||
| if (payload.LoanIds !== undefined && payload.LoanIds.length > 0) { | |||||
| payload.LoanIds.forEach(v => { this.LoanIds.push(v); }); | |||||
| } | |||||
| this.UploadIds = []; | |||||
| if (payload.UploadIds !== undefined && payload.UploadIds.length > 0 ) { | |||||
| payload.UploadIds.forEach(v => { this.UploadIds.push(v); }); | |||||
| } | |||||
| const bigNumber = 9999999999; | |||||
| this.Take = payload.Take || 10; | |||||
| this.Skip = payload.Skip || 0; | |||||
| this.TsFrom = payload.TsFrom? new Date(payload.TsFrom) : new Date('1900-01-01'); | |||||
| this.TsTo = payload.TsTo? new Date(payload.TsTo) : new Date('2038-01-01'); | |||||
| this.IdFrom = payload.IdFrom || 0; | |||||
| this.IdTo = payload.IdTo || bigNumber; | |||||
| this.TrailFrom = payload.TrailFrom || 0; | |||||
| this.TrailTo = payload.TrailTo || bigNumber; | |||||
| this.BalanceFrom = payload.BalanceFrom || -1 ; | |||||
| this.BalanceTo = payload.BalanceTo || bigNumber; | |||||
| this.AmountFrom = payload.AmountFrom || 0; | |||||
| this.AmountTo = payload.AmountTo || bigNumber; | |||||
| } | |||||
| } | } |
| <kendo-grid [data]="gridData" | <kendo-grid [data]="gridData" | ||||
| [pageable]="pageable" | |||||
| [pageSize]="filter.Take" | |||||
| [skip]="filter.Skip" | |||||
| [sortable]="sortable" | |||||
| [filterable]="filterable" | |||||
| [loading]="loading" | |||||
| [sort]="filter.Sort" | |||||
| (add)="addHandler($event)" | (add)="addHandler($event)" | ||||
| (cancel)="cancelHandler($event)" | (cancel)="cancelHandler($event)" | ||||
| (save)="saveHandler($event)" | (save)="saveHandler($event)" | ||||
| (edit)="editHandler($event)" | (edit)="editHandler($event)" | ||||
| (remove)="removeHandler($event)" | (remove)="removeHandler($event)" | ||||
| (pageChange)="pageChange($event)" | |||||
| (sortChange)="sortChange($event)" | |||||
| > | > | ||||
| <ng-template kendoGridToolbarTemplate> | <ng-template kendoGridToolbarTemplate> | ||||
| <div style="width:100%; margin:0px; display:block"> | <div style="width:100%; margin:0px; display:block"> | ||||
| <button kendoGridAddCommand icon="plus" >Add new Income</button> | <button kendoGridAddCommand icon="plus" >Add new Income</button> | ||||
| </div> | </div> | ||||
| <div [ngStyle]="{'width': allowAddNew? '70%': '100%'}" class="filter-panel-wrapper" > | <div [ngStyle]="{'width': allowAddNew? '70%': '100%'}" class="filter-panel-wrapper" > | ||||
| <button kendoButton icon="filter" >Loan</button> | |||||
| <button kendoButton icon="filter" (click)="showFilter()" >Filter</button> | |||||
| <button kendoButton icon="filter" >Upload</button> | <button kendoButton icon="filter" >Upload</button> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </ng-template> | </ng-template> | ||||
| </kendo-grid-command-column> | </kendo-grid-command-column> | ||||
| <kendo-grid-column field="Id" title="Id" width="50" editable="false"> | |||||
| <kendo-grid-column field="Id" title="Id" width="50" editable="false" > | |||||
| <ng-template kendoGridFilterCellTemplate let-filter let-column="column"> | |||||
| <kendo-grid-numeric-filter-cell [column]="column" [filter]="filter" [showOperators]="false" > | |||||
| </kendo-grid-numeric-filter-cell> | |||||
| </ng-template> | |||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| <kendo-grid-column field="Trail" title="Trail Received" width="200" format="{0:c}" editor="numeric"> | |||||
| <kendo-grid-column field="Trail" title="Trail Received" width="150" format="{0:c}" editor="numeric"> | |||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| <kendo-grid-column field="Ts" title="Trail Date" editor="date"> | |||||
| <kendo-grid-column field="Ts" title="Trail Date" editor="date" width="100"> | |||||
| <ng-template kendoGridCellTemplate let-dataItem> | <ng-template kendoGridCellTemplate let-dataItem> | ||||
| {{ dataItem.Ts | date: 'yyyy-MM-dd' }} | {{ dataItem.Ts | date: 'yyyy-MM-dd' }} | ||||
| </ng-template> | </ng-template> | ||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| <kendo-grid-column field="Balance" title="Balance" width="220"> | |||||
| <kendo-grid-column field="Amount" title="Loan Amount" width="150" format="{0:c}" | |||||
| [editable]="false" [sortable]="false"> | |||||
| </kendo-grid-column> | |||||
| <kendo-grid-column field="Balance" title="Balance" width="150"> | |||||
| <ng-template kendoGridCellTemplate let-dataItem> | <ng-template kendoGridCellTemplate let-dataItem> | ||||
| <div *ngIf="dataItem.Balance >=0 "> {{ dataItem.Balance | currency}} </div> | <div *ngIf="dataItem.Balance >=0 "> {{ dataItem.Balance | currency}} </div> | ||||
| <div *ngIf="dataItem.Balance < 0 "> unknown </div> | <div *ngIf="dataItem.Balance < 0 "> unknown </div> | ||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| <kendo-grid-column field="OffsetBalance" title="Offset" width="200" > | |||||
| <kendo-grid-column field="OffsetBalance" title="Offset" width="150" > | |||||
| <ng-template kendoGridCellTemplate let-dataItem> | <ng-template kendoGridCellTemplate let-dataItem> | ||||
| <div *ngIf="dataItem.OffsetBalance >=0 "> {{ dataItem.OffsetBalance | currency}} </div> | <div *ngIf="dataItem.OffsetBalance >=0 "> {{ dataItem.OffsetBalance | currency}} </div> | ||||
| <div *ngIf="dataItem.OffsetBalance < 0 "> unknown </div> | <div *ngIf="dataItem.OffsetBalance < 0 "> unknown </div> | ||||
| </ng-template> | </ng-template> | ||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| <kendo-grid-column field="UploadId" title="Uploads" width="100" format="{0:c}" editable="false"> | |||||
| <kendo-grid-column field="UploadId" title="Uploads" width="100" format="{0:c}" [editable]="false" [sortable]="false"> | |||||
| <ng-template kendoGridCellTemplate let-dataItem > | <ng-template kendoGridCellTemplate let-dataItem > | ||||
| <button kendoButton *ngIf="dataItem.UploadId > 0" (click)="showUpload(dataItem.UploadId)" icon="attachment"> {{ dataItem.UploadId }} | |||||
| <button kendoButton *ngIf="dataItem.UploadId > 0" | |||||
| (click)="showUpload(dataItem.UploadId)" icon="attachment"> {{ dataItem.UploadId }} | |||||
| </button> | </button> | ||||
| <p *ngIf="dataItem.UploadId <=0" > - </p> | <p *ngIf="dataItem.UploadId <=0" > - </p> | ||||
| </ng-template> | </ng-template> | ||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| <kendo-grid-column field="LoanId" title="Loan" width="80" editable="false"> | |||||
| <kendo-grid-column field="LoanId" title="Loan" width="80" [editable]="false" [sortable]="false"> | |||||
| <ng-template kendoGridCellTemplate let-dataItem> | <ng-template kendoGridCellTemplate let-dataItem> | ||||
| <button *ngIf="dataItem.LoanId != '' && dataItem.LoanId != undefined " kendoButton [icon]="'page-properties'" (click)="gotoLoan(dataItem.LoanId)" > </button> | <button *ngIf="dataItem.LoanId != '' && dataItem.LoanId != undefined " kendoButton [icon]="'page-properties'" (click)="gotoLoan(dataItem.LoanId)" > </button> | ||||
| </ng-template> | </ng-template> | ||||
| </kendo-grid-column> | </kendo-grid-column> | ||||
| </kendo-grid> | </kendo-grid> | ||||
| <app-popup-income-filter #filterDialog (DoFilter)="doFilter($event)"> </app-popup-income-filter> |
| import {Component, Input, OnInit} from '@angular/core'; | |||||
| import {Component, Input, OnInit, ViewChild} from '@angular/core'; | |||||
| import {PayInModel} from '../models/pay-in.model'; | import {PayInModel} from '../models/pay-in.model'; | ||||
| import {FormControl, FormGroup, Validators} from '@angular/forms'; | import {FormControl, FormGroup, Validators} from '@angular/forms'; | ||||
| import {PayInListFilterModel} from '../models/pay-in-list.filter.model'; | import {PayInListFilterModel} from '../models/pay-in-list.filter.model'; | ||||
| import {PayInService} from '../service/pay-in.service'; | import {PayInService} from '../service/pay-in.service'; | ||||
| import {PayInListResult} from '../models/pay-in-list-result.model'; | import {PayInListResult} from '../models/pay-in-list-result.model'; | ||||
| import {Router} from '@angular/router'; | import {Router} from '@angular/router'; | ||||
| import {PopupIncomeFilterComponent} from '../popup-income-filter/popup-income-filter.component'; | |||||
| import {PageChangeEvent, SortSettings} from '@progress/kendo-angular-grid'; | |||||
| import {SortDescriptor} from '@progress/kendo-data-query'; | |||||
| const createFormGroup = dataItem => new FormGroup({ | const createFormGroup = dataItem => new FormGroup({ | ||||
| Id: new FormControl({value: dataItem.Id, disabled: true}, Validators.required), | Id: new FormControl({value: dataItem.Id, disabled: true}, Validators.required), | ||||
| styleUrls: ['./pay-in.component.scss'] | styleUrls: ['./pay-in.component.scss'] | ||||
| }) | }) | ||||
| export class PayInComponent implements OnInit { | export class PayInComponent implements OnInit { | ||||
| @Input() loanFilter: string[] = []; | |||||
| @Input() uploadsFilter: string[] = []; | |||||
| @Input() allowAddNew = true; | @Input() allowAddNew = true; | ||||
| @Input() allowEdit = true; | @Input() allowEdit = true; | ||||
| @Input() pageSize = 10; | |||||
| @Input() skip = 0; | |||||
| @Input() dateStart = new Date('1900-01-01'); | |||||
| @Input() dateEnd = new Date('2038-12-31'); | |||||
| @Input() filter: PayInListFilterModel = new PayInListFilterModel({}); | |||||
| @ViewChild('filterDialog', {static: true}) filterDialog: PopupIncomeFilterComponent; | |||||
| public gridData: PayInListResult = { data: [], total: 0}; | public gridData: PayInListResult = { data: [], total: 0}; | ||||
| public incomeFormGroup: FormGroup; | public incomeFormGroup: FormGroup; | ||||
| public showBalance = true; | public showBalance = true; | ||||
| public showOffsetBalance = true; | public showOffsetBalance = true; | ||||
| public pageable = true; | |||||
| public sortable: SortSettings = { | |||||
| mode: 'single' | |||||
| }; | |||||
| public filterable = false; | |||||
| public loading = false; | |||||
| constructor(private pis: PayInService, private router: Router) { } | constructor(private pis: PayInService, private router: Router) { } | ||||
| ngOnInit(): void { | ngOnInit(): void { | ||||
| this.pis.getPayInList(new PayInListFilterModel()).subscribe( | |||||
| this.loadFilteredData(); | |||||
| } | |||||
| public loadFilteredData(): void{ | |||||
| this.loading = true; | |||||
| this.pis.getPayInList(this.filter).subscribe( | |||||
| ( resp: PayInListResult) => { | ( resp: PayInListResult) => { | ||||
| this.gridData.total = resp.total; | this.gridData.total = resp.total; | ||||
| this.gridData.data = []; | |||||
| resp.data.forEach(v => { | resp.data.forEach(v => { | ||||
| this.gridData.data.push(new PayInModel(v)); | this.gridData.data.push(new PayInModel(v)); | ||||
| this.loading = false; | |||||
| }); | }); | ||||
| }, err => { | |||||
| this.loading = false; | |||||
| }, () => { | |||||
| this.loading = false; | |||||
| } | } | ||||
| ); | ); | ||||
| } | } | ||||
| public addHandler({ sender }): void { | public addHandler({ sender }): void { | ||||
| this.closeEditor(sender); | this.closeEditor(sender); | ||||
| } | } | ||||
| } | } | ||||
| public showFilter(): void{ | |||||
| this.filterDialog.show(); | |||||
| } | |||||
| public doFilter(filter: PayInListFilterModel): void { | |||||
| this.filter.BalanceTo = filter.BalanceTo; | |||||
| this.filter.BalanceFrom = filter.BalanceFrom; | |||||
| this.filter.AmountFrom = filter.AmountFrom; | |||||
| this.filter.AmountTo = filter.AmountTo; | |||||
| this.filter.Take = filter.Take; | |||||
| this.filter.TrailFrom = filter.TrailFrom; | |||||
| this.filter.TrailTo = filter.TrailTo; | |||||
| this.filter.IdFrom = filter.IdFrom; | |||||
| this.filter.IdTo = filter.IdTo; | |||||
| this.filter.TsFrom = filter.TsFrom; | |||||
| this.filter.TsTo = filter.TsTo; | |||||
| this.loadFilteredData(); | |||||
| } | |||||
| public pageChange(event: PageChangeEvent): void { | |||||
| this.filter.Skip = event.skip; | |||||
| this.loadFilteredData(); | |||||
| } | |||||
| public sortChange(sort: SortDescriptor[]): void { | |||||
| this.filter.Sort = sort; | |||||
| this.loadFilteredData(); | |||||
| } | |||||
| } | } |
| <kendo-dialog title="Filtering Data" *ngIf="opened" (close)="close('cancel')" | |||||
| [minWidth]="'500px'" [minHeight]="'200px'" | |||||
| [maxWidth]="'100vw'" [maxHeight]="'100vh'" | |||||
| > | |||||
| <form class="k-form" #filterForm="ngForm"> | |||||
| <div class="range-field" > | |||||
| <label> | |||||
| id-from: | |||||
| <kendo-numerictextbox [format]="'n'" [(value)]="filter.IdFrom"></kendo-numerictextbox> | |||||
| </label> | |||||
| ➜ | |||||
| <label> | |||||
| id-to: | |||||
| <kendo-numerictextbox [format]="'n'" [(value)]="filter.IdTo"></kendo-numerictextbox> | |||||
| </label> | |||||
| </div> | |||||
| <div class="range-field" > | |||||
| <label> | |||||
| Trail-from: | |||||
| <kendo-numerictextbox [(value)]="filter.TrailFrom"></kendo-numerictextbox> | |||||
| </label> | |||||
| ➜ | |||||
| <label> | |||||
| Trail-to: | |||||
| <kendo-numerictextbox [(value)]="filter.TrailTo"></kendo-numerictextbox> | |||||
| </label> | |||||
| </div> | |||||
| <div class="range-field" > | |||||
| <kendo-daterange> | |||||
| <label> | |||||
| Tail Date Start: | |||||
| <kendo-dateinput kendoDateRangeStartInput [(value)]="filter.TsFrom"></kendo-dateinput> | |||||
| </label> | |||||
| ➜ | |||||
| <label> | |||||
| Tail Date End: | |||||
| <kendo-dateinput kendoDateRangeEndInput [(value)]="filter.TsTo"></kendo-dateinput> | |||||
| </label> | |||||
| </kendo-daterange> | |||||
| </div> | |||||
| <div class="range-field"> | |||||
| <label> | |||||
| Balance-from: | |||||
| <kendo-numerictextbox [(value)]="filter.BalanceFrom"></kendo-numerictextbox> | |||||
| </label> | |||||
| ➜ | |||||
| <label> | |||||
| Balance-To: | |||||
| <kendo-numerictextbox [(value)]="filter.BalanceTo"></kendo-numerictextbox> | |||||
| </label> | |||||
| </div> | |||||
| <div class="range-field"> | |||||
| <label> | |||||
| Loan-Amount-from: | |||||
| <kendo-numerictextbox [(value)]="filter.AmountFrom"></kendo-numerictextbox> | |||||
| </label> | |||||
| ➜ | |||||
| <label> | |||||
| Loan-Amount-To: | |||||
| <kendo-numerictextbox [(value)]="filter.AmountTo"></kendo-numerictextbox> | |||||
| </label> | |||||
| </div> | |||||
| <div class="range-field"> | |||||
| <label> | |||||
| Record Per Page: | |||||
| <kendo-dropdownlist [(value)]="filter.Take" [data]="[2,5,10,20,30,50]"> </kendo-dropdownlist> | |||||
| </label> | |||||
| </div> | |||||
| </form> | |||||
| <kendo-dialog-actions> | |||||
| <button kendoButton (click)="close('no')" [disabled]="true"></button> | |||||
| <button kendoButton (click)="close('no')" [disabled]="true"></button> | |||||
| <button kendoButton (click)="close('no')" [icon]="'close-circle'">Close</button> | |||||
| <button kendoButton (click)="close('clear')" [icon]="'filter-clear'" >Clear</button> | |||||
| <button type="submit" kendoButton (click)="close('filter')" [icon]="'filter'" primary="true">Filter</button> | |||||
| </kendo-dialog-actions> | |||||
| </kendo-dialog> |
| .range-field { | |||||
| margin-top:10px; | |||||
| margin-bottom:30px; | |||||
| border-bottom: 1px dotted lightgrey; | |||||
| } |
| import { ComponentFixture, TestBed } from '@angular/core/testing'; | |||||
| import { PopupIncomeFilterComponent } from './popup-income-filter.component'; | |||||
| describe('PopupIncomeFilterComponent', () => { | |||||
| let component: PopupIncomeFilterComponent; | |||||
| let fixture: ComponentFixture<PopupIncomeFilterComponent>; | |||||
| beforeEach(async () => { | |||||
| await TestBed.configureTestingModule({ | |||||
| declarations: [ PopupIncomeFilterComponent ] | |||||
| }) | |||||
| .compileComponents(); | |||||
| }); | |||||
| beforeEach(() => { | |||||
| fixture = TestBed.createComponent(PopupIncomeFilterComponent); | |||||
| component = fixture.componentInstance; | |||||
| fixture.detectChanges(); | |||||
| }); | |||||
| it('should create', () => { | |||||
| expect(component).toBeTruthy(); | |||||
| }); | |||||
| }); |
| import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; | |||||
| import {PayInListFilterModel} from '../models/pay-in-list.filter.model'; | |||||
| @Component({ | |||||
| selector: 'app-popup-income-filter', | |||||
| templateUrl: './popup-income-filter.component.html', | |||||
| styleUrls: ['./popup-income-filter.component.scss'] | |||||
| }) | |||||
| export class PopupIncomeFilterComponent implements OnInit { | |||||
| public opened = false; | |||||
| public filter: PayInListFilterModel; | |||||
| @Output() public DoFilter: EventEmitter<PayInListFilterModel> = new EventEmitter<PayInListFilterModel>(); | |||||
| constructor() { } | |||||
| ngOnInit(): void { | |||||
| if ( this.filter === undefined) { | |||||
| this.filter = new PayInListFilterModel({}); | |||||
| } | |||||
| } | |||||
| public close(status: string): void { | |||||
| this.opened = false; | |||||
| if (status === 'filter' ){ | |||||
| this.DoFilter.emit(this.filter); | |||||
| } | |||||
| if (status === 'clear') { | |||||
| this.clearFilter(); | |||||
| this.DoFilter.emit(this.filter); | |||||
| } | |||||
| } | |||||
| private clearFilter(): void { | |||||
| this.filter = new PayInListFilterModel({}); | |||||
| } | |||||
| public show(): void { | |||||
| this.opened = true; | |||||
| } | |||||
| } | |||||