lnd payments page layout

pull/1127/head
ShahanaFarooqui 2 years ago
parent 246b6ee5d8
commit cc1cda3e56

@ -1203,6 +1203,7 @@ export class LNDEffects implements OnDestroy {
this.invoicesPageSize = (settings.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices') || LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'invoices')).recordsPerPage;
this.paymentsPageSize = (settings.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments') || LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments')).recordsPerPage;
this.store.dispatch(fetchInvoices({ payload: { num_max_invoices: this.invoicesPageSize, reversed: true } }));
// this.store.dispatch(fetchPayments({ payload: { max_payments: 100000, reversed: true } }));
return {
type: LNDActions.SET_PAGE_SETTINGS_LND,
payload: settings || []
@ -1228,6 +1229,16 @@ export class LNDEffects implements OnDestroy {
this.store.dispatch(updateLNDAPICallStatus({ 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') || LND_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') || LND_DEFAULT_PAGE_SETTINGS.find((page) => page.pageId === 'transactions')?.tables.find((table) => table.tableId === 'payments')).recordsPerPage;
if (invPgSz !== this.invoicesPageSize) {
this.invoicesPageSize = invPgSz;
this.store.dispatch(fetchInvoices({ payload: { num_max_invoices: this.invoicesPageSize, reversed: true } }));
}
if (payPgSz !== this.paymentsPageSize) {
this.paymentsPageSize = payPgSz;
// this.store.dispatch(fetchPayments({ payload: { max_payments: 100000, reversed: true } }));
}
return {
type: LNDActions.SET_PAGE_SETTINGS_LND,
payload: postRes || []

@ -43,11 +43,53 @@
<ng-container matColumnDef="payment_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Hash</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.payment_hash}}</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="payment_request">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Request</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.payment_request}}</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="payment_preimage">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Payment Preimage</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.payment_preimage}}</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="description">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.description}}</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="description_hash">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Description Hash</th>
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.description_hash}}</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="failure_reason">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Failure Reason</th>
<td mat-cell *matCellDef="let payment">
{{payment?.failure_reason | camelcaseWithReplace:'failure_reason':'_'}}
</td>
</ng-container>
<ng-container matColumnDef="payment_index">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Payment Index</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.payment_index | number}}</span></td>
</ng-container>
<ng-container matColumnDef="fee">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Fee (Sats)</th>
<td mat-cell *matCellDef="let payment"><span fxLayoutAlign="end center">{{payment?.fee | number}}</span></td>
@ -81,25 +123,35 @@
</td>
</ng-container>
<!-- Payment Group Row Start -->
<ng-container matColumnDef="groupTotal">
<ng-container matColumnDef="group_status">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="start center" class="htlc-row-span">
<span *ngIf="payment?.status === 'SUCCEEDED'" class="dot green" matTooltip="Succeeded" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="payment?.status !== 'SUCCEEDED'" class="dot red" matTooltip="Failed" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
Total Attempts: {{payment?.htlcs?.length}}
</span>
<ng-container *ngIf="payment?.is_expanded">
<span *ngFor="let htlc of payment?.htlcs" fxLayoutAlign="start center" class="htlc-row-span pl-3">
<span *ngIf="htlc.status === 'SUCCEEDED'" class="dot green" matTooltip="Succeeded" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
<span *ngIf="htlc.status !== 'SUCCEEDED'" class="dot red" matTooltip="Failed" matTooltipPosition="right" [ngClass]="{'mr-0': screenSize === screenSizeEnum.XS}"></span>
{{(htlc.attempt_time * 1000) | date:'dd/MMM/y HH:mm'}}
</span>
</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="groupHash">
<ng-container matColumnDef="group_creation_date">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '30rem'}">
<span fxLayoutAlign="start center" class="htlc-row-span">
Total Attempts: {{payment?.htlcs?.length}}
</span>
<ng-container *ngIf="payment?.is_expanded">
<span *ngFor="let htlc of payment?.htlcs" fxLayoutAlign="start center" class="htlc-row-span pl-3">
{{(htlc.attempt_time_ns / 1000000) | date:'dd/MMM/y HH:mm'}}
</span>
</ng-container>
</td>
</ng-container>
<ng-container matColumnDef="group_payment_hash">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.payment_hash}}</span>
</span>
<span *ngIf="payment?.is_expanded">
@ -109,7 +161,73 @@
</span>
</td>
</ng-container>
<ng-container matColumnDef="groupFee">
<ng-container matColumnDef="group_payment_request">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.payment_request}}</span>
</span>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let htlc of payment?.htlcs" fxLayoutAlign="start center" class="htlc-row-span">
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="group_payment_preimage">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.payment_preimage}}</span>
</span>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let htlc of payment?.htlcs; index as i" fxLayoutAlign="start center" class="htlc-row-span">
{{htlc?.preimage}}
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="group_description">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.description}}</span>
</span>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let htlc of payment?.htlcs" fxLayoutAlign="start center" class="htlc-row-span">
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="group_description_hash">
<td mat-cell *matCellDef="let payment">
<span fxLayout="row" class="ellipsis-parent htlc-row-span" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '20rem'}">
<span class="ellipsis-child">{{payment?.description_hash}}</span>
</span>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let htlc of payment?.htlcs" fxLayoutAlign="start center" class="htlc-row-span">
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="group_failure_reason">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="start center" class="htlc-row-span">
{{payment?.failure_reason | camelcaseWithReplace:'failure_reason':'_'}}
</span>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let htlc of payment?.htlcs" fxLayoutAlign="start center" class="htlc-row-span">
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="group_payment_index">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="end center" class="htlc-row-span">{{payment?.payment_index | number}}</span>
<span *ngIf="payment?.is_expanded">
<span *ngFor="let htlc of payment?.htlcs" fxLayoutAlign="end center" class="htlc-row-span">
{{htlc.attempt_id | number}}
</span>
</span>
</td>
</ng-container>
<ng-container matColumnDef="group_fee">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="end center" class="htlc-row-span">{{payment?.fee | number:'1.0-0'}}</span>
<span *ngIf="payment?.is_expanded">
@ -119,7 +237,7 @@
</span>
</td>
</ng-container>
<ng-container matColumnDef="groupValue">
<ng-container matColumnDef="group_value">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="end center" class="htlc-row-span">{{payment?.value | number:'1.0-0'}}</span>
<span *ngIf="payment?.is_expanded">
@ -129,7 +247,7 @@
</span>
</td>
</ng-container>
<ng-container matColumnDef="groupHops">
<ng-container matColumnDef="group_hops">
<td mat-cell *matCellDef="let payment">
<span fxLayoutAlign="end center" class="htlc-row-span">-</span>
<span *ngIf="payment?.is_expanded">
@ -139,7 +257,7 @@
</span>
</td>
</ng-container>
<ng-container matColumnDef="groupActions">
<ng-container matColumnDef="group_actions">
<td mat-cell *matCellDef="let payment" class="px-2">
<span fxLayoutAlign="end center">
<button mat-flat-button class="btn-htlc-expand" color="primary" type="button" tabindex="5" (click)="payment.is_expanded = !payment?.is_expanded">{{payment?.is_expanded ? 'Hide' : 'Show'}}</button>

