CLT Update payments lists multiple entries for a payment hash (#438)

CLT Update payments lists multiple entries for a payment hash
pull/442/head
ShahanaFarooqui 4 years ago committed by GitHub
parent b50c58a72e
commit c72e2ed2c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -15,5 +15,5 @@
<link rel="stylesheet" href="styles.7f0a84d9b012559f3600.css"></head> <link rel="stylesheet" href="styles.7f0a84d9b012559f3600.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.fc43c4a60d249539e7ff.js" defer></script><script src="polyfills-es5.2ac0d98b22574ae745b1.js" nomodule defer></script><script src="polyfills.5ae721a6ae5ab597a53d.js" defer></script><script src="main.000a76bc1ed847617608.js" defer></script></body> <script src="runtime.07b50d065ad9d6662cbb.js" defer></script><script src="polyfills-es5.2ac0d98b22574ae745b1.js" nomodule defer></script><script src="polyfills.5ae721a6ae5ab597a53d.js" defer></script><script src="main.000a76bc1ed847617608.js" defer></script></body>
</html> </html>

@ -0,0 +1 @@
!function(e){function r(r){for(var n,u,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)u=i[p],Object.prototype.hasOwnProperty.call(o,u)&&o[u]&&s.push(o[u][0]),o[u]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return a.push.apply(a,f||[]),t()}function t(){for(var e,r=0;r<a.length;r++){for(var t=a[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(a.splice(r--,1),e=u(u.s=t[0]))}return e}var n={},o={0:0},a=[];function u(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,u),t.l=!0,t.exports}u.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var a,i=document.createElement("script");i.charset="utf-8",i.timeout=120,u.nc&&i.setAttribute("nonce",u.nc),i.src=function(e){return u.p+""+({}[e]||e)+"."+{1:"9bb271dd8dffd2d994a5",6:"ffaa7252647a44b45232",7:"4a00e92294df28ac9ca1",8:"98795e7ab86361a07d2b"}[e]+".js"}(e);var c=new Error;a=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+a+")",c.name="ChunkLoadError",c.type=n,c.request=a,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){a({type:"timeout",target:i})}),12e4);i.onerror=i.onload=a,document.head.appendChild(i)}return Promise.all(r)},u.m=e,u.c=n,u.d=function(e,r,t){u.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},u.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},u.t=function(e,r){if(1&r&&(e=u(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(u.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)u.d(t,n,(function(r){return e[r]}).bind(null,n));return t},u.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return u.d(r,"a",r),r},u.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},u.p="",u.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);

@ -1 +0,0 @@
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],f=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(l&&l(r);s.length;)s.shift()();return u.push.apply(u,f||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++)0!==o[t[i]]&&(n=!1);n&&(u.splice(r--,1),e=a(a.s=t[0]))}return e}var n={},o={0:0},u=[];function a(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,a),t.l=!0,t.exports}a.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,i=document.createElement("script");i.charset="utf-8",i.timeout=120,a.nc&&i.setAttribute("nonce",a.nc),i.src=function(e){return a.p+""+({}[e]||e)+"."+{1:"9bb271dd8dffd2d994a5",6:"cc720e644b6f96f3d71b",7:"4a00e92294df28ac9ca1",8:"98795e7ab86361a07d2b"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(f);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var f=setTimeout((function(){u({type:"timeout",target:i})}),12e4);i.onerror=i.onload=u,document.head.appendChild(i)}return Promise.all(r)},a.m=e,a.c=n,a.d=function(e,r,t){a.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},a.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},a.t=function(e,r){if(1&r&&(e=a(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(a.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)a.d(t,n,(function(r){return e[r]}).bind(null,n));return t},a.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return a.d(r,"a",r),r},a.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},a.p="",a.oe=function(e){throw console.error(e),e};var i=window.webpackJsonp=window.webpackJsonp||[],c=i.push.bind(i);i.push=r,i=i.slice();for(var f=0;f<i.length;f++)r(i[f]);var l=c;t()}([]);

