ECL: On-chain Transactions, Invoice and Payments pagination (#1393)

Done most of the UI changes to accommodate pagination on transactions, payments and invoices tables but true pagination cannot be implemented till total number of records are missing from the API response.

Once the issue https://github.com/ACINQ/eclair/issues/2855 is fixed, I will uncomment pagination changes in the frontend.
pull/1394/head
ShahanaFarooqui 2 weeks ago committed by GitHub
parent c31a123f7e
commit 4bdecdf472
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -130,6 +130,12 @@ export const getPayments = (req, res, next) => {
options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
options.form = { from: 0, to: tillToday };
if (req.query.count) {
options.form.count = req.query.count;
}
if (req.query.skip) {
options.form.skip = req.query.skip;
}
if (common.read_dummy_data) {
common.getDummyData('Payments', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); });
}

@ -53,11 +53,18 @@ export const getInvoice = (req, res, next) => {
return res.status(err.statusCode).json({ message: err.message, error: err.error });
});
};
export const listPendingInvoicesRequestCall = (selectedNode) => {
export const listPendingInvoicesRequestCall = (selectedNode, count, skip) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
options = selectedNode.authentication.options;
options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices';
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
// Limit the number of invoices till provided count
if (count) {
options.form.count = count;
}
if (skip) {
options.form.skip = skip;
}
return new Promise((resolve, reject) => {
request.post(options).then((pendingInvoicesResponse) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Pending Invoices List ', data: pendingInvoicesResponse });
@ -74,27 +81,31 @@ export const listInvoices = (req, res, next) => {
return res.status(options.statusCode).json({ message: options.message, error: options.error });
}
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
options.form = { from: 0, to: tillToday };
const options1 = JSON.parse(JSON.stringify(options));
options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices';
options1.form = { from: 0, to: tillToday };
if (req.query.count) {
options1.form.count = req.query.count;
}
if (req.query.skip) {
options1.form.skip = req.query.skip;
}
const options2 = JSON.parse(JSON.stringify(options));
options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices';
options2.form = { from: 0, to: tillToday };
if (common.read_dummy_data) {
return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then((body) => {
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then(([invoices, pendingInvoicesRes]) => {
pendingInvoices = pendingInvoicesRes;
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
then((values) => res.status(200).json(invoices));
});
}
else {
return Promise.all([request(options1), request(options2)]).
then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body });
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
then(([invoices, pendingInvoicesRes]) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: invoices });
// pendingInvoices will be used to get the status (paid/unpaid) of the invoice via getReceivedPaymentInfo
pendingInvoices = pendingInvoicesRes;
if (invoices && invoices.length > 0) {
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
then((values) => {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(()=>{"use strict";var e,v={},m={};function r(e){var o=m[e];if(void 0!==o)return o.exports;var t=m[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(o,t,i,d)=>{if(!t){var a=1/0;for(n=0;n<e.length;n++){for(var[t,i,d]=e[n],c=!0,f=0;f<t.length;f++)(!1&d||a>=d)&&Object.keys(r.O).every(b=>r.O[b](t[f]))?t.splice(f--,1):(c=!1,d<a&&(a=d));if(c){e.splice(n--,1);var u=i();void 0!==u&&(o=u)}}return o}d=d||0;for(var n=e.length;n>0&&e[n-1][2]>d;n--)e[n]=e[n-1];e[n]=[t,i,d]},r.d=(e,o)=>{for(var t in o)r.o(o,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((o,t)=>(r.f[t](e,o),o),[])),r.u=e=>e+"."+{125:"df4ebfbf2688940a",456:"b73706bd7985d63a",570:"58fb22012be84615",758:"b6dcd2f2b36dacf0"}[e]+".js",r.miniCssF=e=>{},r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),(()=>{var e={},o="RTLApp:";r.l=(t,i,d,n)=>{if(e[t])e[t].push(i);else{var a,c;if(void 0!==d)for(var f=document.getElementsByTagName("script"),u=0;u<f.length;u++){var l=f[u];if(l.getAttribute("src")==t||l.getAttribute("data-webpack")==o+d){a=l;break}}a||(c=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",o+d),a.src=r.tu(t)),e[t]=[i];var s=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(y=>y(b)),g)return g(b)},p=setTimeout(s.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=s.bind(null,a.onerror),a.onload=s.bind(null,a.onload),c&&document.head.appendChild(a)}}})(),r.r=e=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:o=>o},typeof trustedTypes<"u"&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(i,d)=>{var n=r.o(e,i)?e[i]:void 0;if(0!==n)if(n)d.push(n[2]);else if(666!=i){var a=new Promise((l,s)=>n=e[i]=[l,s]);d.push(n[2]=a);var c=r.p+r.u(i),f=new Error;r.l(c,l=>{if(r.o(e,i)&&(0!==(n=e[i])&&(e[i]=void 0),n)){var s=l&&("load"===l.type?"missing":l.type),p=l&&l.target&&l.target.src;f.message="Loading chunk "+i+" failed.\n("+s+": "+p+")",f.name="ChunkLoadError",f.type=s,f.request=p,n[1](f)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var o=(i,d)=>{var f,u,[n,a,c]=d,l=0;if(n.some(p=>0!==e[p])){for(f in a)r.o(a,f)&&(r.m[f]=a[f]);if(c)var s=c(r)}for(i&&i(d);l<n.length;l++)r.o(e,u=n[l])&&e[u]&&e[u][0](),e[u]=0;return r.O(s)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))})()})();
(()=>{"use strict";var e,v={},m={};function r(e){var o=m[e];if(void 0!==o)return o.exports;var t=m[e]={id:e,loaded:!1,exports:{}};return v[e].call(t.exports,t,t.exports,r),t.loaded=!0,t.exports}r.m=v,e=[],r.O=(o,t,i,f)=>{if(!t){var a=1/0;for(n=0;n<e.length;n++){for(var[t,i,f]=e[n],c=!0,d=0;d<t.length;d++)(!1&f||a>=f)&&Object.keys(r.O).every(b=>r.O[b](t[d]))?t.splice(d--,1):(c=!1,f<a&&(a=f));if(c){e.splice(n--,1);var u=i();void 0!==u&&(o=u)}}return o}f=f||0;for(var n=e.length;n>0&&e[n-1][2]>f;n--)e[n]=e[n-1];e[n]=[t,i,f]},r.d=(e,o)=>{for(var t in o)r.o(o,t)&&!r.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:o[t]})},r.f={},r.e=e=>Promise.all(Object.keys(r.f).reduce((o,t)=>(r.f[t](e,o),o),[])),r.u=e=>e+"."+{125:"df4ebfbf2688940a",456:"52fd629b36893386",570:"58fb22012be84615",758:"b6dcd2f2b36dacf0"}[e]+".js",r.miniCssF=e=>{},r.o=(e,o)=>Object.prototype.hasOwnProperty.call(e,o),(()=>{var e={},o="RTLApp:";r.l=(t,i,f,n)=>{if(e[t])e[t].push(i);else{var a,c;if(void 0!==f)for(var d=document.getElementsByTagName("script"),u=0;u<d.length;u++){var l=d[u];if(l.getAttribute("src")==t||l.getAttribute("data-webpack")==o+f){a=l;break}}a||(c=!0,(a=document.createElement("script")).type="module",a.charset="utf-8",a.timeout=120,r.nc&&a.setAttribute("nonce",r.nc),a.setAttribute("data-webpack",o+f),a.src=r.tu(t)),e[t]=[i];var s=(g,b)=>{a.onerror=a.onload=null,clearTimeout(p);var h=e[t];if(delete e[t],a.parentNode&&a.parentNode.removeChild(a),h&&h.forEach(y=>y(b)),g)return g(b)},p=setTimeout(s.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=s.bind(null,a.onerror),a.onload=s.bind(null,a.onload),c&&document.head.appendChild(a)}}})(),r.r=e=>{typeof Symbol<"u"&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),(()=>{var e;r.tt=()=>(void 0===e&&(e={createScriptURL:o=>o},typeof trustedTypes<"u"&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e)})(),r.tu=e=>r.tt().createScriptURL(e),r.p="",(()=>{var e={666:0};r.f.j=(i,f)=>{var n=r.o(e,i)?e[i]:void 0;if(0!==n)if(n)f.push(n[2]);else if(666!=i){var a=new Promise((l,s)=>n=e[i]=[l,s]);f.push(n[2]=a);var c=r.p+r.u(i),d=new Error;r.l(c,l=>{if(r.o(e,i)&&(0!==(n=e[i])&&(e[i]=void 0),n)){var s=l&&("load"===l.type?"missing":l.type),p=l&&l.target&&l.target.src;d.message="Loading chunk "+i+" failed.\n("+s+": "+p+")",d.name="ChunkLoadError",d.type=s,d.request=p,n[1](d)}},"chunk-"+i,i)}else e[i]=0},r.O.j=i=>0===e[i];var o=(i,f)=>{var d,u,[n,a,c]=f,l=0;if(n.some(p=>0!==e[p])){for(d in a)r.o(a,d)&&(r.m[d]=a[d]);if(c)var s=c(r)}for(i&&i(f);l<n.length;l++)r.o(e,u=n[l])&&e[u]&&e[u][0](),e[u]=0;return r.O(s)},t=self.webpackChunkRTLApp=self.webpackChunkRTLApp||[];t.forEach(o.bind(null,0)),t.push=o.bind(null,t.push.bind(t))})()})();

@ -113,6 +113,8 @@ export const getPayments = (req, res, next) => {
options.url = req.session.selectedNode.settings.lnServerUrl + '/audit';
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
options.form = { from: 0, to: tillToday };
if (req.query.count) { options.form.count = req.query.count; }
if (req.query.skip) { options.form.skip = req.query.skip; }
if (common.read_dummy_data) {
common.getDummyData('Payments', req.session.selectedNode.lnImplementation).then((data) => { res.status(200).json(arrangePayments(req.session.selectedNode, data)); });
} else {

@ -52,11 +52,14 @@ export const getInvoice = (req, res, next) => {
});
};
export const listPendingInvoicesRequestCall = (selectedNode: SelectedNode) => {
export const listPendingInvoicesRequestCall = (selectedNode: SelectedNode, count?: number, skip?: number) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'List Pending Invoices..' });
options = selectedNode.authentication.options;
options.url = selectedNode.settings.lnServerUrl + '/listpendinginvoices';
options.form = { from: 0, to: (Math.round(new Date(Date.now()).getTime() / 1000)).toString() };
// Limit the number of invoices till provided count
if (count) { options.form.count = count; }
if (skip) { options.form.skip = skip; }
return new Promise((resolve, reject) => {
request.post(options).then((pendingInvoicesResponse) => {
logger.log({ selectedNode: selectedNode, level: 'INFO', fileName: 'Invoices', msg: 'Pending Invoices List ', data: pendingInvoicesResponse });
@ -72,26 +75,26 @@ export const listInvoices = (req, res, next) => {
options = common.getOptions(req);
if (options.error) { return res.status(options.statusCode).json({ message: options.message, error: options.error }); }
const tillToday = (Math.round(new Date(Date.now()).getTime() / 1000)).toString();
options.form = { from: 0, to: tillToday };
const options1 = JSON.parse(JSON.stringify(options));
options1.url = req.session.selectedNode.settings.lnServerUrl + '/listinvoices';
options1.form = { from: 0, to: tillToday };
if (req.query.count) { options1.form.count = req.query.count; }
if (req.query.skip) { options1.form.skip = req.query.skip; }
const options2 = JSON.parse(JSON.stringify(options));
options2.url = req.session.selectedNode.settings.lnServerUrl + '/listpendinginvoices';
options2.form = { from: 0, to: tillToday };
if (common.read_dummy_data) {
return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then((body) => {
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
return common.getDummyData('Invoices', req.session.selectedNode.lnImplementation).then(([invoices, pendingInvoicesRes]: any[]) => {
pendingInvoices = pendingInvoicesRes;
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
then((values) => res.status(200).json(invoices));
});
} else {
return Promise.all([request(options1), request(options2)]).
then((body) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: body });
const invoices = (!body[0] || body[0].length <= 0) ? [] : body[0];
pendingInvoices = (!body[1] || body[1].length <= 0) ? [] : body[1];
then(([invoices, pendingInvoicesRes]) => {
logger.log({ selectedNode: req.session.selectedNode, level: 'DEBUG', fileName: 'Invoice', msg: 'Invoices List Received', data: invoices });
// pendingInvoices will be used to get the status (paid/unpaid) of the invoice via getReceivedPaymentInfo
pendingInvoices = pendingInvoicesRes;
if (invoices && invoices.length > 0) {
return Promise.all(invoices?.map((invoice) => getReceivedPaymentInfo(req.session.selectedNode.settings.lnServerUrl, invoice))).
then((values) => {

@ -89,7 +89,10 @@
<tr *matHeaderRowDef="displayedColumns" mat-header-row></tr>
<tr *matRowDef="let row; columns: displayedColumns;" mat-row></tr>
</table>
<!-- Remove below one line after paginator api is fixed -->
<mat-paginator class="mb-1" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" />
<!-- Uncomment after paginator api is fixed -->
<!-- <mat-paginator class="mb-1" [length]="totalRecords" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" (page)="onPageChange($event)" /> -->
</div>
</div>
</div>

@ -4,13 +4,13 @@ import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { faHistory } from '@fortawesome/free-solid-svg-icons';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatPaginator, MatPaginatorIntl, PageEvent } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { MAT_SELECT_CONFIG } from '@angular/material/select';
import { Transaction } from '../../../shared/models/eclModels';
import { ApiCallStatusPayload } from '../../../shared/models/apiCallsPayload';
import { ApiCallStatusPayload, ApiCallsListECL } from '../../../shared/models/apiCallsPayload';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum, ScreenSizeEnum, APICallStatusEnum, SortOrderEnum, ECL_DEFAULT_PAGE_SETTINGS, ECL_PAGE_DEFS } from '../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../shared/services/logger.service';
import { CommonService } from '../../../shared/services/common.service';
@ -52,6 +52,8 @@ export class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy
public selFilter = '';
public apiCallStatus: ApiCallStatusPayload | null = null;
public apiCallStatusEnum = APICallStatusEnum;
public totalRecords = 0;
public flgInit = false;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private datePipe: DatePipe, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {
@ -59,24 +61,32 @@ export class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy
}
ngOnInit() {
this.store.dispatch(fetchTransactions());
this.store.select(eclPageSettings).pipe(takeUntil(this.unSubs[0])).
subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload }) => {
subscribe((settings: { pageSettings: PageSettings[], apiCallStatus: ApiCallStatusPayload, allApiCallStatus: ApiCallsListECL }) => {
this.errorMessage = '';
this.apiCallStatus = settings.apiCallStatus;
if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {
this.errorMessage = this.apiCallStatus.message || '';
}
this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;
if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));
} else {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));
if (this.apiCallStatus.status === APICallStatusEnum.COMPLETED) {
this.tableSetting = settings.pageSettings.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId) || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === this.PAGE_ID)?.tables.find((table) => table.tableId === this.tableSetting.tableId)!;
if (this.screenSize === ScreenSizeEnum.XS || this.screenSize === ScreenSizeEnum.SM) {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelectionSM));
} else {
this.displayedColumns = JSON.parse(JSON.stringify(this.tableSetting.columnSelection));
}
this.displayedColumns.push('actions');
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 14) + 'rem' : '20rem';
if (!this.flgInit) {
this.flgInit = true;
// Uncomment after paginator api is fixed
// this.store.dispatch(fetchTransactions({ payload : { count: this.pageSize, skip: 0 } }));
// Remove below one line after paginator api is fixed
this.store.dispatch(fetchTransactions({ payload : { count: 1000, skip: 0 } }));
}
this.logger.info(this.displayedColumns);
}
this.displayedColumns.push('actions');
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 14) + 'rem' : '20rem';
this.logger.info(this.displayedColumns);
});
this.store.select(transactions).pipe(takeUntil(this.unSubs[1])).
subscribe((transactionsSelector: { transactions: Transaction[], apiCallStatus: ApiCallStatusPayload }) => {
@ -85,7 +95,9 @@ export class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy
if (this.apiCallStatus.status === APICallStatusEnum.ERROR) {
this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;
}
if (transactionsSelector.transactions && this.sort && this.paginator) {
// Uncomment after paginator api is fixed
// this.totalRecords = transactionsSelector.transactions.totalRecords;
if (transactionsSelector.transactions && this.sort && this.paginator && this.displayedColumns.length > 0) {
this.loadTransactionsTable(transactionsSelector.transactions);
}
this.logger.info(transactionsSelector);
@ -146,12 +158,17 @@ export class ECLOnChainTransactionHistoryComponent implements OnInit, OnDestroy
this.listTransactions = new MatTableDataSource<Transaction>([...transactions]);
this.listTransactions.sort = this.sort;
this.listTransactions.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
// Remove below one line after paginator api is fixed
this.listTransactions.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
this.logger.info(this.listTransactions);
}
onPageChange(event: PageEvent) {
this.store.dispatch(fetchTransactions({ payload : { count: this.pageSize, skip: event.pageIndex * event.pageSize } }));
}
onDownloadCSV() {
if (this.listTransactions.data && this.listTransactions.data.length > 0) {
this.commonService.downloadFile(this.listTransactions.data, 'Transactions');

@ -15,7 +15,7 @@ import { opacityAnimation } from '../../../../shared/animation/opacity-animation
import { DataService } from '../../../../shared/services/data.service';
import { LoggerService } from '../../../../shared/services/logger.service';
import { RTLState } from '../../../../store/rtl.state';
import { fetchChannels, fetchInvoices } from '../../../store/ecl.actions';
import { fetchChannels } from '../../../store/ecl.actions';
@Component({
selector: 'rtl-ecl-channel-rebalance',
@ -124,8 +124,7 @@ export class ECLChannelRebalanceComponent implements OnInit, OnDestroy {
this.logger.info(rebalanceRes);
this.rebalanceStatus = rebalanceRes;
this.flgEditable = true;
this.store.dispatch(fetchInvoices());
this.store.dispatch(fetchChannels({ payload: { fetchPayments: true } }));
this.store.dispatch(fetchChannels());
}, error: (error) => {
this.logger.error(error);
this.rebalanceStatus = error;

@ -26,7 +26,7 @@ export const fetchFees = createAction(ECLActions.FETCH_FEES_ECL);
export const setFees = createAction(ECLActions.SET_FEES_ECL, props<{ payload: Fees }>());
export const fetchChannels = createAction(ECLActions.FETCH_CHANNELS_ECL, props<{ payload: { fetchPayments: boolean } }>());
export const fetchChannels = createAction(ECLActions.FETCH_CHANNELS_ECL);
export const setActiveChannels = createAction(ECLActions.SET_ACTIVE_CHANNELS_ECL, props<{ payload: Channel[] }>());
@ -68,7 +68,7 @@ export const closeChannel = createAction(ECLActions.CLOSE_CHANNEL_ECL, props<{ p
export const removeChannel = createAction(ECLActions.REMOVE_CHANNEL_ECL, props<{ payload: { channelId: string } }>());
export const fetchPayments = createAction(ECLActions.FETCH_PAYMENTS_ECL);
export const fetchPayments = createAction(ECLActions.FETCH_PAYMENTS_ECL, props<{ payload: { count: number, skip: number } }>());
export const setPayments = createAction(ECLActions.SET_PAYMENTS_ECL, props<{ payload: Payments }>());
@ -80,7 +80,7 @@ export const sendPayment = createAction(ECLActions.SEND_PAYMENT_ECL, props<{ pay
export const sendPaymentStatus = createAction(ECLActions.SEND_PAYMENT_STATUS_ECL, props<{ payload: any }>());
export const fetchTransactions = createAction(ECLActions.FETCH_TRANSACTIONS_ECL);
export const fetchTransactions = createAction(ECLActions.FETCH_TRANSACTIONS_ECL, props<{ payload: { count: number, skip: number } }>());
export const setTransactions = createAction(ECLActions.SET_TRANSACTIONS_ECL, props<{ payload: Transaction[] }>());
@ -88,7 +88,7 @@ export const sendOnchainFunds = createAction(ECLActions.SEND_ONCHAIN_FUNDS_ECL,
export const sendOnchainFundsRes = createAction(ECLActions.SEND_ONCHAIN_FUNDS_RES_ECL, props<{ payload: any }>());
export const fetchInvoices = createAction(ECLActions.FETCH_INVOICES_ECL);
export const fetchInvoices = createAction(ECLActions.FETCH_INVOICES_ECL, props<{ payload: { count: number, skip: number } }>());
export const setInvoices = createAction(ECLActions.SET_INVOICES_ECL, props<{ payload: Invoice[] }>());

@ -14,12 +14,12 @@ import { WebSocketClientService } from '../../shared/services/web-socket.service
import { ErrorMessageComponent } from '../../shared/components/data-modal/error-message/error-message.component';
import { GetInfo, OnChainBalance, Peer, Audit, Transaction, Invoice, Channel, ChannelStateUpdate, SaveChannel, UpdateChannel, CloseChannel,
GetQueryRoutes, QueryRoutes, SendPayment, SendPaymentOnChain, CreateInvoice } from '../../shared/models/eclModels';
import { API_URL, API_END_POINTS, RTLActions, ECLActions, APICallStatusEnum, UI_MESSAGES, ECLWSEventTypeEnum } from '../../shared/services/consts-enums-functions';
import { API_URL, API_END_POINTS, RTLActions, ECLActions, APICallStatusEnum, UI_MESSAGES, ECLWSEventTypeEnum, ECL_DEFAULT_PAGE_SETTINGS } from '../../shared/services/consts-enums-functions';
import { closeAllDialogs, closeSpinner, logout, openAlert, openSnackBar, openSpinner, setApiUrl, setNodeData } from '../../store/rtl.actions';
import { ECLInvoiceInformationComponent } from '../transactions/invoice-information-modal/invoice-information.component';
import { RTLState } from '../../store/rtl.state';
import { fetchChannels, fetchFees, fetchInvoices, fetchOnchainBalance, fetchPayments, fetchPeers, sendPaymentStatus, setActiveChannels,
import { fetchChannels, fetchFees, fetchOnchainBalance, fetchPayments, fetchPeers, sendPaymentStatus, setActiveChannels,
setChannelsStatus, setInactiveChannels, setLightningBalance, setPeers, setPendingChannels, setQueryRoutes, updateECLAPICallStatus,
updateChannelState, updateInvoice, updateRelayedPayment } from './ecl.actions';
import { allAPIsCallStatus } from './ecl.selector';
@ -29,6 +29,8 @@ import { ApiCallsListECL } from '../../shared/models/apiCallsPayload';
export class ECLEffects implements OnDestroy {
CHILD_API_URL = API_URL + '/ecl';
private invoicesPageSettings = ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices');
private paymentsPageSettings = ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments');
private flgInitialized = false;
private flgReceivedPaymentUpdateFromWS = false;
private latestPaymentRes = '';
@ -167,9 +169,9 @@ export class ECLEffects implements OnDestroy {
fetchPayments = createEffect(() => this.actions.pipe(
ofType(ECLActions.FETCH_PAYMENTS_ECL),
mergeMap(() => {
mergeMap((action: { type: string, payload: { count: number, skip: number } }) => {
this.store.dispatch(updateECLAPICallStatus({ payload: { action: 'FetchPayments', status: APICallStatusEnum.INITIATED } }));
return this.httpClient.get<Audit>(this.CHILD_API_URL + API_END_POINTS.FEES_API + '/payments').
return this.httpClient.get<Audit>(this.CHILD_API_URL + API_END_POINTS.FEES_API + '/payments?count=' + action.payload.count + '&skip=' + action.payload.skip).
pipe(
map((payments: any) => {
this.logger.info(payments);
@ -189,7 +191,7 @@ export class ECLEffects implements OnDestroy {
channelsFetch = createEffect(() => this.actions.pipe(
ofType(ECLActions.FETCH_CHANNELS_ECL),
mergeMap((action: { type: string, payload: { fetchPayments: boolean } }) => {
mergeMap((action: { type: string }) => {
this.store.dispatch(updateECLAPICallStatus({ payload: { action: 'FetchChannels', status: APICallStatusEnum.INITIATED } }));
return this.httpClient.get<Channel[]>(this.CHILD_API_URL + API_END_POINTS.CHANNELS_API).
pipe(
@ -198,9 +200,6 @@ export class ECLEffects implements OnDestroy {
this.rawChannelsList = channelsRes;
this.setChannelsAndStatusAndBalances();
this.store.dispatch(updateECLAPICallStatus({ payload: { action: 'FetchChannels', status: APICallStatusEnum.COMPLETED } }));
if (action.payload && action.payload.fetchPayments) {
this.store.dispatch(fetchPayments());
}
return { type: RTLActions.VOID };
}),
catchError((err: any) => {
@ -412,7 +411,6 @@ export class ECLEffects implements OnDestroy {
this.logger.info(postRes);
setTimeout(() => {
this.store.dispatch(closeSpinner({ payload: ((action.payload.force) ? UI_MESSAGES.FORCE_CLOSE_CHANNEL : UI_MESSAGES.CLOSE_CHANNEL) }));
this.store.dispatch(fetchChannels({ payload: { fetchPayments: false } }));
this.store.dispatch(openSnackBar({ payload: (action.payload.force ? 'Channel Force Closed Successfully!' : 'Channel Closed Successfully!') }));
}, 2000);
return {
@ -487,9 +485,9 @@ export class ECLEffects implements OnDestroy {
transactionsFetch = createEffect(() => this.actions.pipe(
ofType(ECLActions.FETCH_TRANSACTIONS_ECL),
mergeMap(() => {
mergeMap((action: { type: string, payload: { count: number, skip: number } }) => {
this.store.dispatch(updateECLAPICallStatus({ payload: { action: 'FetchTransactions', status: APICallStatusEnum.INITIATED } }));
return this.httpClient.get<Transaction[]>(this.CHILD_API_URL + API_END_POINTS.ON_CHAIN_API + '/transactions?count=1000&skip=0');
return this.httpClient.get<Transaction[]>(this.CHILD_API_URL + API_END_POINTS.ON_CHAIN_API + '/transactions?count=' + action.payload.count + '&skip=' + action.payload.skip);
}),
map((transactions) => {
this.logger.info(transactions);
@ -571,9 +569,9 @@ export class ECLEffects implements OnDestroy {
invoicesFetch = createEffect(() => this.actions.pipe(
ofType(ECLActions.FETCH_INVOICES_ECL),
mergeMap(() => {
mergeMap((action: { type: string, payload: { count: number, skip: number } }) => {
this.store.dispatch(updateECLAPICallStatus({ payload: { action: 'FetchInvoices', status: APICallStatusEnum.INITIATED } }));
return this.httpClient.get<Invoice[]>(this.CHILD_API_URL + API_END_POINTS.INVOICES_API).
return this.httpClient.get<Invoice[]>(this.CHILD_API_URL + API_END_POINTS.INVOICES_API + '?count=' + action.payload.count + '&skip=' + action.payload.skip).
pipe(
map((res: Invoice[]) => {
this.logger.info(res);
@ -659,6 +657,10 @@ export class ECLEffects implements OnDestroy {
map((pageSettings: any) => {
this.logger.info(pageSettings);
this.store.dispatch(updateECLAPICallStatus({ payload: { action: 'FetchPageSettings', status: APICallStatusEnum.COMPLETED } }));
this.invoicesPageSettings = (pageSettings && Object.keys(pageSettings).length > 0 ? (pageSettings.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices')) :
ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices'));
this.paymentsPageSettings = (pageSettings && Object.keys(pageSettings).length > 0 ? (pageSettings.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments')) :
ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments'));
return {
type: ECLActions.SET_PAGE_SETTINGS_ECL,
payload: pageSettings || []
@ -684,6 +686,14 @@ export class ECLEffects implements OnDestroy {
this.store.dispatch(updateECLAPICallStatus({ payload: { action: 'SavePageSettings', status: APICallStatusEnum.COMPLETED } }));
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.UPDATE_PAGE_SETTINGS }));
this.store.dispatch(openSnackBar({ payload: 'Page Layout Updated Successfully!' }));
const invPgSz = (postRes.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices') || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices'))?.recordsPerPage;
const payPgSz = (postRes.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments') || ECL_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments'))?.recordsPerPage;
if (this.invoicesPageSettings && invPgSz !== this.invoicesPageSettings?.recordsPerPage) {
this.invoicesPageSettings.recordsPerPage = invPgSz;
}
if (this.paymentsPageSettings && payPgSz !== this.paymentsPageSettings?.recordsPerPage) {
this.paymentsPageSettings.recordsPerPage = payPgSz;
}
return {
type: ECLActions.SET_PAGE_SETTINGS_ECL,
payload: postRes || []
@ -748,7 +758,6 @@ export class ECLEffects implements OnDestroy {
this.store.dispatch(updateECLAPICallStatus({ payload: { action: 'SendPayment', status: APICallStatusEnum.COMPLETED } }));
this.store.dispatch(closeSpinner({ payload: UI_MESSAGES.SEND_PAYMENT }));
this.store.dispatch(sendPaymentStatus({ payload: this.latestPaymentRes }));
this.store.dispatch(fetchChannels({ payload: { fetchPayments: true } }));
this.store.dispatch(openSnackBar({ payload: msg }));
};
@ -775,8 +784,7 @@ export class ECLEffects implements OnDestroy {
newRoute = '/ecl/home';
}
this.router.navigate([newRoute]);
this.store.dispatch(fetchInvoices());
this.store.dispatch(fetchChannels({ payload: { fetchPayments: true } }));
this.store.dispatch(fetchChannels());
this.store.dispatch(fetchFees());
this.store.dispatch(fetchOnchainBalance());
this.store.dispatch(fetchPeers());

@ -135,6 +135,9 @@
<tr *matRowDef="let row; columns: displayedColumns;" mat-row></tr>
</table>
</div>
<!-- Remove below one line after paginator api is fixed -->
<mat-paginator class="mb-1" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" />
<!-- Uncomment after paginator api is fixed -->
<!-- <mat-paginator class="mb-1" [length]="totalRecords" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" (page)="onPageChange($event)" /> -->
</div>
</div>

@ -5,7 +5,7 @@ import { filter, takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { faHistory } from '@fortawesome/free-solid-svg-icons';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatPaginator, MatPaginatorIntl, PageEvent } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { MAT_SELECT_CONFIG } from '@angular/material/select';
@ -23,7 +23,7 @@ import { ECLInvoiceInformationComponent } from '../invoice-information-modal/inv
import { RTLState } from '../../../store/rtl.state';
import { rootSelectedNode } from '../../../store/rtl.selector';
import { openAlert } from '../../../store/rtl.actions';
import { createInvoice, invoiceLookup } from '../../store/ecl.actions';
import { createInvoice, fetchInvoices, invoiceLookup } from '../../store/ecl.actions';
import { eclNodeInformation, eclPageSettings, invoices } from '../../store/ecl.selector';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithSpacesPipe } from '../../../shared/pipes/app.pipe';
@ -70,6 +70,8 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
public errorMessage = '';
public apiCallStatus: ApiCallStatusPayload | null = null;
public apiCallStatusEnum = APICallStatusEnum;
public totalRecords = 0;
public flgInit = false;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<RTLState>, private decimalPipe: DecimalPipe, private commonService: CommonService, private datePipe: DatePipe, private actions: Actions, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {
@ -102,6 +104,13 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
this.displayedColumns.push('actions');
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 14) + 'rem' : '20rem';
if (!this.flgInit) {
this.flgInit = true;
// Uncomment after paginator api is fixed
// this.store.dispatch(fetchInvoices({ payload : { count: this.pageSize, skip: 0 } }));
// Remove below one line after paginator api is fixed
this.store.dispatch(fetchInvoices({ payload : { count: 1000000, skip: 0 } }));
}
this.logger.info(this.displayedColumns);
});
this.store.select(invoices).pipe(takeUntil(this.unSubs[3])).
@ -112,6 +121,8 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;
}
this.invoiceJSONArr = (invoicesSelector.invoices && invoicesSelector.invoices.length > 0) ? invoicesSelector.invoices : [];
// Uncomment after paginator api is fixed
// this.totalRecords = invoicesSelector.invoices.totalRecords;
if (this.invoiceJSONArr && this.sort && this.paginator && this.displayedColumns.length > 0) {
this.loadInvoicesTable(this.invoiceJSONArr);
}
@ -226,6 +237,7 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
this.invoices = invs ? new MatTableDataSource<Invoice>([...invs]) : new MatTableDataSource<Invoice>([]);
this.invoices.sort = this.sort;
this.invoices.sortingDataAccessor = (data: any, sortHeaderId: string) => ((data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null);
// Remove below one line after paginator api is fixed
this.invoices.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
@ -254,6 +266,10 @@ export class ECLLightningInvoicesComponent implements OnInit, AfterViewInit, OnD
}
}
onPageChange(event: PageEvent) {
this.store.dispatch(fetchInvoices({ payload : { count: this.pageSize, skip: event.pageIndex * event.pageSize } }));
}
onDownloadCSV() {
if (this.invoices.data && this.invoices.data.length > 0) {
this.commonService.downloadFile(this.invoices.data, 'Invoices');

@ -249,6 +249,9 @@
</table>
</div>
</div>
<!-- Remove below one line after paginator api is fixed -->
<mat-paginator class="mb-1" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" />
<!-- Uncomment after paginator api is fixed -->
<!-- <mat-paginator class="mb-1" [length]="totalRecords" [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" (page)="onPageChange($event)" /> -->
</div>
</div>

@ -4,7 +4,7 @@ import { Subject } from 'rxjs';
import { takeUntil, take } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { faHistory } from '@fortawesome/free-solid-svg-icons';
import { MatPaginator, MatPaginatorIntl } from '@angular/material/paginator';
import { MatPaginator, MatPaginatorIntl, PageEvent } from '@angular/material/paginator';
import { MatSort } from '@angular/material/sort';
import { MatTableDataSource } from '@angular/material/table';
import { MAT_SELECT_CONFIG } from '@angular/material/select';
@ -24,7 +24,7 @@ import { RTLEffects } from '../../../store/rtl.effects';
import { RTLState } from '../../../store/rtl.state';
import { rootSelectedNode } from '../../../store/rtl.selector';
import { openAlert, openConfirmation } from '../../../store/rtl.actions';
import { sendPayment } from '../../store/ecl.actions';
import { fetchPayments, sendPayment } from '../../store/ecl.actions';
import { eclNodeInformation, eclPageSettings, payments } from '../../store/ecl.selector';
import { ColumnDefinition, PageSettings, TableSetting } from '../../../shared/models/pageSettings';
import { CamelCaseWithSpacesPipe } from '../../../shared/pipes/app.pipe';
@ -72,6 +72,8 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
public selFilter = '';
public apiCallStatus: ApiCallStatusPayload | null = null;
public apiCallStatusEnum = APICallStatusEnum;
public totalRecords = 0;
public flgInit = false;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private decimalPipe: DecimalPipe, private dataService: DataService, private datePipe: DatePipe, private camelCaseWithSpaces: CamelCaseWithSpacesPipe) {
@ -105,6 +107,13 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
this.displayedColumns.map((col) => this.partColumns.push('group_' + col));
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.colWidth = this.displayedColumns.length ? ((this.commonService.getContainerSize().width / this.displayedColumns.length) / 14) + 'rem' : '20rem';
if (!this.flgInit) {
this.flgInit = true;
// Uncomment after paginator api is fixed
// this.store.dispatch(fetchPayments({ payload : { count: this.pageSize, skip: 0 } }));
// Remove below one line after paginator api is fixed
this.store.dispatch(fetchPayments({ payload : { count: 1000000, skip: 0 } }));
}
this.logger.info(this.displayedColumns);
});
this.store.select(payments).pipe(takeUntil(this.unSubs[3])).
@ -115,6 +124,8 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
this.errorMessage = !this.apiCallStatus.message ? '' : (typeof (this.apiCallStatus.message) === 'object') ? JSON.stringify(this.apiCallStatus.message) : this.apiCallStatus.message;
}
this.paymentJSONArr = (paymentsSeletor.payments && paymentsSeletor.payments.sent && paymentsSeletor.payments.sent.length > 0) ? paymentsSeletor.payments.sent : [];
// Uncomment after paginator api is fixed
// this.totalRecords = paymentsSeletor.payments.totalRecords;
if (this.paymentJSONArr && this.sort && this.paginator && this.displayedColumns.length > 0) {
this.loadPaymentsTable(this.paymentJSONArr);
}
@ -182,6 +193,7 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
return (data[sortHeaderId] && isNaN(data[sortHeaderId])) ? data[sortHeaderId].toLocaleLowerCase() : data[sortHeaderId] ? +data[sortHeaderId] : null;
}
};
// Remove below one line after paginator api is fixed
this.payments.paginator = this.paginator;
this.setFilterPredicate();
this.applyFilter();
@ -404,6 +416,10 @@ export class ECLLightningPaymentsComponent implements OnInit, AfterViewInit, OnD
}));
}
onPageChange(event: PageEvent) {
this.store.dispatch(fetchPayments({ payload : { count: this.pageSize, skip: event.pageIndex * event.pageSize } }));
}
onDownloadCSV() {
if (this.payments.data && this.payments.data.length > 0) {
const paymentsDataCopy: PaymentSent[] = JSON.parse(JSON.stringify(this.payments.data));

Loading…
Cancel
Save