@ -1,16 +1,20 @@
.mat-column-actions {
min-height: 4.8rem;
.mat-column-status, .mat-column-group_status {
width: 1.5rem;
}
.mat-column-payment_hash {
flex: 0 0 20%;
width: 20%;
.mat-column-payment_hash, .mat-column-payment_request, .mat-column-payment_preimage, .mat-column-description, .mat-column-description_hash {
flex: 0 0 10%;
width: 10%;
& .ellipsis-parent {
display: flex;
}
}
.mat-column-groupActions {
.mat-column-actions {
min-height: 4.8rem;
}
.mat-column-group_actions {
min-height: 4.8rem;
& .btn-htlc-expand {
@ -29,8 +33,15 @@
min-height: 4.2rem;
place-content: center flex-start;
align-items: center;
&.ellipsis-parent {
display: flex;
}
& .dot {
margin-top: -0.4rem;
position: absolute;
}
}
.mat-column-groupTotal {
.mat-column-group_creation_date {
min-width: 17rem;
}

@ -69,15 +69,6 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
constructor(private logger: LoggerService, private commonService: CommonService, private dataService: DataService, private store: Store<RTLState>, private rtlEffects: RTLEffects, private lndEffects: LNDEffects, private decimalPipe: DecimalPipe, private datePipe: DatePipe) {
this.screenSize = this.commonService.getScreenSize();
// if (this.screenSize === ScreenSizeEnum.XS) {
// this.htlcColumns = ['groupTotal', 'groupFee', 'groupActions'];
// } else if (this.screenSize === ScreenSizeEnum.SM) {
// this.htlcColumns = ['groupTotal', 'groupFee', 'groupValue', 'groupHops', 'groupActions'];
// } else if (this.screenSize === ScreenSizeEnum.MD) {
// this.htlcColumns = ['groupTotal', 'groupFee', 'groupValue', 'groupHops', 'groupActions'];
// } else {
// this.htlcColumns = ['groupTotal', 'groupHash', 'groupFee', 'groupValue', 'groupHops', 'groupActions'];
// }
}
ngOnInit() {
@ -102,6 +93,8 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
}
this.displayedColumns.unshift('status');
this.displayedColumns.push('actions');
this.htlcColumns = [];
this.displayedColumns.map((col) => this.htlcColumns.push('group_' + col));
this.pageSize = this.tableSetting.recordsPerPage ? +this.tableSetting.recordsPerPage : PAGE_SIZE;
this.logger.info(this.displayedColumns);
});
@ -300,21 +293,21 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
this.form.resetForm();
}
getHopDetails(hops: Hop[]) {
getHopDetails(currentHop: Hop) {
const self = this;
return hops?.reduce((accumulator: any[], currentHop: Hop) => {
return new Promise((resolve, reject) => {
const peerFound = self.peers.find((peer) => peer.pub_key === currentHop.pub_key);
if (peerFound && peerFound.alias) {
accumulator.push('<pre>Channel: ' + peerFound.alias.padEnd(20) + '&Tab;&Tab;&Tab;Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '</pre>');
resolve('<pre>Channel: ' + peerFound.alias.padEnd(20) + '&Tab;&Tab;&Tab;Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '</pre>');
} else {
self.dataService.getAliasesFromPubkeys((currentHop.pub_key || ''), false).
pipe(takeUntil(self.unSubs[7])).
subscribe((res: any) => {
accumulator.push('<pre>Channel: ' + (res.node && res.node.alias ? res.node.alias.padEnd(20) : (currentHop.pub_key?.substring(0, 17) + '...')) + '&Tab;&Tab;&Tab;Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '</pre>');
subscribe({
next: (res: any) => resolve('<pre>Channel: ' + (res.node && res.node.alias ? res.node.alias.padEnd(20) : (currentHop.pub_key?.substring(0, 17) + '...')) + '&Tab;&Tab;&Tab;Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '</pre>'),
error: (error) => resolve('<pre>Channel: ' + (currentHop.pub_key ? (currentHop.pub_key?.substring(0, 17) + '...') : '') + '&Tab;&Tab;&Tab;Amount (Sats): ' + self.decimalPipe.transform(currentHop.amt_to_forward) + '</pre>')
});
}
return accumulator;
}, []);
});
}
onHTLCClick(selHtlc: PaymentHTLC, selPayment: Payment) {
@ -335,7 +328,35 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
}
showHTLCView(selHtlc: PaymentHTLC, selPayment: Payment, decodedPayment?: PayRequest) {
const reorderedHTLC = [
if (selHtlc.route && selHtlc.route.hops && selHtlc.route.hops.length) {
Promise.all(selHtlc.route.hops.map((hop) => this.getHopDetails(hop))).then((detailsAll: any) => {
this.store.dispatch(openAlert({
payload: {
data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'HTLC Information',
message: this.prepareData(selHtlc, selPayment, decodedPayment, detailsAll),
scrollable: selHtlc.route && selHtlc.route.hops && selHtlc.route.hops.length > 1
}
}
}));
});
} else {
this.store.dispatch(openAlert({
payload: {
data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'HTLC Information',
message: this.prepareData(selHtlc, selPayment, decodedPayment, []),
scrollable: selHtlc.route && selHtlc.route.hops && selHtlc.route.hops.length > 1
}
}
}));
}
}
prepareData(selHtlc: PaymentHTLC, selPayment: Payment, decodedPayment?: PayRequest, hopsDetails?: any) {
const modifiedData = [
[{ key: 'payment_hash', value: selPayment.payment_hash, title: 'Payment Hash', width: 100, type: DataTypeEnum.STRING }],
[{ key: 'preimage', value: selHtlc.preimage, title: 'Preimage', width: 100, type: DataTypeEnum.STRING }],
[{ key: 'payment_request', value: selPayment.payment_request, title: 'Payment Request', width: 100, type: DataTypeEnum.STRING }],
@ -345,21 +366,12 @@ export class LightningPaymentsComponent implements OnInit, AfterViewInit, OnDest
[{ key: 'total_amt', value: selHtlc.route?.total_amt, title: 'Amount (Sats)', width: 33, type: DataTypeEnum.NUMBER },
{ key: 'total_fees', value: selHtlc.route?.total_fees, title: 'Fee (Sats)', width: 33, type: DataTypeEnum.NUMBER },
{ key: 'total_time_lock', value: selHtlc.route?.total_time_lock, title: 'Total Time Lock', width: 34, type: DataTypeEnum.NUMBER }],
[{ key: 'hops', value: this.getHopDetails(selHtlc.route?.hops || []), title: 'Hops', width: 100, type: DataTypeEnum.ARRAY }]
[{ key: 'hops', value: hopsDetails, title: 'Hops', width: 100, type: DataTypeEnum.ARRAY }]
];
if (decodedPayment && decodedPayment.description && decodedPayment.description !== '') {
reorderedHTLC.splice(3, 0, [{ key: 'description', value: decodedPayment.description, title: 'Description', width: 100, type: DataTypeEnum.STRING }]);
modifiedData.splice(3, 0, [{ key: 'description', value: decodedPayment.description, title: 'Description', width: 100, type: DataTypeEnum.STRING }]);
}
this.store.dispatch(openAlert({
payload: {
data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'HTLC Information',
message: reorderedHTLC,
scrollable: selHtlc.route && selHtlc.route.hops && selHtlc.route.hops.length > 1
}
}
}));
return modifiedData;
}
onPaymentClick(selPayment: Payment) {

@ -27,8 +27,15 @@ export class CamelCasePipe implements PipeTransform {
})
export class CamelCaseWithReplacePipe implements PipeTransform {
transform(value: string, args?: any): string {
return value?.replace(/\s+/g, '')?.replace(/-/g, ' ').replace(new RegExp(args, 'g'), ' ').replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (word.toUpperCase()));
transform(value: string, arg1?: string, arg2?: string): string {
value = value?.toLowerCase().replace(/\s+/g, '')?.replace(/-/g, ' ');
if (arg1) {
value = value.replace(new RegExp(arg1, 'g'), ' ');
}
if (arg2) {
value = value.replace(new RegExp(arg2, 'g'), ' ');
}
return value.replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => (word.toUpperCase()));
}
}

@ -980,8 +980,8 @@ export const LND_TABLES_DEF = {
},
transactions: {
payments: {
maxColumns: 5,
allowedColumns: ['creation_date', 'payment_hash', 'fee', 'value', 'hops']
maxColumns: 8,
allowedColumns: ['creation_date', 'payment_hash', 'payment_request', 'payment_preimage', 'description', 'description_hash', 'failure_reason', 'payment_index', 'fee', 'value', 'hops']
},
invoices: {
maxColumns: 9,

Loading…
Cancel
Save