@ -3,6 +3,36 @@ var common = require('../../common');
var logger = require('../logger'); var logger = require('../logger');
var options = {}; var options = {};
function paymentReducer (accumulator, currentPayment) {
let currPayHash = currentPayment.payment_hash;
if(!accumulator[currPayHash]) {
accumulator[currPayHash] = [currentPayment];
} else {
accumulator[currPayHash].push(currentPayment);
}
return accumulator;
}
function groupBy(payments) {
let temp = null;
let paymentsInGroups = payments.reduce(paymentReducer, {});
let paymentsgrpArray = Object.keys(paymentsInGroups).map(key => paymentsInGroups[key]);
return paymentsgrpArray.reduce((acc, curr) => {
if (curr.length && curr.length === 1) {
temp = JSON.parse(JSON.stringify(curr));
temp[0].is_group = false;
temp[0].is_expanded = false;
temp[0].total_parts = 1;
} else {
temp = {};
temp = {is_group: true, is_expanded: false, total_parts: (curr.length ? curr.length : 0), payment_hash: curr[0].payment_hash,
destination: curr[0].destination, msatoshi: curr[0].msatoshi, msatoshi_sent: curr[0].msatoshi_sent, created_at: curr[0].created_at,
created_at_str: curr[0].created_at_str, mpps: curr};
}
return acc.concat(temp);
}, []);
}
exports.listPayments = (req, res, next) => { exports.listPayments = (req, res, next) => {
options = common.getOptions(); options = common.getOptions();
options.url = common.getSelLNServerUrl() + '/v1/pay/listPayments'; options.url = common.getSelLNServerUrl() + '/v1/pay/listPayments';
@ -18,10 +48,10 @@ exports.listPayments = (req, res, next) => {
if ( body && body.payments && body.payments.length > 0) { if ( body && body.payments && body.payments.length > 0) {
body.payments.forEach(payment => { body.payments.forEach(payment => {
payment.created_at_str = (!payment.created_at) ? '' : common.convertTimestampToDate(payment.created_at); payment.created_at_str = (!payment.created_at) ? '' : common.convertTimestampToDate(payment.created_at);
}); });
body.payments = common.sortDescByKey(body.payments, 'created_at'); body.payments = common.sortDescByKey(body.payments, 'created_at');
} }
res.status(200).json(body.payments); res.status(200).json(groupBy(body.payments));
} }
}) })
.catch(errRes => { .catch(errRes => {

@ -26,14 +26,6 @@
<div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100"> <div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100">
<mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar> <mat-progress-bar *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
<table mat-table #table fxFlex="100" [dataSource]="payments" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}"> <table mat-table #table fxFlex="100" [dataSource]="payments" matSort [ngClass]="{'overflow-auto error-border': flgLoading[0]==='error','overflow-auto': true}">
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>ID</th>
<td mat-cell *matCellDef="let payment">{{payment?.id}}</td>
</ng-container>
<ng-container matColumnDef="bolt11">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Bolt11</th>
<td mat-cell *matCellDef="let payment" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">{{payment?.bolt11}}</td>
</ng-container>
<ng-container matColumnDef="created_at"> <ng-container matColumnDef="created_at">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Created At</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Created At</th>
<td mat-cell *matCellDef="let payment"> <td mat-cell *matCellDef="let payment">
@ -42,10 +34,6 @@
{{payment?.created_at_str}} {{payment?.created_at_str}}
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="destination">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Destination</th>
<td mat-cell *matCellDef="let payment">{{payment?.destination | slice:0:25}}...</td>
</ng-container>
<ng-container matColumnDef="payment_hash"> <ng-container matColumnDef="payment_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let payment"> <td mat-cell *matCellDef="let payment">
@ -62,20 +50,6 @@
<td mat-cell *matCellDef="let payment"><span <td mat-cell *matCellDef="let payment"><span
fxLayoutAlign="end center">{{payment?.msatoshi/1000 | number:'1.0-0'}}</span></td> fxLayoutAlign="end center">{{payment?.msatoshi/1000 | number:'1.0-0'}}</span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="payment_preimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Pre Image</th>
<td mat-cell *matCellDef="let payment">
<div>{{payment?.payment_preimage | slice:0:10}}<span *ngIf="payment?.payment_preimage">...</span></div>
</td>
</ng-container>
<ng-container matColumnDef="amount_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Amount mSat</th>
<td mat-cell *matCellDef="let payment">{{payment?.amount_msat}}</td>
</ng-container>
<ng-container matColumnDef="amount_sent_msat">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Amount Sent mSat</th>
<td mat-cell *matCellDef="let payment">{{payment?.amount_sent_msat}}</td>
</ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="px-3"> <th mat-header-cell *matHeaderCellDef class="px-3">
<div class="bordered-box table-actions-select"> <div class="bordered-box table-actions-select">
@ -86,17 +60,75 @@
</div> </div>
</th> </th>
<td mat-cell *matCellDef="let payment" class="px-3" fxLayoutAlign="end center"> <td mat-cell *matCellDef="let payment" class="px-3" fxLayoutAlign="end center">
<button mat-stroked-button color="primary" type="button" tabindex="4" (click)="onPaymentClick(payment,$event)">View Info</button> <button mat-stroked-button color="primary" type="button" tabindex="4" (click)="onPaymentClick(payment)">View Info</button>
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="no_payment"> <ng-container matColumnDef="no_payment">
<td mat-footer-cell *matFooterCellDef colspan="4"> <td mat-footer-cell *matFooterCellDef colspan="4">
<p *ngIf="!payments.data || payments.data.length<1">No payments available.</p> <p *ngIf="!payments?.data || payments?.data?.length<1">No payments available.</p>
</td>
</ng-container>
<!-- Payment Group Row Start -->
<ng-container matColumnDef="groupTotal">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="start center" class="mpp-row-span">Total Attempts: {{payment?.total_parts}}</span>
<ng-container *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="mpp-row-span">
<span *ngIf="mpp.status === 'complete'" class="dot green" matTooltip="Completed" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="mpp.status !== 'complete'" class="dot yellow" matTooltip="Incomplete" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
{{mpp.created_at_str}}
</span>
</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="groupHash">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="start center" class="mpp-row-span">{{payment?.payment_hash}}</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="start center" class="mpp-row-span">
Part ID {{mpp.partid ? mpp.partid : 0}}
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="groupAmtSent">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="end center" class="mpp-row-span">{{payment?.msatoshi_sent/1000 | number:'1.0-0'}}</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="end center" class="mpp-row-span">
{{mpp.msatoshi_sent/1000 | number:'1.0-0'}}
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="groupAmtRecv">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="end center" class="mpp-row-span">{{payment?.msatoshi/1000 | number:'1.0-0'}}</span>
<span *ngIf="payment.is_expanded">
<span *ngFor="let mpp of payment?.mpps" fxLayoutAlign="end center" class="mpp-row-span">
{{mpp.msatoshi/1000 | number:'1.0-0'}}
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="groupAction">
<td mat-cell *matCellDef="let payment" class="px-3">
<span fxLayoutAlign="end center">
<button mat-stroked-button class="btn-mpp-expand" color="primary" type="button" tabindex="5" (click)="payment.is_expanded = !payment.is_expanded">{{payment.is_expanded ? 'Hide Attemps' : 'Show Attemps'}}</button>
</span>
<div *ngIf="payment.is_expanded">
<div *ngFor="let mpp of payment?.mpps; index as i" fxLayoutAlign="end center">
<button mat-stroked-button class="btn-mpp-info" color="primary" type="button" tabindex="6" (click)="onPaymentClick(mpp)">View Part {{mpp.partid ? mpp.partid : 0}}</button>
</div>
</div>
</td> </td>
</ng-container> </ng-container>
<tr mat-row *matRowDef="let row; columns: mppColumns; when: is_group;" [@newlyAddedRowAnimation]="(row.payment_hash === newlyAddedPayment && flgAnimate) ? 'added' : 'notAdded'"></tr>
<!-- Payment Group Row End -->
<tr mat-footer-row *matFooterRowDef="['no_payment']" [ngClass]="{'display-none': payments.data && payments.data.length>0}"></tr> <tr mat-footer-row *matFooterRowDef="['no_payment']" [ngClass]="{'display-none': payments.data && payments.data.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.payment_hash === newlyAddedPayment && flgAnimate) ? 'added' : 'notAdded'"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns; when: !is_group;" [@newlyAddedRowAnimation]="(row.payment_hash === newlyAddedPayment && flgAnimate) ? 'added' : 'notAdded'"></tr>
</table> </table>
</div> </div>
<mat-paginator [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" class="mb-4"></mat-paginator> <mat-paginator [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" [showFirstLastButtons]="screenSize === screenSizeEnum.XS ? false : true" class="mb-4"></mat-paginator>

@ -8,3 +8,15 @@
.mat-column-actions { .mat-column-actions {
min-height: 4.8rem; min-height: 4.8rem;
} }
.mat-column-groupAction {
min-height: 4.8rem;
& .btn-mpp-info {
margin-top: 0.5rem;
}
}
.mpp-row-span {
min-height: 4.2rem;
}

@ -45,6 +45,7 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
public payments: any; public payments: any;
public paymentJSONArr: Payment[] = []; public paymentJSONArr: Payment[] = [];
public displayedColumns = []; public displayedColumns = [];
public mppColumns = [];
public paymentDecoded: PayRequest = {}; public paymentDecoded: PayRequest = {};
public paymentRequest = ''; public paymentRequest = '';
public paymentDecodedHint = ''; public paymentDecodedHint = '';
@ -60,15 +61,19 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
if(this.screenSize === ScreenSizeEnum.XS) { if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['created_at', 'actions']; this.displayedColumns = ['created_at', 'actions'];
this.mppColumns = ['groupTotal', 'groupAction'];
} else if(this.screenSize === ScreenSizeEnum.SM) { } else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['created_at', 'msatoshi', 'actions']; this.displayedColumns = ['created_at', 'msatoshi', 'actions'];
this.mppColumns = ['groupTotal', 'groupAmtRecv', 'groupAction'];
} else if(this.screenSize === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['created_at', 'msatoshi_sent', 'msatoshi', 'actions']; this.displayedColumns = ['created_at', 'msatoshi_sent', 'msatoshi', 'actions'];
this.mppColumns = ['groupTotal', 'groupAmtSent', 'groupAmtRecv', 'groupAction'];
} else { } else {
this.flgSticky = true; this.flgSticky = true;
this.displayedColumns = ['created_at', 'payment_hash', 'msatoshi_sent', 'msatoshi', 'actions']; this.displayedColumns = ['created_at', 'payment_hash', 'msatoshi_sent', 'msatoshi', 'actions'];
this.mppColumns = ['groupTotal', 'groupHash', 'groupAmtSent', 'groupAmtRecv', 'groupAction'];
} }
} }
@ -96,7 +101,10 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
} }
this.logger.info(rtlStore); this.logger.info(rtlStore);
}); });
}
is_group(index: number, payment: Payment) {
return payment.is_group;
} }
onSendPayment() { onSendPayment() {
@ -224,10 +232,9 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
this.form.resetForm(); this.form.resetForm();
} }
onPaymentClick(selPayment: Payment, event: any) { onPaymentClick(selPayment) {
const reorderedPayment = [ const reorderedPayment = [
[{key: 'bolt11', value: selPayment.bolt11, title: 'Bolt 11', width: 100, type: DataTypeEnum.STRING}], [{key: 'bolt11', value: selPayment.bolt11, title: 'Bolt 11', width: 100, type: DataTypeEnum.STRING}],
[{key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING}],
[{key: 'payment_preimage', value: selPayment.payment_preimage, title: 'Payment Preimage', width: 100, type: DataTypeEnum.STRING}], [{key: 'payment_preimage', value: selPayment.payment_preimage, title: 'Payment Preimage', width: 100, type: DataTypeEnum.STRING}],
[{key: 'id', value: selPayment.id, title: 'ID', width: 20, type: DataTypeEnum.STRING}, [{key: 'id', value: selPayment.id, title: 'ID', width: 20, type: DataTypeEnum.STRING},
{key: 'destination', value: selPayment.destination, title: 'Destination', width: 80, type: DataTypeEnum.STRING}], {key: 'destination', value: selPayment.destination, title: 'Destination', width: 80, type: DataTypeEnum.STRING}],
@ -236,6 +243,13 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
[{key: 'msatoshi', value: selPayment.msatoshi, title: 'Amount (mSats)', width: 50, type: DataTypeEnum.NUMBER}, [{key: 'msatoshi', value: selPayment.msatoshi, title: 'Amount (mSats)', width: 50, type: DataTypeEnum.NUMBER},
{key: 'msatoshi_sent', value: selPayment.msatoshi_sent, title: 'Amount Sent (mSats)', width: 50, type: DataTypeEnum.NUMBER}] {key: 'msatoshi_sent', value: selPayment.msatoshi_sent, title: 'Amount Sent (mSats)', width: 50, type: DataTypeEnum.NUMBER}]
]; ];
if (selPayment.partid) {
reorderedPayment.unshift(
[{key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 80, type: DataTypeEnum.STRING},
{key: 'partid', value: selPayment.partid, title: 'Part ID', width: 20, type: DataTypeEnum.STRING}]);
} else {
reorderedPayment.unshift([{key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING}]);
}
this.store.dispatch(new RTLActions.OpenAlert({ data: { this.store.dispatch(new RTLActions.OpenAlert({ data: {
type: AlertTypeEnum.INFORMATION, type: AlertTypeEnum.INFORMATION,
alertTitle: 'Payment Information', alertTitle: 'Payment Information',
@ -249,7 +263,18 @@ export class CLLightningPaymentsComponent implements OnInit, OnDestroy {
onDownloadCSV() { onDownloadCSV() {
if(this.payments.data && this.payments.data.length > 0) { if(this.payments.data && this.payments.data.length > 0) {
this.commonService.downloadFile(this.payments.data, 'Payments'); let paymentsDataCopy = JSON.parse(JSON.stringify(this.payments.data));
let flattenedPayments = paymentsDataCopy.reduce((acc, curr) => {
if (curr.mpps) {
return acc.concat(curr.mpps);
} else {
delete curr.is_group;
delete curr.is_expanded;
delete curr.total_parts;
return acc.concat(curr);
}
}, []);
this.commonService.downloadFile(flattenedPayments, 'Payments');
} }
} }

@ -138,6 +138,26 @@ export interface Payment {
payment_hash?: string; payment_hash?: string;
payment_preimage?: string; payment_preimage?: string;
status?: string; status?: string;
is_group?: boolean;
is_expanded?: boolean;
total_parts?: number;
mpps?: MPP[];
}
export interface MPP {
amount_msat?: string;
amount_sent_msat?: string;
bolt11?: string;
created_at?: number;
created_at_str?: string;
destination?: string;
id?: number;
msatoshi?: number;
msatoshi_sent?: number;
payment_hash?: string;
payment_preimage?: string;
status?: string;
partid?: number;
} }
export interface PayRequest { export interface PayRequest {

Loading…
Cancel
Save