alert,confirmation,error and other components

alert,confirmation,error and other components
This commit is contained in:
Shahana Farooqui 2019-12-01 19:22:25 -05:00
parent 3128cfe2b2
commit 259c5de623
75 changed files with 1059 additions and 987 deletions

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

View file

@ -9,8 +9,8 @@
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon/favicon-16x16.png">
<link rel="manifest" href="assets/images/favicon/site.webmanifest">
<link rel="stylesheet" href="styles.a5b94b699c491c77372b.css"></head>
<link rel="stylesheet" href="styles.72af09d2752fe39920ba.css"></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.2468dfb427c0917909a7.js"></script><script src="polyfills-es5.92f4069201c83f4833ef.js" nomodule></script><script src="polyfills.5ddcccdb990eb395f306.js"></script><script src="main.81428553c1b06d7b04eb.js"></script></body>
<script src="runtime.660e7d8ad0ea662c0efc.js"></script><script src="polyfills-es5.92f4069201c83f4833ef.js" nomodule></script><script src="polyfills.5ddcccdb990eb395f306.js"></script><script src="main.8a8efbaecb55a11ab3f9.js"></script></body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

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

View file

@ -0,0 +1 @@
!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++)o[a=i[p]]&&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:"50859d501eab13ab41b8",6:"62086d585c2ead0254d2",7:"fdc70b63fa397b86320a"}[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()}([]);

File diff suppressed because one or more lines are too long

View file

@ -83,7 +83,7 @@ export class AppComponent implements OnInit, AfterViewInit, OnDestroy {
this.userIdle.onTimeout().pipe(takeUntil(this.unsubs[3])).subscribe(() => {
if (this.sessionService.getItem('token')) {
this.logger.warn('Time limit exceeded for session inactivity.');
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.WARNING,
alertTitle: 'Logging out',
titleMessage: 'Time limit exceeded for session inactivity.'

View file

@ -13,7 +13,7 @@ import { CLEffects } from '../store/cl.effects';
import { RTLEffects } from '../../store/rtl.effects';
import * as RTLActions from '../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-cl-channels',
@ -118,9 +118,16 @@ export class CLChannelsComponent implements OnInit, OnDestroy {
}
if (channelToUpdate === 'all') {
const titleMsg = 'Updated Values for ALL Channels';
const confirmationMsg = {};
// const confirmationMsg = {};
const confirmationMsg = [[{key: '', value: '', title: '', width: 0, type: DataTypeEnum.NUMBER}]];
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Channels Update', titleMessage: titleMsg, noBtnText: 'Cancel', yesBtnText: 'Update', message: JSON.stringify(confirmationMsg), flgShowInput: true, getInputs: [
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Confirm Channels Update',
titleMessage: titleMsg,
noBtnText: 'Cancel',
yesBtnText: 'Update',
message: confirmationMsg,
flgShowInput: true, getInputs: [
{placeholder: 'Base Fee msat', inputType: 'number', inputValue: 1000},
{placeholder: 'Fee Rate mili msat', inputType: 'number', inputValue: 1, min: 1}
]
@ -153,9 +160,17 @@ export class CLChannelsComponent implements OnInit, OnDestroy {
this.logger.info(this.myChanPolicy);
this.store.dispatch(new RTLActions.CloseSpinner());
const titleMsg = 'Updated Values for Channel: ' + channelToUpdate.channel_id;
const confirmationMsg = {};
// const confirmationMsg = {};
const confirmationMsg = [[{key: '', value: '', title: '', width: 0, type: DataTypeEnum.NUMBER}]];
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Channel Update', titleMessage: titleMsg, noBtnText: 'Cancel', yesBtnText: 'Update', message: JSON.stringify(confirmationMsg), flgShowInput: true, getInputs: [
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Confirm Channel Update',
titleMessage: titleMsg,
noBtnText: 'Cancel',
yesBtnText: 'Update',
message: confirmationMsg,
flgShowInput: true,
getInputs: [
{placeholder: 'Base Fee msat', inputType: 'number', inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat},
{placeholder: 'Fee Rate mili msat', inputType: 'number', inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1}
]
@ -180,7 +195,7 @@ export class CLChannelsComponent implements OnInit, OnDestroy {
return;
}
if (channelToClose.state === 'AWAITING_UNILATERAL') {
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.WARNING,
alertTitle: 'Unable to Close Channel',
titleMessage: 'Channel can not be closed when it is in AWAITING UNILATERAL state.'
@ -216,13 +231,14 @@ export class CLChannelsComponent implements OnInit, OnDestroy {
const selChannel = this.channels.data.filter(channel => {
return channel.channel_id === selRow.channel_id;
})[0];
const reorderedChannel = JSON.parse(JSON.stringify(selChannel, [
'channel_id', 'short_channel_id', 'id', 'alias', 'connected', 'private', 'state', 'funding_txid', 'msatoshi_to_us', 'msatoshi_total', 'their_channel_reserve_satoshis', 'our_channel_reserve_satoshis', 'spendable_msatoshi'
] , 2));
const reorderedChannel = [
[{key: 'status', value: selChannel.status, title: 'Status', width: 100, type: DataTypeEnum.NUMBER}]
// 'channel_id', 'short_channel_id', 'id', 'alias', 'connected', 'private', 'state', 'funding_txid', 'msatoshi_to_us', 'msatoshi_total', 'their_channel_reserve_satoshis', 'our_channel_reserve_satoshis', 'spendable_msatoshi'
];
this.store.dispatch(new RTLActions.OpenAlert({width: '75%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Channel Information',
message: JSON.stringify(reorderedChannel)
message: reorderedChannel
}}));
}

View file

@ -10,7 +10,7 @@ import { LoggerService } from '../../shared/services/logger.service';
import * as RTLActions from '../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-cl-forwarding-history',
@ -82,10 +82,16 @@ export class CLForwardingHistoryComponent implements OnInit, OnDestroy {
const selFEvent = this.forwardingHistoryEvents.data.filter(fhEvent => {
return (fhEvent.received_time === selRow.received_time && fhEvent.in_channel === selRow.in_channel);
})[0];
const reorderedFHEvent = JSON.parse(JSON.stringify(selFEvent, [
'status', 'received_time_str', 'resolved_time_str', 'in_channel', 'out_channel', 'in_msatoshi', 'in_msat', 'out_msatoshi', 'out_msat', 'fee', 'fee_msat', 'payment_hash'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Forwarding History', message: JSON.stringify(reorderedFHEvent)}}));
const reorderedFHEvent = [
[{key: 'status', value: selFEvent.status, title: 'Status', width: 100, type: DataTypeEnum.NUMBER}]
// 'status', 'received_time_str', 'resolved_time_str', 'in_channel', 'out_channel', 'in_msatoshi', 'in_msat', 'out_msatoshi', 'out_msat', 'fee', 'fee_msat', 'payment_hash'
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '40%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Forwarding History',
message: reorderedFHEvent
}}));
}
loadForwardingEventsTable(forwardingEvents: ForwardingEventCL[]) {

View file

@ -6,7 +6,7 @@ import { Store } from '@ngrx/store';
import { MatTableDataSource, MatSort } from '@angular/material';
import { SelNodeChild } from '../../shared/models/RTLconfig';
import { GetInfoCL, InvoiceCL } from '../../shared/models/clModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, AlertTypeEnum, DataTypeEnum } from '../../shared/services/consts-enums-functions';
import { LoggerService } from '../../shared/services/logger.service';
import { newlyAddedRowAnimation } from '../../shared/animation/row-animation';
@ -119,13 +119,14 @@ export class CLInvoicesComponent implements OnInit, OnDestroy {
const selInvoice = this.invoices.data.filter(invoice => {
return invoice.bolt11 === selRow.bolt11;
})[0];
const reorderedInvoice = JSON.parse(JSON.stringify(selInvoice, [
'status', 'expires_at_str', 'paid_at_str', 'pay_index', 'label', 'bolt11', 'payment_hash', 'msatoshi', 'msatoshi_received', 'description'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const reorderedInvoice = [
[{key: 'status', value: selInvoice.status, title: 'Status', width: 100, type: DataTypeEnum.NUMBER}]
// 'status', 'expires_at_str', 'paid_at_str', 'pay_index', 'label', 'bolt11', 'payment_hash', 'msatoshi', 'msatoshi_received', 'description'
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Invoice Information',
message: JSON.stringify(reorderedInvoice)
message: reorderedInvoice
}}));
}

View file

@ -13,7 +13,7 @@ import { CLEffects } from '../store/cl.effects';
import { RTLEffects } from '../../store/rtl.effects';
import * as RTLActions from '../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-cl-on-chain',
@ -87,9 +87,16 @@ export class CLOnChainComponent implements OnInit, OnDestroy {
}
onSendFunds() {
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data:
{type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Send Funds', message: JSON.stringify(this.transaction), noBtnText: 'Cancel', yesBtnText: 'Send'}
}));
const reorderedTransaction = [
[{key: 'address', value: this.transaction.address, title: 'Address', width: 100, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Confirm Send Funds',
message: reorderedTransaction,
noBtnText: 'Cancel',
yesBtnText: 'Send'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unsub[3]))
.subscribe(confirmRes => {

View file

@ -12,7 +12,7 @@ import { LoggerService } from '../../../shared/services/logger.service';
import { CLEffects } from '../../store/cl.effects';
import * as RTLActions from '../../../store/rtl.actions';
import * as fromRTLReducer from '../../../store/rtl.reducers';
import { AlertTypeEnum } from '../../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-cl-query-routes',
@ -83,10 +83,15 @@ export class CLQueryRoutesComponent implements OnInit, OnDestroy {
const selRoute = this.qRoutes.data.filter(route => {
return route.id === route.id;
})[0];
const reorderedRoute = JSON.parse(JSON.stringify(selRoute, [
'id', 'alias', 'channel', 'direction', 'msatoshi', 'amount_msat', 'delay'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Route Information', message: JSON.stringify(reorderedRoute)}}));
const reorderedRoute = [
[{key: 'id', value: selRoute.id, title: 'ID', width: 100, type: DataTypeEnum.NUMBER}]
// 'id', 'alias', 'channel', 'direction', 'msatoshi', 'amount_msat', 'delay'
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Route Information',
message: reorderedRoute
}}));
}
ngOnDestroy() {

View file

@ -12,7 +12,7 @@ import { CLEffects } from '../../store/cl.effects';
import { RTLEffects } from '../../../store/rtl.effects';
import * as RTLActions from '../../../store/rtl.actions';
import * as fromRTLReducer from '../../../store/rtl.reducers';
import { AlertTypeEnum } from '../../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-cl-payments',
@ -102,12 +102,19 @@ export class CLPaymentsComponent implements OnInit, OnDestroy {
sendPayment() {
this.flgAnimate = true;
this.newlyAddedPayment = this.paymentDecoded.payment_hash;
const reorderedDecodedPayment = [
[{key: 'amount_msat', value: this.paymentDecoded.amount_msat, title: 'Amount (mSat)', width: 100, type: DataTypeEnum.NUMBER}]
];
if (undefined === this.paymentDecoded.msatoshi || this.paymentDecoded.msatoshi === 0) {
const titleMsg = 'It is an open amount invoice. Enter the amount (Sats) to pay.';
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Enter Amount and Confirm Send Payment', titleMessage: titleMsg, message: JSON.stringify(this.paymentDecoded), noBtnText: 'Cancel', yesBtnText: 'Send', flgShowInput: true, getInputs: [
{placeholder: 'Amount (mSats)', inputType: 'number', inputValue: ''}
]
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Enter Amount and Confirm Send Payment',
titleMessage: titleMsg,
message: reorderedDecodedPayment,
noBtnText: 'Cancel',
yesBtnText: 'Send',
flgShowInput: true, getInputs: [{placeholder: 'Amount (mSats)', inputType: 'number', inputValue: ''}]
}}));
this.rtlEffects.closeConfirm
.pipe(take(1))
@ -120,8 +127,16 @@ export class CLPaymentsComponent implements OnInit, OnDestroy {
}
});
} else {
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Send Payment', titleMessage: 'Send Payment', noBtnText: 'Cancel', yesBtnText: 'Send', message: JSON.stringify(this.paymentDecoded)
const reorderedDecodedPayment = [
[{key: 'amount_msat', value: this.paymentDecoded.amount_msat, title: 'Amount (mSat)', width: 100, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '40%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Confirm Send Payment',
titleMessage: 'Send Payment',
noBtnText: 'Cancel',
yesBtnText: 'Send',
message: reorderedDecodedPayment
}}));
this.rtlEffects.closeConfirm
.pipe(take(1))
@ -158,10 +173,15 @@ export class CLPaymentsComponent implements OnInit, OnDestroy {
const selPayment = this.payments.data.filter(payment => {
return payment.payment_hash === selRow.payment_hash;
})[0];
const reorderedPayment = JSON.parse(JSON.stringify(selPayment, [
'id', 'bolt11', 'created_at_str', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash', 'payment_preimage','amount_msat', 'amount_sent_msat'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Payment Information', message: JSON.stringify(reorderedPayment)}}));
const reorderedPayment = [
[{key: 'id', value: selPayment.id, title: 'Status', width: 100, type: DataTypeEnum.NUMBER}]
// 'id', 'bolt11', 'created_at_str', 'created_at', 'destination', 'status', 'msatoshi', 'msatoshi_sent', 'payment_hash', 'payment_preimage','amount_msat', 'amount_sent_msat'
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Payment Information',
message: reorderedPayment
}}));
}
applyFilter(selFilter: string) {

View file

@ -9,7 +9,7 @@ import { MatTableDataSource, MatSort } from '@angular/material';
import { PeerCL, GetInfoCL } from '../../shared/models/clModels';
import { DialogConfig } from '../../shared/models/alertData';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../shared/services/consts-enums-functions';
import { LoggerService } from '../../shared/services/logger.service';
import { newlyAddedRowAnimation } from '../../shared/animation/row-animation';
@ -105,10 +105,15 @@ export class CLPeersComponent implements OnInit, OnDestroy {
const selPeer = this.peers.data.filter(peer => {
return peer.id === selRow.id;
})[0];
const reorderedPeer = JSON.parse(JSON.stringify(selPeer, [
'id', 'alias', 'connected', 'netaddr', 'globalfeatures', 'localfeatures'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Peer Information', message: JSON.stringify(reorderedPeer)}}));
const reorderedPeer = [
[{key: 'status', value: selPeer.status, title: 'Status', width: 100, type: DataTypeEnum.NUMBER}]
// 'id', 'alias', 'connected', 'netaddr', 'globalfeatures', 'localfeatures'
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '40%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Peer Information',
message: reorderedPeer
}}));
}
resetData() {

View file

@ -14,7 +14,8 @@ import { GetInfoCL, FeesCL, BalanceCL, LocalRemoteBalanceCL, PaymentCL, FeeRates
import * as fromRTLReducer from '../../store/rtl.reducers';
import * as RTLActions from '../../store/rtl.actions';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../shared/services/consts-enums-functions';
import { ErrorMessageComponent } from '../../shared/components/data-modal/error-message/error-message.component';
@Injectable()
export class CLEffects implements OnDestroy {
@ -211,7 +212,7 @@ export class CLEffects implements OnDestroy {
map((postRes: any) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Peer Connected', titleMessage: 'Peer Added Successfully!' }}));
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Peer Connected', titleMessage: 'Peer Added Successfully!' }}));
return {
type: RTLActions.SET_PEERS_CL,
payload: (postRes && postRes.length > 0) ? postRes : []
@ -234,7 +235,7 @@ export class CLEffects implements OnDestroy {
map((postRes: any) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Peer Disconnected', titleMessage: 'Peer Disconnected Successfully!' }}));
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Peer Disconnected', titleMessage: 'Peer Disconnected Successfully!' }}));
return {
type: RTLActions.REMOVE_PEER_CL,
payload: { id: action.payload.id }
@ -303,7 +304,7 @@ export class CLEffects implements OnDestroy {
map((postRes: any) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Channel Updated', titleMessage: 'Channel Updated Successfully!' }}));
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Channel Updated', titleMessage: 'Channel Updated Successfully!' }}));
return {
type: RTLActions.FETCH_CHANNELS_CL
};
@ -404,10 +405,17 @@ export class CLEffects implements OnDestroy {
if (sendRes.error) {
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.PAYMENTS_API, { status: sendRes.status, error: sendRes.error.message });
} else {
const reorderedRes = [
[{key: 'status', value: sendRes.status, title: 'Status', width: 100, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({
width: '70%',
data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Payment Sent', titleMessage: 'Payment Sent Successfully!', message: JSON.stringify(sendRes) }
}));
data: {
type: AlertTypeEnum.SUCCESS,
alertTitle: 'Payment Sent',
titleMessage: 'Payment Sent Successfully!',
message: reorderedRes
}}));
this.store.dispatch(new RTLActions.FetchChannelsCL());
this.store.dispatch(new RTLActions.FetchBalanceCL());
this.store.dispatch(new RTLActions.FetchPaymentsCL());
@ -606,9 +614,17 @@ export class CLEffects implements OnDestroy {
postRes.expires_at_str = new Date(+postRes.expires_at * 1000).toUTCString();
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
const reorderedRes = [
[{key: 'status', value: postRes.bolt11, title: 'Status', width: 100, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({
width: '70%',
data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Invoice Created', titleMessage: 'Invoice Added Successfully!', message: JSON.stringify(postRes) }
data: {
type: AlertTypeEnum.SUCCESS,
alertTitle: 'Invoice Created',
titleMessage: 'Invoice Added Successfully!',
message: reorderedRes
}
}));
return {
type: RTLActions.FETCH_INVOICES_CL,
@ -732,11 +748,12 @@ export class CLEffects implements OnDestroy {
} else {
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({
width: '70%', data: {
width: '55%',
data: {
type: alerType,
alertTitle: alertTitle,
titleMessage: alertTitle,
message: JSON.stringify({ code: err.status, Message: err.error.error, URL: errURL })
message: { code: err.status, message: err.error.error, URL: errURL },
component: ErrorMessageComponent
}
}));
}

View file

@ -1,109 +1,106 @@
<div fxLayout="column" fxLayout.gt-sm="row wrap">
<mat-card fxFlex="100" fxLayoutAlign="start start">
<mat-card-content fxFlex="100" *ngIf="lookupResult">
<mat-list fxLayoutAlign="space-between start">
<mat-list-item fxFlex="30" fxLayoutAlign="start start">Channel Id</mat-list-item>
<mat-list-item fxFlex="68" fxLayoutAlign="start start">{{lookupResult.channel_id}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="space-between start">
<mat-list-item fxFlex="30" fxLayoutAlign="start start">Channel Point</mat-list-item>
<mat-list-item fxFlex="68" fxLayoutAlign="start start" class="word-break">{{lookupResult.chan_point}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="space-between start">
<mat-list-item fxFlex="30" fxLayoutAlign="start start">Last Update</mat-list-item>
<mat-list-item fxFlex="68" fxLayoutAlign="start start">{{lookupResult.last_update_str}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="space-between start">
<mat-list-item fxFlex="30" fxLayoutAlign="start start">Capacity (Sats)</mat-list-item>
<mat-list-item fxFlex="68" fxLayoutAlign="start start">{{lookupResult.capacity | number}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
</mat-card-content>
</mat-card>
</div>
<div fxLayout="column" fxLayoutAlign="space-between start" fxLayout.gt-sm="row wrap" class="mt-2">
<div fxFlex="48">
<mat-card class="custom-card mat-elevation-z12">
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
<mat-card-title class="m-0 pt-2">
<h5 *ngIf="!node1_match">Node 1</h5>
<h5 *ngIf="node1_match">Node 1 (Your Node)</h5>
</mat-card-title>
</mat-card-header>
<mat-card-content class="px-2">
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="100" fxLayoutAlign="start start" class="word-break">{{lookupResult.node1_pub}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Time Lock Delta</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.time_lock_delta}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Min HTLC</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.min_htlc}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Fee Base Msat</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.fee_base_msat}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Fee Rate Milli Msat</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.fee_rate_milli_msat}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Disabled</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.disabled}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
</mat-card-content>
</mat-card>
<div fxLayout="column" *ngIf="lookupResult">
<mat-list fxLayoutAlign="space-between start">
<mat-list-item fxFlex="30" fxLayoutAlign="start start">Channel Id</mat-list-item>
<mat-list-item fxFlex="68" fxLayoutAlign="start start">{{lookupResult.channel_id}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="space-between start">
<mat-list-item fxFlex="30" fxLayoutAlign="start start">Channel Point</mat-list-item>
<mat-list-item fxFlex="68" fxLayoutAlign="start start" class="word-break">{{lookupResult.chan_point}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="space-between start">
<mat-list-item fxFlex="30" fxLayoutAlign="start start">Last Update</mat-list-item>
<mat-list-item fxFlex="68" fxLayoutAlign="start start">{{lookupResult.last_update_str}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="space-between start">
<mat-list-item fxFlex="30" fxLayoutAlign="start start">Capacity (Sats)</mat-list-item>
<mat-list-item fxFlex="68" fxLayoutAlign="start start">{{lookupResult.capacity | number}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<div fxLayout="column" fxLayoutAlign="space-between start" fxLayout.gt-sm="row wrap" class="mt-1">
<div fxFlex="48">
<mat-card class="custom-card">
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
<mat-card-title class="m-0 pt-2">
<h5 *ngIf="!node1_match">Node 1</h5>
<h5 *ngIf="node1_match">Node 1 (Your Node)</h5>
</mat-card-title>
</mat-card-header>
<mat-card-content class="px-2">
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="100" fxLayoutAlign="start start" class="word-break">{{lookupResult.node1_pub}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Time Lock Delta</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.time_lock_delta}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Min HTLC</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.min_htlc}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Fee Base Msat</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.fee_base_msat}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Fee Rate Milli Msat</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.fee_rate_milli_msat}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Disabled</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node1_policy.disabled}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
</mat-card-content>
</mat-card>
</div>
<div fxFlex="48">
<mat-card class="custom-card">
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
<mat-card-title class="m-0 pt-2">
<h5 *ngIf="!node2_match">Node 2</h5>
<h5 *ngIf="node2_match">Node 2 (Your Node)</h5>
</mat-card-title>
</mat-card-header>
<mat-card-content class="px-2">
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="100" fxLayoutAlign="start start" class="word-break">{{lookupResult.node2_pub}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Time Lock Delta</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.time_lock_delta}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Min HTLC</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.min_htlc}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Fee Base Msat</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.fee_base_msat}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Fee Rate Milli Msat</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.fee_rate_milli_msat}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Disabled</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.disabled}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
</mat-card-content>
</mat-card>
</div>
</div>
<div fxFlex="48">
<mat-card class="custom-card mat-elevation-z12">
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
<mat-card-title class="m-0 pt-2">
<h5 *ngIf="!node2_match">Node 2</h5>
<h5 *ngIf="node2_match">Node 2 (Your Node)</h5>
</mat-card-title>
</mat-card-header>
<mat-card-content class="px-2">
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="100" fxLayoutAlign="start start" class="word-break">{{lookupResult.node2_pub}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Time Lock Delta</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.time_lock_delta}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Min HTLC</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.min_htlc}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Fee Base Msat</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.fee_base_msat}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Fee Rate Milli Msat</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.fee_rate_milli_msat}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Disabled</mat-list-item>
<mat-list-item fxFlex="50" fxLayoutAlign="start start">{{lookupResult.node2_policy.disabled}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
</mat-card-content>
</mat-card>
</div>

View file

@ -1,46 +1,37 @@
<div fxLayout="column">
<div class="padding-gap">
<mat-card>
<mat-card-header>
<mat-card-subtitle>
<h2>Lookups</h2>
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<form fxLayout="column" fxLayout.gt-sm="row wrap" #form="ngForm">
<mat-form-field fxFlex="20" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selectedField" placeholder="Lookup Field" (selectionChange)="onSelectChange($event)" tabindex="1" required name="lookupField">
<mat-option *ngFor="let lookupField of lookupFields" [value]="lookupField">
<div fxLayout="row" fxLayoutAlign="start end" class="padding-gap-x page-title-container">
<fa-icon [icon]="faSearch" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Lookups</span>
</div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start start" class="padding-gap-x">
<mat-card fxLayout="row" fxFlex="100" fxLayoutAlign="start start">
<mat-card-content fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="card-content-gap">
<form fxFlex="100" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="w-100" #form="ngForm">
<mat-form-field fxFlex="22" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selectedFieldId" placeholder="Lookup Field" (selectionChange)="onSelectChange($event)" tabindex="1" required name="lookupField">
<mat-option *ngFor="let lookupField of lookupFields" [value]="lookupField.id">
{{lookupField.name}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="50" fxLayoutAlign="start end">
<input matInput name="lookupKey" [placeholder]="selectedField?.placeholder || 'Lookup Key'" (change)="clearLookupValue()" [(ngModel)]="lookupKey" tabindex="2" required>
<input matInput name="lookupKey" [placeholder]="lookupFields[selectedFieldId]?.placeholder || 'Lookup Key'" (change)="clearLookupValue()" [(ngModel)]="lookupKey" tabindex="2" required>
</mat-form-field>
<div fxFlex="12" fxLayoutAlign="start start">
<button fxFlex="90" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="3" type="submit" (click)="onLookup()" [disabled]="!form.valid">Lookup</button>
<div fxFlex="25" fxLayoutAlign="space-between center">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="3" type="button" (click)="resetData()">Clear</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="4" type="submit" (click)="onLookup()" [disabled]="!form.valid">Lookup</button>
</div>
<div fxFlex="12" fxLayoutAlign="start start">
<button fxFlex="90" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="4" type="reset" (click)="resetData()">Clear</button>
</form>
<div fxFlex="100" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" *ngIf="lookupValue && flgSetLookupValue" class="w-100 mt-2">
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start center">
<span class="page-title font-bold-500">{{lookupFields[selectedFieldId].name}} Details</span>
</div>
</form>
</mat-card-content>
</mat-card>
</div>
<div class="padding-gap" *ngIf="lookupValue && flgSetLookupValue">
<mat-card [ngClass]="{'error-border': flgLoading[0]==='error'}">
<mat-card-header>
<mat-card-subtitle>
<h2>{{selectedField.name}} Details</h2>
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div [ngSwitch]="selectedField.id">
<span *ngSwitchCase="0"><rtl-node-lookup [lookupResult]="lookupValue"></rtl-node-lookup></span>
<span *ngSwitchCase="1"><rtl-channel-lookup [lookupResult]="lookupValue"></rtl-channel-lookup></span>
<span *ngSwitchDefault><h3>Error! Unable to find details!</h3></span>
</div>
<div [ngSwitch]="selectedFieldId" fxLayout="row" fxFlex="100" fxLayoutAlign="start center">
<span fxFlex="100" *ngSwitchCase="0"><rtl-node-lookup [lookupResult]="lookupValue"></rtl-node-lookup></span>
<span fxFlex="100" *ngSwitchCase="1"><rtl-channel-lookup [lookupResult]="lookupValue"></rtl-channel-lookup></span>
<span fxFlex="100" *ngSwitchDefault><h3>Error! Unable to find details!</h3></span>
</div>
</div>
</mat-card-content>
</mat-card>
</div>

View file

@ -3,6 +3,7 @@ import { Subject } from 'rxjs';
import { takeUntil, filter } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { faSearch } from '@fortawesome/free-solid-svg-icons';
import { LoggerService } from '../../shared/services/logger.service';
@ -20,12 +21,13 @@ export class LookupsComponent implements OnInit, OnDestroy {
public flgSetLookupValue = false;
public temp: any;
public messageObj = [];
public selectedField = { id: '0', name: 'Node', placeholder: 'Pubkey'};
public selectedFieldId = 0;
public lookupFields = [
{ id: '0', name: 'Node', placeholder: 'Pubkey'},
{ id: '1', name: 'Channel', placeholder: 'Channel ID'}
{ id: 0, name: 'Node', placeholder: 'Pubkey'},
{ id: 1, name: 'Channel', placeholder: 'Channel ID'}
];
public flgLoading: Array<Boolean | 'error'> = [true];
public faSearch = faSearch;
private unSubs: Array<Subject<void>> = [new Subject()];
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) {}
@ -35,27 +37,28 @@ export class LookupsComponent implements OnInit, OnDestroy {
.pipe(
takeUntil(this.unSubs[0]),
filter((action) => (action.type === RTLActions.SET_LOOKUP || action.type === RTLActions.EFFECT_ERROR_LND))
).subscribe((resLookup: RTLActions.SetLookup) => {
if (resLookup.payload.action === 'Lookup') {
this.flgLoading[0] = 'error';
} else {
).subscribe((resLookup: RTLActions.SetLookup | RTLActions.EffectErrorLnd) => {
if(resLookup.type === RTLActions.SET_LOOKUP) {
this.flgLoading[0] = true;
this.lookupValue = JSON.parse(JSON.stringify(resLookup.payload));
this.flgSetLookupValue = true;
this.logger.info(this.lookupValue);
}
if (resLookup.type === RTLActions.EFFECT_ERROR_LND && resLookup.payload.action === 'Lookup') {
this.flgLoading[0] = 'error';
}
});
}
onLookup() {
this.flgSetLookupValue = false;
this.lookupValue = {};
this.store.dispatch(new RTLActions.OpenSpinner('Searching ' + this.selectedField.name + '...'));
switch (this.selectedField.id) {
case '0':
this.store.dispatch(new RTLActions.OpenSpinner('Searching ' + this.lookupFields[this.selectedFieldId].name + '...'));
switch (this.selectedFieldId) {
case 0:
this.store.dispatch(new RTLActions.PeerLookup(this.lookupKey.trim()));
break;
case '1':
case 1:
this.store.dispatch(new RTLActions.ChannelLookup(this.lookupKey.trim()));
break;
default:
@ -71,8 +74,8 @@ export class LookupsComponent implements OnInit, OnDestroy {
resetData() {
this.flgSetLookupValue = false;
this.selectedFieldId = 0;
this.lookupKey = '';
this.selectedField = { id: '0', name: 'Node', placeholder: 'Pubkey'};
this.lookupValue = {};
this.flgLoading.forEach((flg, i) => {
this.flgLoading[i] = true;

View file

@ -1,56 +1,52 @@
<div fxLayout="column">
<div class="padding-gap">
<mat-card>
<mat-card-content *ngIf="lookupResult">
<div fxLayout="column">
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Alias</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.node.alias}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Pub Key</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.node.pub_key}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Color</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start"><span [ngStyle]="{'background-color': lookupResult.node?.color}">{{lookupResult.node?.color}}</span></mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Last Update</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.node.last_update_str}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Total Capacity (Sats)</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.total_capacity | number}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Number of Channels</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.num_channels | number}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayout="column" fxLayoutAlign="start start">
<mat-divider></mat-divider>
<mat-list-item fxFlex="100" fxLayoutAlign="start start">Addresses</mat-list-item>
<mat-table [dataSource]="lookupResult.node.addresses" matSort class="mat-elevation-z8 overflow-auto">
<ng-container matColumnDef="network">
<mat-header-cell *matHeaderCellDef mat-sort-header>Network</mat-header-cell>
<mat-cell *matCellDef="let address"><div>{{address?.network}}</div></mat-cell>
</ng-container>
<ng-container matColumnDef="addr">
<mat-header-cell *matHeaderCellDef mat-sort-header>Address</mat-header-cell>
<mat-cell *matCellDef="let address"><div>{{address?.addr}}</div></mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns;"></mat-header-row>
<mat-row fxLayoutAlign="stretch stretch" *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>
</mat-list>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
<div fxLayout="column" *ngIf="lookupResult">
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Alias</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.node.alias}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Pub Key</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.node.pub_key}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Color</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start"><span [ngStyle]="{'background-color': lookupResult.node?.color}">{{lookupResult.node?.color}}</span></mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Last Update</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.node.last_update_str}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Total Capacity (Sats)</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.total_capacity | number}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayoutAlign="start start">
<mat-list-item fxFlex="50" fxLayoutAlign="start start">Number of Channels</mat-list-item>
<mat-list-item fxFlex="40" fxLayoutAlign="start start">{{lookupResult.num_channels | number}}</mat-list-item>
<mat-divider></mat-divider>
</mat-list>
<mat-list fxLayout="column" fxLayoutAlign="start start">
<mat-divider></mat-divider>
<mat-list-item fxFlex="100" fxLayoutAlign="start start">Addresses</mat-list-item>
<div fxLayout="row" fxLayoutAlign="start center" class="w-100">
<div perfectScrollbar class="table-container" fxFlex="100">
<table mat-table [dataSource]="lookupResult.node.addresses" matSort class="overflow-auto">
<ng-container matColumnDef="network">
<mat-header-cell *matHeaderCellDef mat-sort-header>Network</mat-header-cell>
<mat-cell *matCellDef="let address"><div>{{address?.network}}</div></mat-cell>
</ng-container>
<ng-container matColumnDef="addr">
<mat-header-cell *matHeaderCellDef mat-sort-header>Address</mat-header-cell>
<mat-cell *matCellDef="let address"><div>{{address?.addr}}</div></mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="displayedColumns;"></mat-header-row>
<mat-row fxLayoutAlign="stretch stretch" *matRowDef="let row; columns: displayedColumns;"></mat-row>
</table>
</div>
</div>
</mat-list>
</div>

View file

@ -36,9 +36,9 @@ export class OnChainReceiveComponent implements OnInit, OnDestroy {
this.store.dispatch(new RTLActions.OpenAlert({
width: '58%',
data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Generated Address',
message: JSON.stringify({address: this.newAddress, addressType: this.selectedAddressType.addressTp}),
address: this.newAddress,
addressType: this.selectedAddressType.addressTp,
component: OnChainGeneratedAddressComponent
}
}));

View file

@ -7,7 +7,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
import { SelNodeChild, GetInfoRoot } from '../../../shared/models/RTLconfig';
import { GetInfo, Balance, ChannelsTransaction, AddressType } from '../../../shared/models/lndModels';
import { CURRENCY_UNITS, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, AlertTypeEnum } from '../../../shared/services/consts-enums-functions';
import { CURRENCY_UNITS, CurrencyUnitEnum, CURRENCY_UNIT_FORMATS, AlertTypeEnum, DataTypeEnum } from '../../../shared/services/consts-enums-functions';
import { RTLConfiguration } from '../../../shared/models/RTLconfig';
import { CommonService } from '../../../shared/services/common.service';
import { LoggerService } from '../../../shared/services/logger.service';
@ -16,6 +16,7 @@ import * as sha256 from 'sha256';
import { RTLEffects } from '../../../store/rtl.effects';
import * as RTLActions from '../../../store/rtl.actions';
import * as fromRTLReducer from '../../../store/rtl.reducers';
import { MessageDataField } from '../../../shared/models/alertData';
@Component({
selector: 'rtl-on-chain-send',
@ -99,34 +100,42 @@ export class OnChainSendComponent implements OnInit, OnDestroy {
}
confirmSend() {
const confirmationMsg = {
'BTC Address': this.transaction.address,
};
const confirmationMsg: Array<Array<MessageDataField>> = [
[{key: 'address', value: this.transaction.address, title: 'BTC Address', width: 100}]
];
if (this.sweepAll) {
confirmationMsg['Sweep All'] = 'True';
confirmationMsg.push([{key: 'sweep_all', value: true, title: 'Sweep All', width: 50, type: DataTypeEnum.BOOLEAN}]);
this.transaction.sendAll = true;
} else {
confirmationMsg['Amount (' + this.nodeData.smaller_currency_unit + ')'] = this.transaction.amount;
confirmationMsg.push([{key: 'amount', value: this.transaction.amount, title: 'Amount (' + this.nodeData.smaller_currency_unit + ')', width: 50, type: DataTypeEnum.NUMBER}]);
this.transaction.sendAll = false;
}
if (this.selTransType === '1') {
delete this.transaction.fees;
confirmationMsg['Target Confirmation Blocks'] = this.transaction.blocks;
confirmationMsg[1].push({key: 'target_conf_blocks', value: this.transaction.blocks, title: 'Target Confirmation Blocks', width: 50, type: DataTypeEnum.NUMBER});
} else {
delete this.transaction.blocks;
confirmationMsg['Fee (' + this.nodeData.smaller_currency_unit + '/Byte)'] = this.transaction.fees;
confirmationMsg[1].push({key: 'fees_per_byte', value: this.transaction.fees, title: 'Fee (' + this.nodeData.smaller_currency_unit + '/Byte)', width: 50, type: DataTypeEnum.NUMBER});
}
if (this.sweepAll && !+this.appConfig.sso.rtlSSO) {
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data:
{type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Payment', titleMessage: 'Please authorize to sweep all funds with login password.',
message: JSON.stringify(confirmationMsg), noBtnText: 'Cancel', yesBtnText: 'Authorize And Sweep All Funds',
flgShowInput: true, getInputs: [{placeholder: 'Enter Login Password', inputType: 'password', inputValue: ''}
]}
}));
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '55%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Confirm Payment',
titleMessage: 'Please authorize to sweep all funds with login password.',
message: confirmationMsg,
noBtnText: 'Cancel',
yesBtnText: 'Authorize And Sweep All',
flgShowInput: true,
getInputs: [{placeholder: 'Enter Login Password', inputType: 'password', inputValue: ''}]
}}));
} else {
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data:
{type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Payment', message: JSON.stringify(confirmationMsg), noBtnText: 'Cancel', yesBtnText: 'Send'}
}));
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '55%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Confirm Payment',
message: confirmationMsg,
noBtnText: 'Cancel',
yesBtnText: 'Send'
}}));
}
}

View file

@ -7,7 +7,7 @@ import { faHistory } from '@fortawesome/free-solid-svg-icons';
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
import { Transaction } from '../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum } from '../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../shared/services/logger.service';
import { RTLEffects } from '../../../store/rtl.effects';
@ -93,12 +93,21 @@ export class OnChainTransactionHistoryComponent implements OnInit, OnDestroy {
const selTransaction = this.listTransactions.data.filter(transaction => {
return transaction.tx_hash === selRow.tx_hash;
})[0];
const reorderedTransactions = JSON.parse(JSON.stringify(selTransaction, ['dest_addresses', 'block_hash', 'tx_hash', 'time_stamp_str', 'block_height', 'num_confirmations', 'total_fees', 'amount'], 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '35%', data: {
const reorderedTransactions = [
[{key: 'dest_addresses', value: selTransaction.dest_addresses, title: 'Destination Address', width: 100, type: DataTypeEnum.ARRAY}],
[{key: 'block_hash', value: selTransaction.block_hash, title: 'Block Hash', width: 100}],
[{key: 'tx_hash', value: selTransaction.tx_hash, title: 'Transaction Hash', width: 100}],
[{key: 'time_stamp_str', value: selTransaction.time_stamp_str, title: 'Date/Time', width: 50, type: DataTypeEnum.DATE_TIME},
{key: 'block_height', value: selTransaction.block_height, title: 'Block Height', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'num_confirmations', value: selTransaction.num_confirmations, title: 'Number of Confirmations', width: 50, type: DataTypeEnum.NUMBER},
{key: 'total_fees', value: selTransaction.total_fees, title: 'Total Fees (Sats)', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'amount', value: selTransaction.amount, title: 'Amount (Sats)', width: 50, type: DataTypeEnum.NUMBER},
{key: 'active', value: selTransaction.active, title: 'Active', width: 50, type: DataTypeEnum.BOOLEAN}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '40%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Transaction Information',
message: JSON.stringify(reorderedTransactions),
messageFieldsBreakdown: [1, 1, 1, 2, 3]
message: reorderedTransactions,
}}));
}

View file

@ -12,7 +12,7 @@ import { LoggerService } from '../../../shared/services/logger.service';
import { LNDEffects } from '../../store/lnd.effects';
import * as RTLActions from '../../../store/rtl.actions';
import * as fromRTLReducer from '../../../store/rtl.reducers';
import { AlertTypeEnum } from '../../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-query-routes',
@ -83,10 +83,16 @@ export class QueryRoutesComponent implements OnInit, OnDestroy {
const selHop = this.qrHops.data.filter(hop => {
return hop.hop_sequence === selRow.hop_sequence;
})[0];
const reorderedHop = JSON.parse(JSON.stringify(selHop, [
'hop_sequence', 'pubkey_alias', 'pub_key', 'chan_id', 'chan_capacity', 'expiry', 'amt_to_forward', 'amt_to_forward_msat', 'fee_msat'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Route Information', message: JSON.stringify(reorderedHop)}}));
const reorderedHop = [
[{key: 'active', value: selHop.active, title: 'Active', width: 100, type: DataTypeEnum.NUMBER}]
// 'hop_sequence', 'pubkey_alias', 'pub_key', 'chan_id', 'chan_capacity', 'expiry', 'amt_to_forward', 'amt_to_forward_msat', 'fee_msat'
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Route Information',
message: reorderedHop
}}));
}
ngOnDestroy() {

View file

@ -6,7 +6,7 @@ import { Store } from '@ngrx/store';
import { MatTableDataSource, MatSort } from '@angular/material';
import { Channel, Peer, GetInfo } from '../../../../shared/models/lndModels';
import { TRANS_TYPES, AlertTypeEnum } from '../../../../shared/services/consts-enums-functions';
import { TRANS_TYPES, AlertTypeEnum, DataTypeEnum } from '../../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../../shared/services/logger.service';
import { LNDEffects } from '../../../store/lnd.effects';
@ -24,57 +24,23 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
public totalBalance = 0;
public selectedPeer = '';
public fundingAmount: number;
public displayedColumns = [];
public channels: any;
public peers: Peer[] = [];
public information: GetInfo = {};
public flgLoading: Array<Boolean | 'error'> = [true];
public selectedFilter = '';
public myChanPolicy: any = {};
public selFilter = '';
public transTypes = TRANS_TYPES;
public selTransType = '0';
public transTypeValue = {blocks: '', fees: ''};
public spendUnconfirmed = false;
public isPrivate = false;
public showAdvanced = false;
public flgSticky = false;
public redirectedWithPeer = false;
private unsub: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects, private lndEffects: LNDEffects, private activatedRoute: ActivatedRoute) {
switch (true) {
case (window.innerWidth <= 415):
this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias'];
break;
case (window.innerWidth > 415 && window.innerWidth <= 730):
this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias', 'capacity'];
break;
case (window.innerWidth > 730 && window.innerWidth <= 1024):
this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias', 'capacity', 'local_balance', 'remote_balance'];
break;
case (window.innerWidth > 1024 && window.innerWidth <= 1280):
this.flgSticky = true;
this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_alias', 'capacity', 'local_balance', 'remote_balance', 'total_satoshis_sent',
'total_satoshis_received', 'commit_fee', 'private'];
break;
default:
this.flgSticky = true;
this.displayedColumns = ['close', 'update', 'active', 'chan_id', 'remote_pubkey', 'remote_alias', 'capacity', 'local_balance', 'remote_balance',
'total_satoshis_sent', 'total_satoshis_received', 'commit_fee', 'private'];
break;
}
}
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>, private activatedRoute: ActivatedRoute) {}
ngOnInit() {
this.store.select('lnd')
.pipe(takeUntil(this.unsub[0]))
.subscribe((rtlStore) => {
rtlStore.effectErrorsLnd.forEach(effectsErr => {
if (effectsErr.action === 'FetchChannels/all') {
this.flgLoading[0] = 'error';
}
});
this.information = rtlStore.information;
this.peers = rtlStore.peers;
this.peers.forEach(peer => {
@ -82,20 +48,9 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
peer.alias = peer.pub_key.substring(0, 15) + '...';
}
});
this.totalBalance = +rtlStore.blockchainBalance.total_balance;
if (undefined !== rtlStore.allChannels) {
this.loadChannelsTable(rtlStore.allChannels);
}
if (this.flgLoading[0] !== 'error') {
this.flgLoading[0] = (undefined !== rtlStore.allChannels) ? false : true;
}
this.logger.info(rtlStore);
});
this.activatedRoute.paramMap.subscribe(() => {
this.selectedPeer = window.history.state.peer;
this.redirectedWithPeer = (window.history.state.peer) ? true : false;
});
}
onOpenChannel() {
@ -112,129 +67,6 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
}));
}
onChannelUpdate(channelToUpdate: any) {
if (channelToUpdate === 'all') {
const titleMsg = 'Updated Values for ALL Channels';
const confirmationMsg = {};
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Channels Update', titleMessage: titleMsg, noBtnText: 'Cancel', yesBtnText: 'Update', message: JSON.stringify(confirmationMsg), flgShowInput: true, getInputs: [
{placeholder: 'Base Fee msat', inputType: 'number', inputValue: 1000},
{placeholder: 'Fee Rate mili msat', inputType: 'number', inputValue: 1, min: 1},
{placeholder: 'Time Lock Delta', inputType: 'number', inputValue: 144}
]
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unsub[2]))
.subscribe(confirmRes => {
if (confirmRes) {
const base_fee = confirmRes[0].inputValue;
const fee_rate = confirmRes[1].inputValue;
const time_lock_delta = confirmRes[2].inputValue;
this.store.dispatch(new RTLActions.OpenSpinner('Updating Channel Policy...'));
this.store.dispatch(new RTLActions.UpdateChannels({baseFeeMsat: base_fee, feeRate: fee_rate, timeLockDelta: time_lock_delta, chanPoint: 'all'}));
}
});
} else {
this.myChanPolicy = {fee_base_msat: 0, fee_rate_milli_msat: 0, time_lock_delta: 0};
this.store.dispatch(new RTLActions.OpenSpinner('Fetching Channel Policy...'));
this.store.dispatch(new RTLActions.ChannelLookup(channelToUpdate.chan_id.toString()));
this.lndEffects.setLookup
.pipe(takeUntil(this.unsub[3]))
.subscribe(resLookup => {
this.logger.info(resLookup);
if (resLookup.node1_pub === this.information.identity_pubkey) {
this.myChanPolicy = resLookup.node1_policy;
} else if (resLookup.node2_pub === this.information.identity_pubkey) {
this.myChanPolicy = resLookup.node2_policy;
} else {
this.myChanPolicy = {fee_base_msat: 0, fee_rate_milli_msat: 0, time_lock_delta: 0};
}
this.logger.info(this.myChanPolicy);
this.store.dispatch(new RTLActions.CloseSpinner());
const titleMsg = 'Updated Values for Channel Point: ' + channelToUpdate.channel_point;
const confirmationMsg = {};
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Channel Update', titleMessage: titleMsg, noBtnText: 'Cancel', yesBtnText: 'Update', message: JSON.stringify(confirmationMsg), flgShowInput: true, getInputs: [
{placeholder: 'Base Fee msat', inputType: 'number', inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat},
{placeholder: 'Fee Rate mili msat', inputType: 'number', inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1},
{placeholder: 'Time Lock Delta', inputType: 'number', inputValue: this.myChanPolicy.time_lock_delta}
]
}}));
});
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unsub[2]))
.subscribe(confirmRes => {
if (confirmRes) {
const base_fee = confirmRes[0].inputValue;
const fee_rate = confirmRes[1].inputValue;
const time_lock_delta = confirmRes[2].inputValue;
this.store.dispatch(new RTLActions.OpenSpinner('Updating Channel Policy...'));
this.store.dispatch(new RTLActions.UpdateChannels({baseFeeMsat: base_fee, feeRate: fee_rate, timeLockDelta: time_lock_delta, chanPoint: channelToUpdate.channel_point}));
}
});
}
this.applyFilter();
}
onChannelClose(channelToClose: Channel) {
this.store.dispatch(new RTLActions.OpenConfirmation({
width: '70%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Channel Closing', titleMessage: 'Closing channel: ' + channelToClose.chan_id, noBtnText: 'Cancel', yesBtnText: 'Close Channel'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unsub[1]))
.subscribe(confirmRes => {
if (confirmRes) {
this.store.dispatch(new RTLActions.OpenSpinner('Closing Channel...'));
this.store.dispatch(new RTLActions.CloseChannel({channelPoint: channelToClose.channel_point, forcibly: !channelToClose.active}));
}
});
}
applyFilter() {
this.selectedFilter = this.selFilter;
this.channels.filter = this.selFilter;
}
onChannelClick(selRow: Channel, event: any) {
const flgCloseClicked =
event.target.className.includes('mat-column-close')
|| event.target.className.includes('mat-column-update')
|| event.target.className.includes('mat-icon');
if (flgCloseClicked) {
return;
}
const selChannel = this.channels.data.filter(channel => {
return channel.chan_id === selRow.chan_id;
})[0];
const reorderedChannel = JSON.parse(JSON.stringify(selChannel, [
'active', 'remote_pubkey', 'remote_alias', 'channel_point', 'chan_id', 'capacity', 'local_balance', 'remote_balance', 'commit_fee', 'commit_weight',
'fee_per_kw', 'unsettled_balance', 'total_satoshis_sent', 'total_satoshis_received', 'num_updates', 'pending_htlcs', 'csv_delay', 'private'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Channel Information',
message: JSON.stringify(reorderedChannel)
}}));
}
loadChannelsTable(channels) {
channels.sort(function(a, b) {
return (a.active === b.active) ? 0 : ((b.active) ? 1 : -1);
});
this.channels = new MatTableDataSource<Channel>([...channels]);
this.channels.sort = this.sort;
this.channels.filterPredicate = (channel: Channel, fltr: string) => {
const newChannel = ((channel.active) ? 'active' : 'inactive') + (channel.chan_id ? channel.chan_id : '') +
(channel.remote_pubkey ? channel.remote_pubkey : '') + (channel.remote_alias ? channel.remote_alias : '') +
(channel.capacity ? channel.capacity : '') + (channel.local_balance ? channel.local_balance : '') +
(channel.remote_balance ? channel.remote_balance : '') + (channel.total_satoshis_sent ? channel.total_satoshis_sent : '') +
(channel.total_satoshis_received ? channel.total_satoshis_received : '') + (channel.commit_fee ? channel.commit_fee : '') +
(channel.private ? 'private' : 'public');
return newChannel.includes(fltr);
};
this.logger.info(this.channels);
}
resetData() {
this.selectedPeer = '';
this.fundingAmount = 0;
@ -243,7 +75,6 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
this.isPrivate = false;
this.selTransType = '0';
this.transTypeValue = {blocks: '', fees: ''};
this.redirectedWithPeer = false;
}
onShowAdvanced() {

View file

@ -7,7 +7,7 @@ import { Actions } from '@ngrx/effects';
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
import { SelNodeChild } from '../../../../../shared/models/RTLconfig';
import { Channel } from '../../../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../../../shared/services/logger.service';
import * as RTLActions from '../../../../../store/rtl.actions';
@ -95,14 +95,30 @@ export class ChannelBackupTableComponent implements OnInit, OnDestroy {
const selChannel = this.channels.data.filter(channel => {
return channel.chan_id === selRow.chan_id;
})[0];
const reorderedChannel = JSON.parse(JSON.stringify(selChannel, [
'active', 'remote_pubkey', 'remote_alias', 'channel_point', 'chan_id', 'capacity', 'local_balance', 'remote_balance', 'commit_fee', 'commit_weight',
'fee_per_kw', 'unsettled_balance', 'total_satoshis_sent', 'total_satoshis_received', 'num_updates', 'pending_htlcs', 'csv_delay', 'private'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const reorderedChannel = [
[{key: 'remote_alias', value: selChannel.remote_alias, title: 'Peer Alias', width: 40},
{key: 'active', value: selChannel.active, title: 'Active', width: 30, type: DataTypeEnum.BOOLEAN},
{key: 'private', value: selChannel.private, title: 'Private', width: 30, type: DataTypeEnum.BOOLEAN}],
[{key: 'remote_pubkey', value: selChannel.remote_pubkey, title: 'Peer Public Key', width: 100}],
[{key: 'channel_point', value: selChannel.channel_point, title: 'Channel Point', width: 100}],
[{key: 'chan_id', value: selChannel.chan_id, title: 'Channel ID', width: 50},
{key: 'capacity', value: selChannel.capacity, title: 'Capacity', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'local_balance', value: selChannel.local_balance, title: 'Local Balance', width: 50, type: DataTypeEnum.NUMBER},
{key: 'remote_balance', value: selChannel.remote_balance, title: 'Remote Balance', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'commit_fee', value: selChannel.commit_fee, title: 'Commit Fee', width: 50, type: DataTypeEnum.NUMBER},
{key: 'commit_weight', value: selChannel.commit_weight, title: 'Commit Weight', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'fee_per_kw', value: selChannel.fee_per_kw, title: 'Fee/KW', width: 50, type: DataTypeEnum.NUMBER},
{key: 'unsettled_balance', value: selChannel.unsettled_balance, title: 'Unsettled Balance', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'total_satoshis_sent', value: selChannel.total_satoshis_sent, title: 'Total Satoshis Sent', width: 50, type: DataTypeEnum.NUMBER},
{key: 'total_satoshis_received', value: selChannel.total_satoshis_received, title: 'Total Satoshis Received', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'num_updates', value: selChannel.num_updates, title: 'Number of Updates', width: 40, type: DataTypeEnum.NUMBER},
{key: 'pending_htlcs', value: selChannel.pending_htlcs, title: 'Pending HTLCs', width: 30, type: DataTypeEnum.NUMBER},
{key: 'csv_delay', value: selChannel.csv_delay, title: 'CSV Delay', width: 30, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'channel Information',
message: JSON.stringify(reorderedChannel)
message: reorderedChannel
}}));
}

View file

@ -7,7 +7,7 @@ import { faHistory } from '@fortawesome/free-solid-svg-icons';
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
import { ClosedChannel } from '../../../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { RTLEffects } from '../../../../../store/rtl.effects';
@ -90,12 +90,21 @@ export class ChannelClosedTableComponent implements OnInit, OnDestroy {
const selChannel = this.closedChannels.data.filter(closedChannel => {
return closedChannel.chan_id === selRow.chan_id;
})[0];
const reorderedChannel = JSON.parse(JSON.stringify(selChannel, ['close_type', 'channel_point', 'chan_id', 'closing_tx_hash', 'remote_pubkey', 'capacity',
'close_height', 'settled_balance', 'time_locked_balance'] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const reorderedChannel = [
[{key: 'close_type', value: selChannel.close_type, title: 'Close Type', width: 40, type: DataTypeEnum.STRING},
{key: 'time_locked_balance', value: selChannel.time_locked_balance, title: 'Time Locked Balance', width: 30, type: DataTypeEnum.NUMBER},
{key: 'settled_balance', value: selChannel.settled_balance, title: 'Settled Balance', width: 30, type: DataTypeEnum.NUMBER}],
[{key: 'remote_pubkey', value: selChannel.remote_pubkey, title: 'Peer Public Key', width: 100}],
[{key: 'channel_point', value: selChannel.channel_point, title: 'Channel Point', width: 100}],
[{key: 'chan_id', value: selChannel.chan_id, title: 'Channel ID', width: 40},
{key: 'capacity', value: selChannel.capacity, title: 'capacity', width: 30, type: DataTypeEnum.NUMBER},
{key: 'close_height', value: selChannel.close_height, title: 'Close Height', width: 30, type: DataTypeEnum.NUMBER}],
[{key: 'closing_tx_hash', value: selChannel.closing_tx_hash, title: 'Closing Transaction Hash', width: 100, type: DataTypeEnum.STRING}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Closed Channel Information',
message: JSON.stringify(reorderedChannel)
message: reorderedChannel
}}));
}

View file

@ -26,9 +26,17 @@
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Received ({{information?.smaller_currency_unit}}) </th>
<td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">{{channel.total_satoshis_received | number}} </span></td>
</ng-container>
<ng-container matColumnDef="local_balance">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Local Balance </th>
<td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">{{channel.local_balance | number}} </span></td>
</ng-container>
<ng-container matColumnDef="remote_balance">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Remote Balance </th>
<td mat-cell *matCellDef="let channel"><span fxLayoutAlign="end center">{{channel.remote_balance | number}} </span></td>
</ng-container>
<ng-container matColumnDef="capacity">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Capacity</th>
<td mat-cell *matCellDef="let channel">
<th mat-header-cell *matHeaderCellDef mat-sort-header class="px-3">Capacity</th>
<td mat-cell *matCellDef="let channel" class="px-3">
<div fxLayout="row">
<mat-hint fxFlex="50" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">Local: </strong>{{channel.local_balance || 0 | number}} {{information?.smaller_currency_unit}}</mat-hint>
<mat-hint fxFlex="50" fxLayoutAlign="end center" class="font-size-80"><strong class="font-weight-900">Remote: </strong>{{channel.remote_balance || 0 | number}} {{information?.smaller_currency_unit}}</mat-hint>

View file

@ -1,6 +1,6 @@
.mat-column-remote_alias {
flex: 0 0 28%;
width: 28%;
flex: 0 0 20%;
width: 20%;
& .ellipsis-parent {
display: flex;
max-width: 25rem;
@ -10,14 +10,21 @@
.mat-column-capacity {
padding-left: 3rem;
padding-right: 3rem;
flex: 0 0 40%;
width: 40%;
flex: 0 0 30%;
width: 30%;
}
.mat-column-total_satoshis_sent, .mat-column-total_satoshis_received {
.mat-column-local_balance, .mat-column-remote_balance, .mat-column-total_satoshis_sent, .mat-column-total_satoshis_received {
flex: 0 0 10%;
width: 10%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.mat-column-actions {
width: 12rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

View file

@ -5,7 +5,7 @@ import { Store } from '@ngrx/store';
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
import { Channel, GetInfo } from '../../../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { LNDEffects } from '../../../../store/lnd.effects';
@ -47,15 +47,15 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
this.displayedColumns = ['remote_alias', 'total_satoshis_sent', 'total_satoshis_received', 'actions'];
break;
case (window.innerWidth > 730 && window.innerWidth <= 1024):
this.displayedColumns = ['remote_alias', 'total_satoshis_sent', 'total_satoshis_received', 'capacity', 'actions'];
this.displayedColumns = ['remote_alias', 'total_satoshis_sent', 'total_satoshis_received', 'local_balance', 'remote_balance', 'capacity', 'actions'];
break;
case (window.innerWidth > 1024 && window.innerWidth <= 1280):
this.flgSticky = true;
this.displayedColumns = ['remote_alias', 'total_satoshis_sent', 'total_satoshis_received', 'capacity', 'actions'];
this.displayedColumns = ['remote_alias', 'total_satoshis_sent', 'total_satoshis_received', 'local_balance', 'remote_balance', 'capacity', 'actions'];
break;
default:
this.flgSticky = true;
this.displayedColumns = ['remote_alias', 'total_satoshis_sent', 'total_satoshis_received', 'capacity', 'actions'];
this.displayedColumns = ['remote_alias', 'total_satoshis_sent', 'total_satoshis_received', 'local_balance', 'remote_balance', 'capacity', 'actions'];
break;
}
}
@ -85,12 +85,19 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
onChannelUpdate(channelToUpdate: any) {
if (channelToUpdate === 'all') {
const titleMsg = 'Updated Values for ALL Channels';
const confirmationMsg = {};
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Channel Update', titleMessage: titleMsg, noBtnText: 'Cancel', yesBtnText: 'Update', message: JSON.stringify(confirmationMsg), flgShowInput: true, getInputs: [
{placeholder: 'Base Fee msat', inputType: 'number', inputValue: 1000},
{placeholder: 'Fee Rate mili msat', inputType: 'number', inputValue: 1, min: 1},
{placeholder: 'Time Lock Delta', inputType: 'number', inputValue: 144}
const confirmationMsg = [];
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '55%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Update Channel',
titleMessage: titleMsg,
noBtnText: 'Cancel',
yesBtnText: 'Update All Channels',
message: confirmationMsg,
flgShowInput: true,
getInputs: [
{placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 1000},
{placeholder: 'Fee Rate (mili mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 1, min: 1},
{placeholder: 'Time Lock Delta', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: 144}
]
}}));
this.rtlEffects.closeConfirm
@ -121,13 +128,20 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
}
this.logger.info(this.myChanPolicy);
this.store.dispatch(new RTLActions.CloseSpinner());
const titleMsg = 'Updated Values for Channel Point: ' + channelToUpdate.channel_point;
const confirmationMsg = {};
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Channel Update', titleMessage: titleMsg, noBtnText: 'Cancel', yesBtnText: 'Update', message: JSON.stringify(confirmationMsg), flgShowInput: true, getInputs: [
{placeholder: 'Base Fee msat', inputType: 'number', inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat},
{placeholder: 'Fee Rate mili msat', inputType: 'number', inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1},
{placeholder: 'Time Lock Delta', inputType: 'number', inputValue: this.myChanPolicy.time_lock_delta}
const titleMsg = 'Update values for channel point: ' + channelToUpdate.channel_point;
const confirmationMsg = [];
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '55%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Update Channel',
titleMessage: titleMsg,
noBtnText: 'Cancel',
yesBtnText: 'Update Channel',
message: confirmationMsg,
flgShowInput: true,
getInputs: [
{placeholder: 'Base Fee (mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: (this.myChanPolicy.fee_base_msat === '') ? 0 : this.myChanPolicy.fee_base_msat},
{placeholder: 'Fee Rate (mili mSat)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: this.myChanPolicy.fee_rate_milli_msat, min: 1},
{placeholder: 'Time Lock Delta', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: this.myChanPolicy.time_lock_delta}
]
}}));
});
@ -147,8 +161,12 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
}
onChannelClose(channelToClose: Channel) {
this.store.dispatch(new RTLActions.OpenConfirmation({
width: '70%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Channel Closing', titleMessage: 'Closing channel: ' + channelToClose.chan_id, noBtnText: 'Cancel', yesBtnText: 'Close Channel'
this.store.dispatch(new RTLActions.OpenConfirmation({width: '55%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Close Channel',
titleMessage: 'Closing channel: ' + channelToClose.channel_point,
noBtnText: 'Cancel',
yesBtnText: 'Close Channel'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[4]))
@ -171,14 +189,30 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
const selChannel = this.channels.data.filter(channel => {
return channel.chan_id === selRow.chan_id;
})[0];
const reorderedChannel = JSON.parse(JSON.stringify(selChannel, [
'active', 'remote_pubkey', 'remote_alias', 'channel_point', 'chan_id', 'capacity', 'local_balance', 'remote_balance', 'commit_fee', 'commit_weight',
'fee_per_kw', 'unsettled_balance', 'total_satoshis_sent', 'total_satoshis_received', 'num_updates', 'pending_htlcs', 'csv_delay', 'private'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const reorderedChannel = [
[{key: 'remote_alias', value: selChannel.remote_alias, title: 'Peer Alias', width: 40},
{key: 'active', value: selChannel.active, title: 'Active', width: 30, type: DataTypeEnum.BOOLEAN},
{key: 'private', value: selChannel.private, title: 'Private', width: 30, type: DataTypeEnum.BOOLEAN}],
[{key: 'remote_pubkey', value: selChannel.remote_pubkey, title: 'Peer Public Key', width: 100}],
[{key: 'channel_point', value: selChannel.channel_point, title: 'Channel Point', width: 100}],
[{key: 'chan_id', value: selChannel.chan_id, title: 'Channel ID', width: 50},
{key: 'capacity', value: selChannel.capacity, title: 'Capacity', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'local_balance', value: selChannel.local_balance, title: 'Local Balance', width: 50, type: DataTypeEnum.NUMBER},
{key: 'remote_balance', value: selChannel.remote_balance, title: 'Remote Balance', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'commit_fee', value: selChannel.commit_fee, title: 'Commit Fee', width: 50, type: DataTypeEnum.NUMBER},
{key: 'commit_weight', value: selChannel.commit_weight, title: 'Commit Weight', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'fee_per_kw', value: selChannel.fee_per_kw, title: 'Fee/KW', width: 50, type: DataTypeEnum.NUMBER},
{key: 'unsettled_balance', value: selChannel.unsettled_balance, title: 'Unsettled Balance', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'total_satoshis_sent', value: selChannel.total_satoshis_sent, title: 'Total Satoshis Sent', width: 50, type: DataTypeEnum.NUMBER},
{key: 'total_satoshis_received', value: selChannel.total_satoshis_received, title: 'Total Satoshis Received', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'num_updates', value: selChannel.num_updates, title: 'Number of Updates', width: 40, type: DataTypeEnum.NUMBER},
{key: 'pending_htlcs', value: selChannel.pending_htlcs, title: 'Pending HTLCs', width: 30, type: DataTypeEnum.NUMBER},
{key: 'csv_delay', value: selChannel.csv_delay, title: 'CSV Delay', width: 30, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Channel Information',
message: JSON.stringify(reorderedChannel)
message: reorderedChannel
}}));
}

View file

@ -11,7 +11,7 @@ import { LoggerService } from '../../../../../shared/services/logger.service';
import { RTLEffects } from '../../../../../store/rtl.effects';
import * as RTLActions from '../../../../../store/rtl.actions';
import * as fromRTLReducer from '../../../../../store/rtl.reducers';
import { AlertTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../../../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-channel-pending-table',
@ -115,12 +115,23 @@ export class ChannelPendingTableComponent implements OnInit, OnDestroy {
})[0];
const fcChannelObj1 = JSON.parse(JSON.stringify(selChannel, ['commit_weight', 'confirmation_height', 'fee_per_kw', 'commit_fee'], 2));
const fcChannelObj2 = JSON.parse(JSON.stringify(selChannel.channel, ['channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity'], 2));
const reorderedChannel = {};
Object.assign(reorderedChannel, fcChannelObj1, fcChannelObj2);
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const preOrderedChannel: any = {};
Object.assign(preOrderedChannel, fcChannelObj1, fcChannelObj2);
const reorderedChannel = [
[{key: 'channel_point', value: preOrderedChannel.channel_point, title: 'Channel Point', width: 100, type: DataTypeEnum.STRING}],
[{key: 'remote_node_pub', value: preOrderedChannel.remote_node_pub, title: 'Peer Node Pubkey', width: 100, type: DataTypeEnum.STRING}],
[{key: 'remote_balance', value: preOrderedChannel.remote_balance, title: 'Remote Balance', width: 50, type: DataTypeEnum.NUMBER},
{key: 'local_balance', value: preOrderedChannel.local_balance, title: 'Local Balance', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'capacity', value: preOrderedChannel.capacity, title: 'Capacity', width: 50, type: DataTypeEnum.NUMBER},
{key: 'confirmation_height', value: preOrderedChannel.confirmation_height, title: 'Confirmation Height', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'fee_per_kw', value: preOrderedChannel.fee_per_kw, title: 'Fee/KW', width: 40, type: DataTypeEnum.NUMBER},
{key: 'commit_weight', value: preOrderedChannel.commit_weight, title: 'Commit Weight', width: 30, type: DataTypeEnum.NUMBER},
{key: 'commit_fee', value: preOrderedChannel.commit_fee, title: 'Commit Fee', width: 30, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Opening Channel Information',
message: JSON.stringify(reorderedChannel)
message: reorderedChannel
}}));
}
@ -130,12 +141,24 @@ export class ChannelPendingTableComponent implements OnInit, OnDestroy {
})[0];
const fcChannelObj1 = JSON.parse(JSON.stringify(selChannel, ['closing_txid', 'limbo_balance', 'maturity_height', 'blocks_til_maturity', 'recovered_balance'], 2));
const fcChannelObj2 = JSON.parse(JSON.stringify(selChannel.channel, ['channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity'], 2));
const reorderedChannel = {};
Object.assign(reorderedChannel, fcChannelObj1, fcChannelObj2);
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const preOrderedChannel: any = {};
Object.assign(preOrderedChannel, fcChannelObj1, fcChannelObj2);
const reorderedChannel = [
[{key: 'channel_point', value: preOrderedChannel.channel_point, title: 'Channel Point', width: 100, type: DataTypeEnum.STRING}],
[{key: 'remote_node_pub', value: preOrderedChannel.remote_node_pub, title: 'Peer Node Pubkey', width: 100, type: DataTypeEnum.STRING}],
[{key: 'remote_balance', value: preOrderedChannel.remote_balance, title: 'Remote Balance', width: 50, type: DataTypeEnum.NUMBER},
{key: 'local_balance', value: preOrderedChannel.local_balance, title: 'Local Balance', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'capacity', value: preOrderedChannel.capacity, title: 'Capacity', width: 50, type: DataTypeEnum.NUMBER},
{key: 'limbo_balance', value: preOrderedChannel.limbo_balance, title: 'Limbo Balance', width: 100, type: DataTypeEnum.NUMBER}],
[{key: 'closing_txid', value: preOrderedChannel.closing_txid, title: 'Closing Transaction ID', width: 100, type: DataTypeEnum.STRING}],
[{key: 'maturity_height', value: preOrderedChannel.maturity_height, title: 'Maturity Height', width: 40, type: DataTypeEnum.NUMBER},
{key: 'blocks_til_maturity', value: preOrderedChannel.blocks_til_maturity, title: 'Blocks Till Maturity', width: 30, type: DataTypeEnum.NUMBER},
{key: 'recovered_balance', value: preOrderedChannel.recovered_balance, title: 'Recovered Balance', width: 30, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Force Closing Channel Information',
message: JSON.stringify(reorderedChannel)
message: reorderedChannel
}}));
}
@ -145,12 +168,20 @@ export class ChannelPendingTableComponent implements OnInit, OnDestroy {
})[0];
const fcChannelObj1 = JSON.parse(JSON.stringify(selChannel, ['closing_txid'], 2));
const fcChannelObj2 = JSON.parse(JSON.stringify(selChannel.channel, ['channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity'], 2));
const reorderedChannel = {};
Object.assign(reorderedChannel, fcChannelObj1, fcChannelObj2);
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const preOrderedChannel: any = {};
Object.assign(preOrderedChannel, fcChannelObj1, fcChannelObj2);
const reorderedChannel = [
[{key: 'channel_point', value: preOrderedChannel.channel_point, title: 'Channel Point', width: 100, type: DataTypeEnum.STRING}],
[{key: 'remote_node_pub', value: preOrderedChannel.remote_node_pub, title: 'Peer Node Pubkey', width: 100, type: DataTypeEnum.STRING}],
[{key: 'remote_balance', value: preOrderedChannel.remote_balance, title: 'Remote Balance', width: 50, type: DataTypeEnum.NUMBER},
{key: 'local_balance', value: preOrderedChannel.local_balance, title: 'Local Balance', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'capacity', value: preOrderedChannel.capacity, title: 'Capacity', width: 50, type: DataTypeEnum.NUMBER},
{key: 'closing_txid', value: preOrderedChannel.closing_txid, title: 'Closing Transaction ID', width: 50, type: DataTypeEnum.STRING}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Closing Channel Information',
message: JSON.stringify(reorderedChannel)
message: reorderedChannel
}}));
}
@ -160,12 +191,20 @@ export class ChannelPendingTableComponent implements OnInit, OnDestroy {
})[0];
const fcChannelObj1 = JSON.parse(JSON.stringify(selChannel, ['limbo_balance'], 2));
const fcChannelObj2 = JSON.parse(JSON.stringify(selChannel.channel, ['channel_point', 'remote_balance', 'local_balance', 'remote_node_pub', 'capacity'], 2));
const reorderedChannel = {};
Object.assign(reorderedChannel, fcChannelObj1, fcChannelObj2);
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const preOrderedChannel: any = {};
Object.assign(preOrderedChannel, fcChannelObj1, fcChannelObj2);
const reorderedChannel = [
[{key: 'channel_point', value: preOrderedChannel.channel_point, title: 'Channel Point', width: 100, type: DataTypeEnum.STRING}],
[{key: 'remote_node_pub', value: preOrderedChannel.remote_node_pub, title: 'Peer Node Pubkey', width: 100, type: DataTypeEnum.STRING}],
[{key: 'remote_balance', value: preOrderedChannel.remote_balance, title: 'Remote Balance', width: 50, type: DataTypeEnum.NUMBER},
{key: 'local_balance', value: preOrderedChannel.local_balance, title: 'Local Balance', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'capacity', value: preOrderedChannel.capacity, title: 'Capacity', width: 50, type: DataTypeEnum.NUMBER},
{key: 'limbo_balance', value: preOrderedChannel.limbo_balance, title: 'Limbo Balance', width: 50, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Wait Closing Channel Information',
message: JSON.stringify(reorderedChannel)
message: reorderedChannel
}}));
}

View file

@ -6,7 +6,7 @@ import { Store } from '@ngrx/store';
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
import { SelNodeChild } from '../../../../../shared/models/RTLconfig';
import { Channel } from '../../../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum } from '../../../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../../../shared/services/logger.service';
import { LNDEffects } from '../../../../store/lnd.effects';
@ -69,25 +69,6 @@ export class ChannelRestoreTableComponent implements OnInit {
this.channels.filter = selFilter;
}
onChannelClick(selRow: Channel, event: any) {
const flgButtonsClicked = event.target.className.includes('mat-icon')
|| event.target.className.includes('mat-column-backup')
|| event.target.className.includes('mat-column-verify');
if (flgButtonsClicked) { return; }
const selChannel = this.channels.data.filter(channel => {
return channel.chan_id === selRow.chan_id;
})[0];
const reorderedChannel = JSON.parse(JSON.stringify(selChannel, [
'active', 'remote_pubkey', 'remote_alias', 'channel_point', 'chan_id', 'capacity', 'local_balance', 'remote_balance', 'commit_fee', 'commit_weight',
'fee_per_kw', 'unsettled_balance', 'total_satoshis_sent', 'total_satoshis_received', 'num_updates', 'pending_htlcs', 'csv_delay', 'private'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Restored Channel Information',
message: JSON.stringify(reorderedChannel)
}}));
}
ngOnDestroy() {
this.unSubs.forEach(completeSub => {
completeSub.next();

View file

@ -9,7 +9,7 @@ import { faUsers } from '@fortawesome/free-solid-svg-icons';
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
import { Peer, GetInfo } from '../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum } from '../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../shared/services/logger.service';
import { OpenChannelComponent } from '../../../shared/components/data-modal/open-channel/open-channel.component';
import { newlyAddedRowAnimation } from '../../../shared/animation/row-animation';
@ -137,10 +137,20 @@ export class PeersComponent implements OnInit, OnDestroy {
const selPeer = this.peers.data.filter(peer => {
return peer.pub_key === selRow.pub_key;
})[0];
const reorderedPeer = JSON.parse(JSON.stringify(selPeer, [
'alias', 'pub_key', 'address', 'bytes_sent', 'bytes_recv', 'sat_sent', 'sat_recv', 'inbound', 'ping_time'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Peer Information', message: JSON.stringify(reorderedPeer)}}));
const reorderedPeer = [
[{key: 'pub_key', value: selPeer.pub_key, title: 'Public Key', width: 100}],
[{key: 'address', value: selPeer.address, title: 'Address', width: 100}],
[{key: 'alias', value: selPeer.alias, title: 'Alias', width: 40}, {key: 'inbound', value: selPeer.inbound ? 'True' : 'False', title: 'Inbound', width: 30}, {key: 'ping_time', value: selPeer.ping_time, title: 'Ping Time', width: 30, type: DataTypeEnum.NUMBER}],
[{key: 'sat_sent', value: selPeer.sat_sent, title: 'Satoshis Sent', width: 50, type: DataTypeEnum.NUMBER}, {key: 'sat_recv', value: selPeer.sat_recv, title: 'Satoshis Received', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'bytes_sent', value: selPeer.bytes_sent, title: 'Bytes Sent', width: 50, type: DataTypeEnum.NUMBER}, {key: 'bytes_recv', value: selPeer.bytes_recv, title: 'Bytes Received', width: 50, type: DataTypeEnum.NUMBER}],
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Peer Information',
showQRName: 'Public Key',
showQRField: selPeer.pub_key,
message: reorderedPeer
}}));
}
resetData() {
@ -148,17 +158,33 @@ export class PeersComponent implements OnInit, OnDestroy {
}
onOpenChannel(peerToAddChannel: Peer) {
this.store.dispatch(new RTLActions.OpenAlert({ width: '50%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Open Channel', message: JSON.stringify({peer: peerToAddChannel, information: this.information, balance: this.availableBalance}), newlyAdded: false, component: OpenChannelComponent}}));
const peerToAddChannelMessage = {
peer: peerToAddChannel,
information: this.information,
balance: this.availableBalance
};
this.store.dispatch(new RTLActions.OpenAlert({ width: '50%', data: {
alertTitle: 'Open Channel',
message: peerToAddChannelMessage,
newlyAdded: false,
component: OpenChannelComponent
}}));
}
onPeerDetach(peerToDetach: Peer) {
const msg = 'Disconnect peer: ' + peerToDetach.pub_key;
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Peer Disconnect', titleMessage: msg, noBtnText: 'Cancel', yesBtnText: 'Detach'}}));
const msg = 'Disconnect peer: ' + ((peerToDetach.alias) ? peerToDetach.alias : peerToDetach.pub_key);
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '55%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Disconnect Peer',
titleMessage: msg,
noBtnText: 'Cancel',
yesBtnText: 'Disconnect'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[3]))
.subscribe(confirmRes => {
if (confirmRes) {
this.store.dispatch(new RTLActions.OpenSpinner('Detaching Peer...'));
this.store.dispatch(new RTLActions.OpenSpinner('Disconnecting Peer...'));
this.store.dispatch(new RTLActions.DetachPeer({pubkey: peerToDetach.pub_key}));
}
});

View file

@ -11,7 +11,7 @@ import { CommonService } from '../../shared/services/common.service';
import * as RTLActions from '../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-routing-peers',
@ -86,7 +86,7 @@ export class RoutingPeersComponent implements OnInit, OnDestroy {
}
onRoutingPeerClick(selRow: RoutingPeers, event: any, direction: string) {
let selRPeer = {};
let selRPeer: RoutingPeers = {};
if (direction === 'in') {
selRPeer = this.RoutingPeersIncoming.data.find(rPeer => {
return rPeer.chan_id === selRow.chan_id;
@ -96,11 +96,14 @@ export class RoutingPeersComponent implements OnInit, OnDestroy {
return rPeer.chan_id === selRow.chan_id;
});
}
const reorderedRoutingPeer = JSON.parse(JSON.stringify(selRPeer, ['chan_id', 'alias', 'events', 'total_amount'] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const reorderedRoutingPeer = [
[{key: 'chan_id', value: selRPeer.chan_id, title: 'Channel ID', width: 100, type: DataTypeEnum.STRING}]
// 'chan_id', 'alias', 'events', 'total_amount'
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Route Information',
message: JSON.stringify(reorderedRoutingPeer)
message: reorderedRoutingPeer
}}));
}

View file

@ -20,6 +20,7 @@ import { CurrencyUnitEnum, AlertTypeEnum } from '../../shared/services/consts-en
import * as RTLActions from '../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers';
import * as fromLNDReducers from '../store/lnd.reducers';
import { ErrorMessageComponent } from '../../shared/components/data-modal/error-message/error-message.component';
@Injectable()
export class LNDEffects implements OnDestroy {
@ -129,10 +130,20 @@ export class LNDEffects implements OnDestroy {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.SetPeers((postRes && postRes.length > 0) ? postRes : []));
const peerToAddChannelMessage = {
peer: postRes[0],
information: lndData.information,
balance: lndData.blockchainBalance.total_balance || 0
};
return {
type: RTLActions.OPEN_ALERT,
payload: { width: '50%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Peer Connected', message: JSON.stringify({peer: postRes[0], information: lndData.information, balance: lndData.blockchainBalance.total_balance || 0}), newlyAdded: true}},
component: OpenChannelComponent
payload: { width: '50%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Peer Connected',
message: peerToAddChannelMessage,
newlyAdded: true,
component: OpenChannelComponent
}}
};
}),
catchError((err: any) => {
@ -152,7 +163,11 @@ export class LNDEffects implements OnDestroy {
map((postRes: any) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Peer Disconnected', titleMessage: 'Peer Disconnected Successfully!' }}));
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.SUCCESS,
alertTitle: 'Peer Disconnected',
titleMessage: 'Peer Disconnected Successfully!'
}}));
return {
type: RTLActions.REMOVE_PEER,
payload: { pubkey: action.payload.pubkey }
@ -184,8 +199,10 @@ export class LNDEffects implements OnDestroy {
postRes.creation_date_str = new Date(+postRes.creation_date * 1000).toUTCString().substring(5, 22).replace(' ', '/').replace(' ', '/').toUpperCase();
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({
width: '58%', data: { type: AlertTypeEnum.INFORMATION, alertTitle: 'Invoice Created', message: JSON.stringify(postRes), newlyAdded: true, component: InvoiceInformationComponent
this.store.dispatch(new RTLActions.OpenAlert({ width: '58%', data: {
invoice: postRes,
newlyAdded: true,
component: InvoiceInformationComponent
}}));
return {
type: RTLActions.FETCH_INVOICES,
@ -238,7 +255,7 @@ export class LNDEffects implements OnDestroy {
map((postRes: any) => {
this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Channel Updated', titleMessage: 'Channel Updated Successfully!' }}));
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Channel Updated', titleMessage: 'Channel Updated Successfully!' }}));
return {
type: RTLActions.FETCH_CHANNELS,
payload: { routeParam: 'all', channelStatus: '' }
@ -591,29 +608,23 @@ export class LNDEffects implements OnDestroy {
this.store.dispatch(new RTLActions.CloseSpinner());
if (sendRes.payment_error) {
this.logger.error('Error: ' + sendRes.payment_error);
return {
type: RTLActions.OPEN_ALERT,
payload: {config : {
width: '70%', data: {
type: 'ERROR', titleMessage: 'Send Payment Failed',
message: JSON.stringify(
{ code: sendRes.payment_error.status, Message: sendRes.payment_error.error.message, URL: this.CHILD_API_URL + environment.CHANNELS_API + '/transactions/' + action.payload[0] }
)
}
}}
};
const myErr = {status: sendRes.payment_error.status, error: sendRes.payment_error.error.message};
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.CHANNELS_API + '/transactions/' + action.payload[0], myErr);
return of({type: RTLActions.VOID});
} else {
const confirmationMsg = { 'Destination': action.payload[1].destination, 'Timestamp': action.payload[1].timestamp_str, 'Expiry': action.payload[1].expiry };
confirmationMsg['Amount (' + ((undefined === store.nodeData.smaller_currency_unit) ?
CurrencyUnitEnum.SATS : store.nodeData.smaller_currency_unit) + ')'] = action.payload[1].num_satoshis;
const msg = {};
const msg = [];
msg['Total Fee (' + ((undefined === store.nodeData.smaller_currency_unit) ? CurrencyUnitEnum.SATS : store.nodeData.smaller_currency_unit) + ')'] =
(sendRes.payment_route.total_fees_msat / 1000);
Object.assign(msg, confirmationMsg);
this.store.dispatch(new RTLActions.OpenAlert({
width: '70%',
data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Payment Sent', titleMessage: 'Payment Sent Successfully!', message: JSON.stringify(msg) }
}));
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.SUCCESS,
alertTitle: 'Payment Sent',
titleMessage: 'Payment Sent Successfully!',
message: msg
}}));
this.store.dispatch(new RTLActions.FetchChannels({ routeParam: 'all' }));
this.store.dispatch(new RTLActions.FetchBalance('channels'));
this.store.dispatch(new RTLActions.FetchPayments());
@ -624,7 +635,8 @@ export class LNDEffects implements OnDestroy {
}
}),
catchError((err: any) => {
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.CHANNELS_API + '/transactions', err);
const myErr = {status: err.status, error: typeof(err.error.error) === 'object' ? err.error.error : {error: err.error.error}};
this.handleErrorWithAlert('ERROR', 'Send Payment Failed', this.CHILD_API_URL + environment.CHANNELS_API + '/transactions', myErr);
return of({type: RTLActions.VOID});
})
);
@ -1066,9 +1078,11 @@ export class LNDEffects implements OnDestroy {
} else {
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({
width: '70%', data: {
type: alertType, alertTitle: alertType, titleMessage: alertTitle,
message: JSON.stringify({ code: err.status, Message: err.error.error, URL: errURL })
width: '55%', data: {
type: alertType,
alertTitle: alertTitle,
message: { code: err.status, message: err.error.error, URL: errURL },
component: ErrorMessageComponent
}
}));
}

View file

@ -10,7 +10,7 @@ import { LoggerService } from '../../shared/services/logger.service';
import * as RTLActions from '../../store/rtl.actions';
import * as fromRTLReducer from '../../store/rtl.reducers';
import { AlertTypeEnum } from '../../shared/services/consts-enums-functions';
import { AlertTypeEnum, DataTypeEnum } from '../../shared/services/consts-enums-functions';
@Component({
selector: 'rtl-forwarding-history',
@ -82,11 +82,14 @@ export class ForwardingHistoryComponent implements OnInit, OnDestroy {
const selFEvent = this.forwardingHistoryEvents.data.filter(fhEvent => {
return (fhEvent.chan_id_in === selRow.chan_id_in && fhEvent.timestamp === selRow.timestamp);
})[0];
const reorderedFHEvent = JSON.parse(JSON.stringify(selFEvent, ['timestamp_str', 'chan_id_in', 'alias_in', 'chan_id_out', 'alias_out', 'amt_out', 'amt_in', 'fee'] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const reorderedFHEvent = [
[{key: 'alias', value: selFEvent.alias, title: 'Alias', width: 100, type: DataTypeEnum.STRING}]
// 'timestamp_str', 'chan_id_in', 'alias_in', 'chan_id_out', 'alias_out', 'amt_out', 'amt_in', 'fee'
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Event Information',
message: JSON.stringify(reorderedFHEvent)
message: reorderedFHEvent
}}));
}

View file

@ -6,7 +6,7 @@ import { Store } from '@ngrx/store';
import { faHistory } from '@fortawesome/free-solid-svg-icons';
import { MatTableDataSource, MatSort, MatPaginatorIntl } from '@angular/material';
import { TimeUnitEnum, CurrencyUnitEnum, TIME_UNITS, CURRENCY_UNIT_FORMATS, PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum } from '../../../shared/services/consts-enums-functions';
import { TimeUnitEnum, CurrencyUnitEnum, TIME_UNITS, CURRENCY_UNIT_FORMATS, PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum } from '../../../shared/services/consts-enums-functions';
import { SelNodeChild } from '../../../shared/models/RTLconfig';
import { GetInfo, Invoice } from '../../../shared/models/lndModels';
import { LoggerService } from '../../../shared/services/logger.service';
@ -119,16 +119,9 @@ export class LightningInvoicesComponent implements OnInit, OnDestroy {
const selInvoice = this.invoices.data.filter(invoice => {
return invoice.payment_request === selRow.payment_request;
})[0];
const reorderedInvoice = JSON.parse(JSON.stringify(selInvoice, [
'settled', 'creation_date_str', 'settle_date_str', 'memo', 'receipt', 'r_preimage', 'r_hash', 'value', 'payment_request',
'description_hash', 'expiry', 'fallback_addr', 'cltv_expiry', 'route_hints', 'private', 'add_index', 'settle_index',
'amt_paid', 'amt_paid_sat', 'amt_paid_msat'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '58%',
data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Invoice Information',
message: JSON.stringify(reorderedInvoice),
invoice: selInvoice,
newlyAdded: false,
component: InvoiceInformationComponent
}}));

View file

@ -56,7 +56,7 @@
</ng-container>
<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-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.payment_hash === newlyAddedPayment && flgAnimate) ? 'added' : 'notAdded'"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;" [@newlyAddedRowAnimation]="(row.payment_hash === newlyAddedPayment && flgAnimate) ? 'added' : 'notAdded'"></tr>
</table>
</div>
<mat-paginator [pageSize]="pageSize" [pageSizeOptions]="pageSizeOptions" showFirstLastButtons class="mb-4"></mat-paginator>

View file

@ -6,7 +6,7 @@ import { faHistory } from '@fortawesome/free-solid-svg-icons';
import { MatTableDataSource, MatSort, MatPaginator, MatPaginatorIntl } from '@angular/material';
import { GetInfo, Payment, PayRequest } from '../../../shared/models/lndModels';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum } from '../../../shared/services/consts-enums-functions';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, getPaginatorLabel, AlertTypeEnum, DataTypeEnum } from '../../../shared/services/consts-enums-functions';
import { LoggerService } from '../../../shared/services/logger.service';
import { newlyAddedRowAnimation } from '../../../shared/animation/row-animation';
@ -116,10 +116,25 @@ export class LightningPaymentsComponent implements OnInit, OnDestroy {
this.flgAnimate = true;
this.newlyAddedPayment = this.paymentDecoded.payment_hash;
if (undefined === this.paymentDecoded.num_satoshis || this.paymentDecoded.num_satoshis === '' || this.paymentDecoded.num_satoshis === '0') {
const reorderedPaymentDecoded = [
[{key: 'payment_hash', value: this.paymentDecoded.payment_hash, title: 'Payment Hash', width: 100}],
[{key: 'destination', value: this.paymentDecoded.destination, title: 'Destination', width: 100}],
[{key: 'description', value: this.paymentDecoded.description, title: 'Description', width: 100}],
[{key: 'timestamp_str', value: this.paymentDecoded.timestamp_str, title: 'Creation Date', width: 40},
{key: 'expiry', value: this.paymentDecoded.expiry, title: 'Expiry', width: 30, type: DataTypeEnum.NUMBER},
{key: 'cltv_expiry', value: this.paymentDecoded.cltv_expiry, title: 'CLTV Expiry', width: 30}]
];
const titleMsg = 'It is an open amount invoice. Enter the amount (Sats) to pay.';
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Enter Amount and Confirm Send Payment', titleMessage: titleMsg, message: JSON.stringify(this.paymentDecoded), noBtnText: 'Cancel', yesBtnText: 'Send', flgShowInput: true, getInputs: [
{placeholder: 'Amount (Sats)', inputType: 'number', inputValue: ''}
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '55%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Enter Amount and Confirm Send Payment',
titleMessage: titleMsg,
message: reorderedPaymentDecoded,
noBtnText: 'Cancel',
yesBtnText: 'Send Payment',
flgShowInput: true,
getInputs: [
{placeholder: 'Amount (Sats)', inputType: DataTypeEnum.NUMBER.toLowerCase(), inputValue: ''}
]
}}));
this.rtlEffects.closeConfirm
@ -133,8 +148,21 @@ export class LightningPaymentsComponent implements OnInit, OnDestroy {
}
});
} else {
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '70%', data: {
type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Send Payment', titleMessage: 'Send Payment', noBtnText: 'Cancel', yesBtnText: 'Send', message: JSON.stringify(this.paymentDecoded)
const reorderedPaymentDecoded = [
[{key: 'payment_hash', value: this.paymentDecoded.payment_hash, title: 'Payment Hash', width: 100}],
[{key: 'destination', value: this.paymentDecoded.destination, title: 'Destination', width: 100}],
[{key: 'description', value: this.paymentDecoded.description, title: 'Description', width: 100}],
[{key: 'timestamp_str', value: this.paymentDecoded.timestamp_str, title: 'Creation Date', width: 50},
{key: 'num_satoshis', value: this.paymentDecoded.num_satoshis, title: 'Amount (Sats)', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'expiry', value: this.paymentDecoded.expiry, title: 'Expiry', width: 50, type: DataTypeEnum.NUMBER},
{key: 'cltv_expiry', value: this.paymentDecoded.cltv_expiry, title: 'CLTV Expiry', width: 50}]
];
this.store.dispatch(new RTLActions.OpenConfirmation({ width: '55%', data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Send Payment',
noBtnText: 'Cancel',
yesBtnText: 'Send',
message: reorderedPaymentDecoded
}}));
this.rtlEffects.closeConfirm
.pipe(take(1))
@ -170,13 +198,20 @@ export class LightningPaymentsComponent implements OnInit, OnDestroy {
const selPayment = this.payments.data.filter(payment => {
return payment.payment_hash === selRow.payment_hash;
})[0];
const reorderedPayment = JSON.parse(JSON.stringify(selPayment, [
'creation_date_str', 'payment_hash', 'fee', 'value_msat', 'value_sat', 'value', 'payment_preimage', 'path'
] , 2));
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
const reorderedPayment = [
[{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: 'path', value: selPayment.path, title: 'Path', width: 100, type: DataTypeEnum.ARRAY}],
[{key: 'creation_date_str', value: selPayment.creation_date_str, title: 'Creation Date', width: 50, type: DataTypeEnum.DATE_TIME},
{key: 'fee', value: selPayment.fee, title: 'Fee', width: 50, type: DataTypeEnum.NUMBER}],
[{key: 'value_msat', value: selPayment.value_msat, title: 'Value (mSats)', width: 50, type: DataTypeEnum.NUMBER},
{key: 'value_sat', value: selPayment.value, title: 'Value (Sats)', width: 50, type: DataTypeEnum.NUMBER}]
];
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: 'Payment Information',
message: JSON.stringify(reorderedPayment)
message: reorderedPayment
}}));
}

View file

@ -118,7 +118,7 @@ export class AppSettingsComponent implements OnInit, OnDestroy {
let defaultNodeIndex = (this.previousDefaultNode !== this.appConfig.defaultNodeIndex) ? this.appConfig.defaultNodeIndex : null;
this.logger.info(this.selNode.settings);
if (!updatedSettings && !defaultNodeIndex) {
this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
this.store.dispatch(new RTLActions.OpenAlert({ width: '55%', data: {
type: AlertTypeEnum.WARNING,
alertTitle: 'Configuration Not Updated',
titleMessage: 'Nothing has been updated to save!'

View file

@ -1,30 +1,42 @@
<div fxLayout="row">
<div fxFlex="100" class="padding-gap-large">
<div *ngIf="showQRField !== ''" fxFlex="35" fxLayoutAlign="center start" class="modal-qr-code-container padding-gap-large">
<qrcode [qrdata]="showQRField" [size]="230" [level]="'L'" [allowEmptyString]="true" class="qr-border"></qrcode>
</div>
<div [fxFlex]="showQRField !== '' ? '65' : '100'" class="padding-gap-large">
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header">
<div fxFlex="95" fxLayoutAlign="start start">
<span class="page-title">{{data.alertTitle || alertTypeEnum[data.type]}}</span>
</div>
<button tabindex="8" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button>
<button tabindex="3" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button>
</mat-card-header>
<mat-card-content class="mt-5px">
<mat-card-content class="mt-5px mb-0">
<div fxLayout="column">
<p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="title-message pb-1 pl-1">{{data.titleMessage | titlecase}}</p>
<p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="pb-1">{{data.titleMessage}}</p>
<div *ngIf="messageObjs?.length>0">
<div *ngFor="let objs of messageObjs; index as i;">
<div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutAlign.gt-md="space-between start">
<div fxLayout="column" fxFlex="100" fxFlex.gt-md="{{100/messageFieldsBreakdown[i]}}" *ngFor="let obj of objs">
<h4 fxLayoutAlign="start" class="font-bold-500">{{obj[0] | titlecase}}</h4>
<span fxFlex="100" class="foreground-secondary-text" *ngIf="isNumber(obj[1], obj[0]);else notNumberTemplate">{{obj[1] | number:'1.0-3'}}</span>
<ng-template #notNumberTemplate>
<span fxFlex="100" class="foreground-secondary-text">{{obj[1]}}</span>
<div fxLayout="column" fxFlex="100" fxFlex.gt-md="{{obj.width}}" *ngFor="let obj of objs; index as j;">
<h4 fxLayoutAlign="start" class="font-bold-500">{{obj.title}}</h4>
<span *ngIf="obj && obj.value; else emptyField">
<span [ngSwitch]="obj.type" class="foreground-secondary-text">
<ng-container *ngSwitchCase="dataTypeEnum.ARRAY"><span *ngFor="let arrayObj of obj.value" class="display-block">{{arrayObj}}</span></ng-container>
<ng-container *ngSwitchCase="dataTypeEnum.NUMBER">{{obj.value | number:'1.0-3'}}</ng-container>
<ng-container *ngSwitchCase="dataTypeEnum.BOOLEAN">{{obj.value === true ? 'True' : 'False'}}</ng-container>
<ng-container *ngSwitchDefault>{{obj.value}}</ng-container>
</span>
</span>
<ng-template #emptyField>
<span fxFlex="100" class="foreground-secondary-text">&nbsp;</span>
</ng-template>
<mat-divider class="w-100 my-1"></mat-divider>
</div>
</div>
</div>
</div>
<div class="mt-2" fxLayout="row" fxLayoutAlign="end center">
<button fxLayoutAlign="center center" tabindex="1" autoFocus mat-raised-button color="primary" fxFlex="20" type="submit" [mat-dialog-close]="false" default>OK</button>
<div fxLayout="row" fxLayoutAlign="end center">
<button *ngIf="!showQRField || showQRField == ''" fxLayoutAlign="center center" tabindex="1" autoFocus mat-raised-button color="primary" fxFlex="20" type="submit" [mat-dialog-close]="false" default>OK</button>
<button *ngIf="showQRField !== ''" fxLayoutAlign="center center" tabindex="1" class="mr-2" mat-stroked-button color="primary" type="button" [mat-dialog-close]="false" default>OK</button>
<button *ngIf="showQRField !== ''" fxFlex="30" fxLayoutAlign="center center" autoFocus mat-raised-button color="primary" tabindex="2" type="submit" rtlClipboard [payload]="showQRField" (copied)="onCopyField($event)">Copy {{showQRName}}</button>
</div>
</div>
</mat-card-content>

View file

@ -1,40 +1,3 @@
.p-2 {
padding: 1rem;
}
.pb-1 {
padding-bottom: 0.3rem;
}
.pb-2 {
padding-bottom: 1rem;
}
.mb-1 {
margin-bottom: 0.5rem;
}
.wrap-text {
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}
.mat-icon[type="button"] {
cursor: pointer;
}
.new-line {
white-space: pre-wrap;
}
.title-message {
font-size: 110%;
}
.mt-minus-40px {
margin-top:-40px;
}
.display-block {
display: block;
}

View file

@ -1,10 +1,9 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { faCopy } from '@fortawesome/free-solid-svg-icons';
import { MatDialogRef, MAT_DIALOG_DATA, MatSnackBar } from '@angular/material';
import { LoggerService } from '../../../services/logger.service';
import { AlertData } from '../../../models/alertData';
import { AlertTypeEnum } from '../../../services/consts-enums-functions';
import { AlertData, ErrorData } from '../../../models/alertData';
import { AlertTypeEnum, DataTypeEnum } from '../../../services/consts-enums-functions';
@Component({
selector: 'rtl-alert-message',
@ -12,107 +11,32 @@ import { AlertTypeEnum } from '../../../services/consts-enums-functions';
styleUrls: ['./alert-message.component.scss']
})
export class AlertMessageComponent implements OnInit {
public msgTypeBackground = 'bg-primary p-1';
public msgTypeForeground = 'primary';
public messageObjsArr = [];
public showQRField = '';
public showQRName = '';
public errorMessage = '';
public messageObjs = [];
public messageFieldsBreakdown = [];
public flgCopied = false;
public faCopy = faCopy;
public alertTypeEnum = AlertTypeEnum;
public dataTypeEnum = DataTypeEnum;
constructor(public dialogRef: MatDialogRef<AlertMessageComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService) { }
constructor(public dialogRef: MatDialogRef<AlertMessageComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService, private snackBar: MatSnackBar) { }
ngOnInit() {
this.messageFieldsBreakdown = this.data.messageFieldsBreakdown;
this.setStyleOnAlertType();
this.convertJSONData();
}
setStyleOnAlertType() {
if (this.data.type === AlertTypeEnum.WARNING) {
this.msgTypeBackground = 'bg-primary p-1';
this.msgTypeForeground = 'primary';
}
this.messageObjs = this.data.message;
this.showQRField = this.data.showQRField ? this.data.showQRField : '';
this.showQRName = this.data.showQRName ? this.data.showQRName : '';
if (this.data.type === AlertTypeEnum.ERROR) {
this.msgTypeBackground = 'bg-warn p-1';
this.msgTypeForeground = 'warn';
if (undefined === this.data.message && undefined === this.data.titleMessage && this.messageObjsArr.length <= 0 ) {
if (undefined === this.data.message && undefined === this.data.titleMessage && this.messageObjs.length <= 0) {
this.data.titleMessage = 'Please Check Server Connection';
}
}
this.logger.info(this.messageObjs);
}
convertJSONData() {
this.data.message = (undefined === this.data.message) ? '' : this.data.message.replace(/{/g, '').replace(/"/g, '').replace(/}/g, '').replace(/\n/g, '');
// Start: For Payment Path
const arrayStartIdx = this.data.message.search('\\[');
const arrayEndIdx = this.data.message.search('\\]');
if (arrayStartIdx > -1 && arrayEndIdx > -1) {
this.data.message = this.data.message.substring(0, arrayStartIdx).concat(
this.data.message.substring(arrayStartIdx + 1, arrayEndIdx).replace(/,/g, '\n'),
this.data.message.substring(arrayEndIdx + 1));
}
// End: For Payment Path
this.messageObjsArr = (this.data.message === '') ? [] : this.data.message.split(',');
this.messageObjsArr.forEach((obj, idx) => {
this.messageObjsArr[idx] = obj.split(':');
this.messageObjsArr[idx][0] = this.messageObjsArr[idx][0].replace('_str', '');
this.messageObjsArr[idx][0] = this.messageObjsArr[idx][0].replace(/_/g, ' '); // To replace Backend Data's '_'
// Start: To Merge Time Value Again with ':', example Payment Creation Time
if (this.messageObjsArr[idx].length > 2) {
this.messageObjsArr[idx].forEach((dataValue, j) => {
if (j === 0 || j === 1) {
return;
} else {
this.messageObjsArr[idx][1] = this.messageObjsArr[idx][1] + ':' + this.messageObjsArr[idx][j];
}
});
}
// End: To Merge Time Value Again with ':', example Payment Creation Time
});
for (let i = 0; i < this.messageFieldsBreakdown.length; i++) {
this.messageObjs[i] = [];
for (let j = 0, k = i; k < (i + this.messageFieldsBreakdown[i]); j++, k++) {
this.messageObjs[i][j] = this.messageObjsArr[k];
}
}
console.warn(this.messageObjs);
}
showCopyOption(key): boolean {
let flgFoundKey = false;
const showCopyOnKeys = ['payment request', 'bolt11'];
showCopyOnKeys.filter((arrKey) => {
if (arrKey === key) {
flgFoundKey = true;
return true;
}
});
return flgFoundKey;
}
copiedText(payload) {
this.flgCopied = true;
setTimeout(() => {this.flgCopied = false; }, 5000);
onCopyField(payload: string) {
this.snackBar.open(this.showQRName + ' copied');
this.logger.info('Copied Text: ' + payload);
}
isNumber(value, key): boolean {
let flgFoundKey = false;
const notNumberKeys = ['chan id', 'creation date', 'chan id out', 'chan id in'];
notNumberKeys.filter((arrKey) => {
if (arrKey === key) {
flgFoundKey = true;
}
});
if (!flgFoundKey) {
return new RegExp(/^[0-9]+$/).test(value);
} else {
return false;
}
}
onClose() {
this.dialogRef.close(false);
}

View file

@ -8,34 +8,38 @@
</mat-card-header>
<mat-card-content class="mt-5px">
<div fxLayout="column">
<p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="title-message pb-1 pl-1">{{data.titleMessage | titlecase}}</p>
<div *ngIf="flgShowInput" fxLayoutAlign="start center">
<mat-form-field class="pl-2" *ngFor="let getInput of getInputs; index as i">
<p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="pb-1">{{data.titleMessage}}</p>
<div *ngIf="flgShowInput" fxLayoutAlign="space-between center">
<mat-form-field *ngFor="let getInput of getInputs; index as i" [fxFlex]="(getInputs.length > 0 && getInputs.length < 3) ? 25: ((100/getInputs.length) - getInputs.length)">
<input matInput [placeholder]="getInput.placeholder" name="input{{i}}" [min]="getInput.min" [type]="getInput.inputType" [(ngModel)]="getInput.inputValue" [tabindex]="i+1" required>
</mat-form-field>
</div>
<div *ngIf="messageObj?.length>0">
<div *ngFor="let obj of messageObj" fxLayout="row" fxLayoutAlign="center flex-start">
<div fxFlex="20">{{obj[0] | titlecase}}</div>
<div fxFlex="2">:</div>
<div fxFlex="75">
<div *ngIf="isNumber(obj[1], obj[0]);else notNumberTemplate">
<span>{{obj[1] | number:'1.0-3'}}</span>
</div>
<ng-template #notNumberTemplate>
<span>{{obj[1]}}</span>
</ng-template>
<fa-icon *ngIf="showCopyOption(obj[0])" rtlClipboard [payload]="obj[1]" (copied)="copiedText($event)" [icon]="faCopy"></fa-icon>
<span *ngIf="showCopyOption(obj[0])" [hidden]="!flgCopied">Copied</span>
</div>
<div *ngIf="messageObjs?.length>0">
<div *ngFor="let objs of messageObjs; index as i;">
<div fxLayout="row wrap" fxLayoutAlign="start center" fxLayoutAlign.gt-md="space-between start">
<div fxLayout="column" fxFlex="100" fxFlex.gt-md="{{obj.width}}" *ngFor="let obj of objs; index as j;">
<h4 fxLayoutAlign="start" class="font-bold-500">{{obj.title}}</h4>
<span *ngIf="obj && obj.value; else emptyField">
<span [ngSwitch]="obj.type" class="foreground-secondary-text">
<ng-container *ngSwitchCase="dataTypeEnum.ARRAY"><span *ngFor="let arrayObj of obj.value" class="display-block">{{arrayObj}}</span></ng-container>
<ng-container *ngSwitchCase="dataTypeEnum.NUMBER">{{obj.value | number:'1.0-3'}}</ng-container>
<ng-container *ngSwitchCase="dataTypeEnum.BOOLEAN">{{obj.value === true ? 'True' : 'False'}}</ng-container>
<ng-container *ngSwitchDefault>{{obj.value}}</ng-container>
</span>
</span>
<ng-template #emptyField>
<span fxFlex="100" class="foreground-secondary-text">&nbsp;</span>
</ng-template>
<mat-divider class="w-100 my-1"></mat-divider>
</div>
</div>
</div>
</div>
</div>
<mat-divider class="pb-1"></mat-divider>
<div fxLayoutAlign="center">
<button mat-stroked-button color="primary" fxFlex="20" type="button" fxLayoutAlign="center center" class="mr-2" (click)="onClose(false)" tabindex="2" default>{{noBtnText}}</button>
<button *ngIf="flgShowInput" mat-raised-button [color]="msgTypeForeground" fxLayoutAlign="center center" fxFlex="20" type="button" tabindex="3" (click)="onClose(getInputs)" [disabled]="!getInputs[0].inputValue">{{yesBtnText}}</button>
<button *ngIf="!flgShowInput" mat-raised-button [color]="msgTypeForeground" fxLayoutAlign="center center" fxFlex="20" type="button" tabindex="4" (click)="onClose(true)">{{yesBtnText}}</button>
<div fxLayout="row" fxLayoutAlign="end center">
<button autoFocus mat-stroked-button color="primary" fxFlex="20" type="button" fxLayoutAlign="center center" class="mr-2" (click)="onClose(false)" tabindex="2" default>{{noBtnText}}</button>
<button *ngIf="flgShowInput" mat-raised-button color="primary" fxLayoutAlign="center center" fxFlex="25" type="button" tabindex="3" (click)="onClose(getInputs)" [disabled]="!getInputs[0].inputValue">{{yesBtnText}}</button>
<button *ngIf="!flgShowInput" mat-raised-button color="primary" fxLayoutAlign="center center" fxFlex="25" type="button" tabindex="4" (click)="onClose(true)">{{yesBtnText}}</button>
</div>
</div>
</mat-card-content>
</div>

View file

@ -1,16 +0,0 @@
.new-line {
white-space: pre-wrap;
}
.wrap-text {
-ms-word-break: break-all;
word-break: break-all;
word-break: break-word;
-webkit-hyphens: auto;
-moz-hyphens: auto;
hyphens: auto;
}
.title-message {
font-size: 110%;
}

View file

@ -1,11 +1,10 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Store } from '@ngrx/store';
import { faCopy } from '@fortawesome/free-solid-svg-icons';
import { LoggerService } from '../../../services/logger.service';
import { AlertData, InputData } from '../../../models/alertData';
import { AlertTypeEnum } from '../../../services/consts-enums-functions';
import { InputData, ConfirmationData } from '../../../models/alertData';
import { AlertTypeEnum, DataTypeEnum } from '../../../services/consts-enums-functions';
import * as RTLActions from '../../../../store/rtl.actions';
import * as fromRTLReducer from '../../../../store/rtl.reducers';
@ -16,18 +15,15 @@ import * as fromRTLReducer from '../../../../store/rtl.reducers';
styleUrls: ['./confirmation-message.component.scss']
})
export class ConfirmationMessageComponent implements OnInit {
public msgTypeBackground = 'bg-primary p-1';
public msgTypeForeground = 'primary';
public noBtnText = 'No';
public yesBtnText = 'Yes';
public messageObj = [];
public flgCopied = false;
public messageObjs = [];
public flgShowInput = false;
public faCopy = faCopy;
public alertTypeEnum = AlertTypeEnum;
public dataTypeEnum = DataTypeEnum;
public getInputs: Array<InputData> = [{placeholder: '', inputType: 'text', inputValue: ''}];
constructor(public dialogRef: MatDialogRef<ConfirmationMessageComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService,
constructor(public dialogRef: MatDialogRef<ConfirmationMessageComponent>, @Inject(MAT_DIALOG_DATA) public data: ConfirmationData, private logger: LoggerService,
private store: Store<fromRTLReducer.RTLState>) { }
ngOnInit() {
@ -35,70 +31,13 @@ export class ConfirmationMessageComponent implements OnInit {
this.getInputs = this.data.getInputs;
this.noBtnText = (undefined !== this.data.noBtnText) ? this.data.noBtnText : 'No';
this.yesBtnText = (undefined !== this.data.yesBtnText) ? this.data.yesBtnText : 'Yes';
// INFORMATION/WARNING/ERROR/SUCCESS/CONFIRM
if (this.data.type === 'ERROR') {
this.msgTypeBackground = 'bg-warn p-1';
this.msgTypeForeground = 'warn';
}
this.data.message = (undefined === this.data.message) ? '' : this.data.message.replace(/{/g, '').replace(/"/g, '').replace(/}/g, '').replace(/\n/g, '');
// Start: For Payment Path
const arrayStartIdx = this.data.message.search('\\[');
const arrayEndIdx = this.data.message.search('\\]');
if (arrayStartIdx > -1 && arrayEndIdx > -1) {
this.data.message = this.data.message.substring(0, arrayStartIdx).concat(
this.data.message.substring(arrayStartIdx + 1, arrayEndIdx).replace(/,/g, '\n'),
this.data.message.substring(arrayEndIdx + 1));
}
// End: For Payment Path
this.messageObj = (this.data.message === '') ? [] : this.data.message.split(',');
this.messageObj.forEach((obj, idx) => {
this.messageObj[idx] = obj.split(':');
this.messageObj[idx][0] = this.messageObj[idx][0].replace(/_/g, ' '); // To replace Backend Data's '_'
// Start: To Merge Time Value Again with ':', example Payment Creation Time
if (this.messageObj[idx].length > 2) {
this.messageObj[idx].forEach((dataValue, j) => {
if (j === 0 || j === 1) {
return;
} else {
this.messageObj[idx][1] = this.messageObj[idx][1] + ':' + this.messageObj[idx][j];
}
});
this.messageObjs = this.data.message;
if (this.data.type === AlertTypeEnum.ERROR) {
if (undefined === this.data.message && undefined === this.data.titleMessage && this.messageObjs.length <= 0) {
this.data.titleMessage = 'Please Check Server Connection';
}
// End: To Merge Time Value Again with ':', example Payment Creation Time
});
}
showCopyOption(key): boolean {
let flgFoundKey = false;
const showCopyOnKeys = ['payment request', 'bolt11'];
showCopyOnKeys.filter((arrKey) => {
if (arrKey === key) {
flgFoundKey = true;
return true;
}
});
return flgFoundKey;
}
copiedText(payload) {
this.flgCopied = true;
setTimeout(() => {this.flgCopied = false; }, 5000);
this.logger.info('Copied Text: ' + payload);
}
isNumber(value, key): boolean {
let flgFoundKey = false;
const notNumberKeys = ['chan id', 'creation date'];
notNumberKeys.filter((arrKey) => {
if (arrKey === key) {
flgFoundKey = true;
}
});
if (!flgFoundKey) {
return new RegExp(/^[0-9]+$/).test(value);
} else {
return false;
}
this.logger.warn(this.messageObjs);
}
onClose(dialogRes: any) {

View file

@ -0,0 +1,27 @@
<div fxLayout="row">
<div fxFlex="100" class="padding-gap-large">
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header">
<div fxFlex="95" fxLayoutAlign="start start">
<span class="page-title">{{data.alertTitle || 'ERROR'}}</span>
</div>
<button tabindex="3" fxFlex="5" fxLayoutAlign="center" class="btn-close-x p-0" (click)="onClose()" mat-button>X</button>
</mat-card-header>
<mat-card-content class="mt-5px mb-0 error-alert-block">
<div fxLayout="column">
<p *ngIf="data.titleMessage" fxLayoutAlign="start center" class="pb-1">{{data.titleMessage}}</p>
<h4 fxLayoutAlign="start" class="font-bold-500">Error Code</h4>
<span>{{data.message.code}}</span>
<mat-divider class="w-100 my-1"></mat-divider>
<h4 fxLayoutAlign="start" class="font-bold-500">Error Message</h4>
<span class="word-break">{{errorMessage}}</span>
<mat-divider class="w-100 my-1"></mat-divider>
<h4 fxLayoutAlign="start" class="font-bold-500">API URL</h4>
<span class="word-break">{{data.message.URL}}</span>
<mat-divider class="w-100 my-1"></mat-divider>
<div fxLayout="row" fxLayoutAlign="end center">
<button fxLayoutAlign="center center" tabindex="1" autoFocus mat-raised-button color="primary" fxFlex="20" type="submit" [mat-dialog-close]="false" default>OK</button>
</div>
</div>
</mat-card-content>
</div>
</div>

View file

@ -0,0 +1,3 @@
.display-block {
display: block;
}

View file

@ -0,0 +1,28 @@
import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { LoggerService } from '../../../services/logger.service';
import { ErrorData } from '../../../models/alertData';
@Component({
selector: 'rtl-error-message',
templateUrl: './error-message.component.html',
styleUrls: ['./error-message.component.scss']
})
export class ErrorMessageComponent implements OnInit {
public errorMessage = '';
constructor(public dialogRef: MatDialogRef<ErrorMessageComponent>, @Inject(MAT_DIALOG_DATA) public data: ErrorData, private logger: LoggerService) { }
ngOnInit() {
this.errorMessage = (typeof(this.data.message.message) === 'object') ? JSON.stringify(this.data.message.message) : this.data.message.message;
if (undefined === this.data.message && undefined === this.data.titleMessage && !this.data.message) {
this.data.titleMessage = 'Please Check Server Connection';
}
this.logger.info(this.data.message);
}
onClose() {
this.dialogRef.close(false);
}
}

View file

@ -4,7 +4,7 @@ import { faReceipt } from '@fortawesome/free-solid-svg-icons';
import { MatSnackBar } from '@angular/material/snack-bar';
import { LoggerService } from '../../../services/logger.service';
import { AlertData } from '../../../models/alertData';
import { InvoiceInformation } from '../../../models/alertData';
import { Invoice } from '../../../models/lndModels';
@Component({
@ -18,10 +18,10 @@ export class InvoiceInformationComponent implements OnInit {
public newlyAdded = false;
public invoice: Invoice;
constructor(public dialogRef: MatDialogRef<InvoiceInformationComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService, private snackBar: MatSnackBar) { }
constructor(public dialogRef: MatDialogRef<InvoiceInformationComponent>, @Inject(MAT_DIALOG_DATA) public data: InvoiceInformation, private logger: LoggerService, private snackBar: MatSnackBar) { }
ngOnInit() {
this.invoice = JSON.parse(this.data.message);
this.invoice = this.data.invoice;
this.newlyAdded = this.data.newlyAdded;
}

View file

@ -1,6 +1,6 @@
<div fxLayout="row">
<div fxFlex="35" fxLayoutAlign="center start" class="modal-qr-code-container padding-gap-large">
<qrcode [qrdata]="address.address" [size]="230" [level]="'L'" [allowEmptyString]="true" class="qr-border"></qrcode>
<qrcode [qrdata]="address" [size]="230" [level]="'L'" [allowEmptyString]="true" class="qr-border"></qrcode>
</div>
<div fxFlex="65" class="padding-gap-large">
<mat-card-header fxLayout="row" fxLayoutAlign="space-between center" class="modal-info-header mb-2">
@ -15,19 +15,19 @@
<div fxLayout="row">
<div fxFlex="100">
<h4 fxLayoutAlign="start" class="font-bold-500">Address Type</h4>
<span class="foreground-secondary-text">{{address.addressType}}</span>
<span class="foreground-secondary-text">{{addressType}}</span>
</div>
</div>
<mat-divider class="w-100 my-1"></mat-divider>
<div fxLayout="row">
<div fxFlex="100">
<h4 fxLayoutAlign="start" class="font-bold-500">Address</h4>
<span class="overflow-wrap foreground-secondary-text">{{address.address}}</span>
<span class="overflow-wrap foreground-secondary-text">{{address}}</span>
</div>
</div>
<mat-divider class="w-100 my-1"></mat-divider>
<div class="mt-2" fxLayout="row" fxLayoutAlign="end center">
<button autoFocus fxFlex="33" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="1" type="submit" rtlClipboard [payload]="address.address" (copied)="onCopyAddress($event)">Copy Address</button>
<button autoFocus fxFlex="33" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="1" type="submit" rtlClipboard [payload]="address" (copied)="onCopyAddress($event)">Copy Address</button>
</div>
</div>
</mat-card-content>

View file

@ -4,7 +4,7 @@ import { faReceipt } from '@fortawesome/free-solid-svg-icons';
import { MatSnackBar } from '@angular/material/snack-bar';
import { LoggerService } from '../../../services/logger.service';
import { AlertData } from '../../../models/alertData';
import { OnChainAddressInformation } from '../../../models/alertData';
@Component({
selector: 'rtl-on-chain-generated-address',
@ -13,12 +13,14 @@ import { AlertData } from '../../../models/alertData';
})
export class OnChainGeneratedAddressComponent implements OnInit {
public faReceipt = faReceipt;
public address: {address: '', addressType: ''};
public address = '';
public addressType = '';
constructor(public dialogRef: MatDialogRef<OnChainGeneratedAddressComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService, private snackBar: MatSnackBar) { }
constructor(public dialogRef: MatDialogRef<OnChainGeneratedAddressComponent>, @Inject(MAT_DIALOG_DATA) public data: OnChainAddressInformation, private logger: LoggerService, private snackBar: MatSnackBar) { }
ngOnInit() {
this.address = JSON.parse(this.data.message);
this.address = this.data.address;
this.addressType = this.data.addressType;
}
onClose() {

View file

@ -3,7 +3,7 @@ import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
import { Store } from '@ngrx/store';
import { Peer, GetInfo } from '../../../models/lndModels';
import { AlertData } from '../../../models/alertData';
import { OpenChannelAlert } from '../../../models/alertData';
import { TRANS_TYPES } from '../../../services/consts-enums-functions';
import * as RTLActions from '../../../../store/rtl.actions';
@ -27,13 +27,12 @@ export class OpenChannelComponent implements OnInit {
public transTypeValue = {blocks: '', fees: ''};
public transTypes = TRANS_TYPES;
constructor(public dialogRef: MatDialogRef<OpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private store: Store<fromRTLReducer.RTLState>) { }
constructor(public dialogRef: MatDialogRef<OpenChannelComponent>, @Inject(MAT_DIALOG_DATA) public data: OpenChannelAlert, private store: Store<fromRTLReducer.RTLState>) { }
ngOnInit() {
let JSONdata = JSON.parse(this.data.message);
this.peer = JSONdata.peer;
this.information = JSONdata.information;
this.totalBalance = JSONdata.balance;
this.peer = this.data.message.peer;
this.information = this.data.message.information;
this.totalBalance = this.data.message.balance;
this.newlyAdded = this.data.newlyAdded;
this.alertTitle = this.data.alertTitle;
}

View file

@ -4,7 +4,7 @@ import { faReceipt } from '@fortawesome/free-solid-svg-icons';
import { MatSnackBar } from '@angular/material/snack-bar';
import { LoggerService } from '../../../services/logger.service';
import { AlertData } from '../../../models/alertData';
import { ShowPubkeyData } from '../../../models/alertData';
import { GetInfoRoot } from '../../../models/RTLconfig';
@Component({
@ -18,11 +18,10 @@ export class ShowPubkeyComponent implements OnInit {
public infoTypes = [{infoID: 0, infoKey: 'node pubkey', infoName: 'Node pubkey'}, { infoID: 1, infoKey: 'node URI', infoName: 'Node URI'}];
public selInfoType = this.infoTypes[0];
constructor(public dialogRef: MatDialogRef<ShowPubkeyComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService, private snackBar: MatSnackBar) { }
constructor(public dialogRef: MatDialogRef<ShowPubkeyComponent>, @Inject(MAT_DIALOG_DATA) public data: ShowPubkeyData, private logger: LoggerService, private snackBar: MatSnackBar) { }
ngOnInit() {
this.information = JSON.parse(this.data.message);
this.information.uris[0]
this.information = this.data.information;
}
onClose() {

View file

@ -1,15 +1,17 @@
<div fxLayout="column" fxLayoutAlign="center center">
<mat-card class="mat-elevation-z24 not-found-box">
<div fxLayout="column" fxLayoutAlign="center center" class="bg-primary py-2">
<button mat-fab color="accent" class="mat-elevation-z12">
<mat-icon>error</mat-icon>
</button>
<h1 class="error">{{error.errorCode}}</h1>
</div>
<mat-card-content fxLayout="row" fxLayoutAlign="center center">
<mat-card fxLayout="column" fxLayoutAlign="center center" class="mat-elevation-z12 w-100">
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
<fa-icon [icon]="faTimes" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Error {{error.errorCode}}</span>
</div>
<div fxLayout="column" class="padding-gap-x">
<mat-card>
<mat-card-content fxLayout="column" class="padding-gap-large">
<div fxLayout="column" fxLayoutAlign="start start">
<div class="box-text">{{error.errorMessage}}</div>
</mat-card>
<span fxLayout="row" fxLayoutAlign="center" fxFlex="80">
<button mat-raised-button color="primary" class="mt-2" type="button" (click)="goToHelp()">Go To Help</button>
</span>
</div>
</mat-card-content>
</mat-card>
</div>

View file

@ -1,8 +1,9 @@
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd } from '@angular/router';
import { ActivatedRoute, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { filter, map, takeUntil } from 'rxjs/operators';
import { takeUntil } from 'rxjs/operators';
import { faTimes } from '@fortawesome/free-solid-svg-icons';
@Component({
selector: 'rtl-error',
@ -10,9 +11,10 @@ import { filter, map, takeUntil } from 'rxjs/operators';
})
export class ErrorComponent implements OnInit {
error = {errorCode: '', errorMessage: ''};
public faTimes = faTimes;
private unsubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(private router: Router, private activatedRoute: ActivatedRoute) { }
constructor(private activatedRoute: ActivatedRoute, private router: Router) { }
ngOnInit() {
this.activatedRoute.paramMap
@ -22,4 +24,8 @@ export class ErrorComponent implements OnInit {
});
}
goToHelp(): void {
this.router.navigate(['/help']);
}
}

View file

@ -1,12 +1,11 @@
<div fxLayout="column">
<div class="padding-gap">
<mat-card>
<mat-card-header>
<mat-card-subtitle>
<h2>Help</h2>
</mat-card-subtitle>
</mat-card-header>
<mat-card-content *ngFor="let helpTopic of helpTopics">
<div fxLayout="column" fxFlex="100">
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
<fa-icon [icon]="faQuestion" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Help</span>
</div>
<div fxLayout="row" fxFlex="100" class="padding-gap-x" fxLayoutAlign="start start">
<mat-card fxLayout="column" fxFlex="100" class="padding-gap-large">
<mat-card-content fxFlex="100" *ngFor="let helpTopic of helpTopics">
<mat-expansion-panel>
<mat-expansion-panel-header>
<mat-panel-title>{{helpTopic.question}}</mat-panel-title>
@ -17,4 +16,5 @@
</mat-card-content>
</mat-card>
</div>
</div>
</div>

View file

@ -1,4 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { faQuestion } from '@fortawesome/free-solid-svg-icons';
export class HelpTopic {
question: string;
@ -17,13 +18,13 @@ export class HelpTopic {
})
export class HelpComponent implements OnInit {
public helpTopics: Array<HelpTopic> = [];
public faQuestion = faQuestion;
constructor() {}
ngOnInit() {
// this.helpTopics.push(new HelpTopic('Set LND home directory?',
// 'Pass the directroy information while getting the server up with --lndir "local-lnd-path".<br>Example: node rtl --lndir C:\lnd\dir\path'));
this.helpTopics.push(new HelpTopic('Change theme?', 'Click on rotating setting icon on the right side of the screen and choose from the given options.'));
this.helpTopics.push(new HelpTopic('Change setting?', 'Click on setting icon on the navigation and choose from the given options.'));
// this.helpTopics.push(new HelpTopic('', ''));
}
}

View file

@ -69,7 +69,7 @@ export class HorizontalNavigationComponent implements OnInit, OnDestroy {
onClick(node) {
if (node.name === 'Logout') {
this.store.dispatch(new RTLActions.OpenConfirmation({
width: '70%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Logout', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout'
width: '55%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Logout', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[2]))

View file

@ -118,7 +118,7 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
onClick(node: MenuChildNode) {
if (node.name === 'Logout') {
this.store.dispatch(new RTLActions.OpenConfirmation({
width: '70%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Logout', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout'
width: '55%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Logout', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[3]))

View file

@ -79,7 +79,7 @@ export class TopMenuComponent implements OnInit, OnDestroy {
onClick() {
this.store.dispatch(new RTLActions.OpenConfirmation({
width: '70%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Confirm Logout', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout'
width: '55%', data: { type: AlertTypeEnum.CONFIRM, alertTitle: 'Logout', titleMessage: 'Logout from this device?', noBtnText: 'Cancel', yesBtnText: 'Logout'
}}));
this.rtlEffects.closeConfirm
.pipe(takeUntil(this.unSubs[3]))

View file

@ -1,16 +1,16 @@
<div fxLayout="column" fxLayoutAlign="center center">
<mat-card class="mat-elevation-z24 not-found-box">
<div fxLayout="column" fxLayoutAlign="center center" class="bg-primary">
<button mat-fab color="accent" class="mat-elevation-z12">
<mat-icon>error</mat-icon>
</button>
<h1 class="error">404</h1>
</div>
<mat-card-content fxLayout="row" fxLayoutAlign="center center">
<mat-card fxLayout="column" fxLayoutAlign="center center" class="mat-elevation-z12 w-100">
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
<fa-icon [icon]="faTimes" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Page Not Found</span>
</div>
<div fxLayout="column" class="padding-gap-x">
<mat-card>
<mat-card-content fxLayout="column" class="padding-gap-large">
<div fxLayout="column" fxLayoutAlign="start start">
<div class="box-text">This page does not exist!</div>
<button mat-raised-button color="primary" class="mat-elevation-z12 padding-gap-x" type="button" (click)="goToHelp()">HELP</button>
</mat-card>
<span fxLayout="row" fxLayoutAlign="center" fxFlex="80">
<button mat-raised-button color="primary" class="mt-2" type="button" (click)="goToHelp()">Go To Help</button>
</span>
</div>
</mat-card-content>
</mat-card>
</div>

View file

@ -1,12 +1,14 @@
import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { faTimes } from '@fortawesome/free-solid-svg-icons';
@Component({
selector: 'rtl-not-found',
templateUrl: './not-found.component.html'
})
export class NotFoundComponent {
public faTimes = faTimes;
constructor(public router: Router) {}
goToHelp(): void {

View file

@ -1,27 +1,28 @@
<div fxLayout="column">
<div class="padding-gap">
<mat-card>
<mat-card-header>
<mat-card-subtitle>
<h2>Show Configurations</h2>
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-md="row wrap" class="mb-2">
<mat-radio-group fxFlex="20" fxLayoutAlign="start" (change)="onSelectionChange($event)" class="mt-1 mb-1">
<mat-radio-button class="pr-5" value="rtl" [checked]="selectedNodeType=='rtl'">RTL</mat-radio-button>
<mat-radio-button class="pr-5" value="ln" *ngIf="showLnConfig" [checked]="selectedNodeType=='ln'">{{lnImplementationStr}}</mat-radio-button>
<mat-radio-button class="pr-5" value="bitcoind" *ngIf="showBitcoind" [checked]="selectedNodeType=='bitcoind'">BITCOIND</mat-radio-button>
<div fxLayout="column" fxFlex="100">
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
<fa-icon [icon]="faCog" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Show Configurations</span>
</div>
<div fxLayout="row" class="padding-gap-x" fxLayoutAlign="start start">
<mat-card fxLayout="column" fxFlex="100" class="padding-gap-large">
<mat-card-content class="card-content-gap">
<form fxLayout="column" fxLayoutAlign="space-between stretch" fxLayout.gt-md="row wrap">
<mat-radio-group color="primary" fxFlex="20" fxLayoutAlign="start" (change)="onSelectionChange($event)" class="mt-1 mb-1">
<mat-radio-button tabindex="1" class="pr-5" value="rtl" [checked]="selectedNodeType=='rtl'">RTL</mat-radio-button>
<mat-radio-button tabindex="2" class="pr-5" value="ln" *ngIf="showLnConfig" [checked]="selectedNodeType=='ln'">{{lnImplementationStr}}</mat-radio-button>
<mat-radio-button tabindex="3" class="pr-5" value="bitcoind" *ngIf="showBitcoind" [checked]="selectedNodeType=='bitcoind'">BITCOIND</mat-radio-button>
</mat-radio-group>
<div fxFlex="30" fxLayoutAlign="space-between stretch">
<button fxFlex="50" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onShowConfig()" tabindex="2">Show Config</button>
<button fxFlex="50" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="3" type="reset" class="ml-2" (click)="resetData()">Clear</button>
<div fxFlex="30" fxLayoutAlign="space-between center">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="4" type="reset" (click)="resetData()">Clear</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onShowConfig()" tabindex="5">Show Config</button>
</div>
</form>
<div *ngIf="configData !== '' && fileFormat === 'JSON'">
<mat-divider *ngIf="configData !== ''" class="my-1"></mat-divider>
<div *ngIf="configData !== '' && fileFormat === 'JSON'" class="mt-2 mb-6">
<pre>{{configData | json}}</pre>
<mat-divider *ngIf="configData !== ''" class="my-1"></mat-divider>
</div>
<div *ngIf="configData !== '' && fileFormat === 'INI'">
<div *ngIf="configData !== '' && fileFormat === 'INI'" class="mt-2">
<mat-list>
<mat-list-item *ngFor="let conf of configData; index as i;">
<mat-card-subtitle class="my-1">
@ -38,3 +39,4 @@
</mat-card>
</div>
</div>

View file

@ -7,6 +7,7 @@ import { LightningNode } from '../../models/RTLconfig';
import { RTLEffects } from '../../../store/rtl.effects';
import * as RTLActions from '../../../store/rtl.actions';
import * as fromRTLReducer from '../../../store/rtl.reducers';
import { faCog } from '@fortawesome/free-solid-svg-icons';
@Component({
selector: 'rtl-server-config',
@ -21,18 +22,17 @@ export class ServerConfigComponent implements OnInit, OnDestroy {
public showBitcoind = false;
public configData = '';
public fileFormat = 'INI';
private unsubs: Array<Subject<void>> = [new Subject(), new Subject()];
public faCog = faCog;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects) {}
ngOnInit() {
this.store.select('root')
.pipe(takeUntil(this.unsubs[0]))
.pipe(takeUntil(this.unSubs[0]))
.subscribe((rtlStore) => {
rtlStore.effectErrorsRoot.forEach(effectsErr => {
if (effectsErr.action === 'fetchConfig') {
this.resetData();
}
if (effectsErr.action === 'fetchConfig') { this.resetData(); }
});
this.configData = '';
this.showLnConfig = false;
@ -63,7 +63,7 @@ export class ServerConfigComponent implements OnInit, OnDestroy {
this.store.dispatch(new RTLActions.OpenSpinner('Opening Config File...'));
this.store.dispatch(new RTLActions.FetchConfig(this.selectedNodeType));
this.rtlEffects.showLnConfig
.pipe(takeUntil(this.unsubs[1]))
.pipe(takeUntil(this.unSubs[1]))
.subscribe((config: any) => {
const configFile = config.data;
this.fileFormat = config.format;
@ -83,7 +83,7 @@ export class ServerConfigComponent implements OnInit, OnDestroy {
}
ngOnDestroy() {
this.unsubs.forEach(completeSub => {
this.unSubs.forEach(completeSub => {
completeSub.next();
completeSub.complete();
});

View file

@ -1,3 +1,21 @@
import { DataTypeEnum } from '../services/consts-enums-functions';
import { GetInfoRoot } from './RTLconfig';
import { GetInfo, Invoice } from './lndModels';
export interface MessageErrorField {
code: number;
message: string | any;
URL: string;
}
export interface MessageDataField {
key: string;
value: any;
title: string;
width: number;
type?: DataTypeEnum;
}
export interface InputData {
placeholder: string;
inputValue?: string | number | boolean;
@ -7,21 +25,63 @@ export interface InputData {
step?: number;
}
export interface AlertData {
type: string; // INFORMATION/WARNING/ERROR/SUCCESS/CONFIRM
export interface OpenChannelAlert {
alertTitle?: string;
titleMessage?: string;
message?: string;
messageFieldsBreakdown?: Array<number>;
message?: { peer: any, information: GetInfo, balance: number };
newlyAdded?: boolean;
component?: any;
}
export interface InvoiceInformation {
invoice: Invoice;
newlyAdded?: boolean;
component?: any;
}
export interface OnChainAddressInformation {
alertTitle?: string;
address: string;
addressType: string;
component?: any;
}
export interface ShowPubkeyData {
information: GetInfoRoot;
component?: any;
}
export interface AlertData {
type: string; // INFORMATION/WARNING/SUCCESS/ERROR
alertTitle?: string;
titleMessage?: string;
message?: Array<Array<MessageDataField>>;
showQRName?: string;
showQRField?: string;
newlyAdded?: boolean;
component?: any;
}
export interface ConfirmationData {
type: string; // INFORMATION/WARNING/SUCCESS/ERROR
alertTitle?: string;
titleMessage?: string;
message?: any;
noBtnText?: string;
yesBtnText?: string;
flgShowInput?: boolean;
getInputs?: Array<InputData>;
newlyAdded?: boolean;
component?: any;
}
export interface ErrorData {
alertTitle?: string;
titleMessage?: string;
message?: MessageErrorField;
component?: any;
}
export interface DialogConfig {
width: string;
data: AlertData;
data: AlertData | ConfirmationData | ErrorData | OpenChannelAlert | InvoiceInformation | OnChainAddressInformation | ShowPubkeyData;
}

View file

@ -1,4 +1,4 @@
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faProjectDiagram, faCog, faLifeRing, faSearch, faTools } from '@fortawesome/free-solid-svg-icons';
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faProjectDiagram, faCog, faQuestion, faSearch, faTools } from '@fortawesome/free-solid-svg-icons';
export const MENU_DATA: MenuRootNode = {
LNDChildren: [
@ -12,7 +12,7 @@ export const MENU_DATA: MenuRootNode = {
]},
{id: 4, parentId: 0, name: 'Advanced', iconType: 'FA', icon: faCog, link: '/sconfig'},
{id: 5, parentId: 0, name: 'Settings', iconType: 'FA', icon: faTools, link: '/settings'},
{id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faLifeRing, link: '/help'}
{id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help'}
],
CLChildren: [
{id: 1, parentId: 0, name: 'Dashboard', iconType: 'FA', icon: faTachometerAlt, link: '/cl/home'},
@ -25,7 +25,7 @@ export const MENU_DATA: MenuRootNode = {
]},
{id: 4, parentId: 0, name: 'Advanced', iconType: 'FA', icon: faCog, link: '/sconfig'},
{id: 5, parentId: 0, name: 'Settings', iconType: 'FA', icon: faTools, link: '/settings'},
{id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faLifeRing, link: '/help'}
{id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help'}
]
};

View file

@ -52,3 +52,13 @@ export enum CurrencyUnitEnum {
LTC = 'LTC',
OTHER = 'OTHER'
}
export enum DataTypeEnum {
ARRAY = 'ARRAY',
NUMBER = 'NUMBER',
STRING = 'STRING',
BOOLEAN = 'BOOLEAN',
PASSWORD = 'PASSWORD',
DATE = 'DATE',
DATE_TIME = 'DATE_TIME'
}

View file

@ -21,6 +21,7 @@ import { OnChainGeneratedAddressComponent } from './components/data-modal/on-cha
import { AppSettingsComponent } from './components/app-settings/app-settings.component';
import { AlertMessageComponent } from './components/data-modal/alert-message/alert-message.component';
import { ConfirmationMessageComponent } from './components/data-modal/confirmation-message/confirmation-message.component';
import { ErrorMessageComponent } from './components/data-modal/error-message/error-message.component';
import { SpinnerDialogComponent } from './components/data-modal/spinner-dialog/spinner-dialog.component';
import { NotFoundComponent } from './components/not-found/not-found.component';
import { SigninComponent } from './components/signin/signin.component';
@ -120,6 +121,7 @@ import { ShowPubkeyComponent } from './components/data-modal/show-pubkey/show-pu
OnChainGeneratedAddressComponent,
AlertMessageComponent,
ConfirmationMessageComponent,
ErrorMessageComponent,
SpinnerDialogComponent,
NotFoundComponent,
SideNavigationComponent,
@ -141,6 +143,7 @@ import { ShowPubkeyComponent } from './components/data-modal/show-pubkey/show-pu
OnChainGeneratedAddressComponent,
AlertMessageComponent,
ConfirmationMessageComponent,
ErrorMessageComponent,
SpinnerDialogComponent,
NotFoundComponent,
SideNavigationComponent,
@ -164,7 +167,8 @@ import { ShowPubkeyComponent } from './components/data-modal/show-pubkey/show-pu
ShowPubkeyComponent,
SpinnerDialogComponent,
AlertMessageComponent,
ConfirmationMessageComponent
ConfirmationMessageComponent,
ErrorMessageComponent
],
providers: [
{ provide: MAT_DIALOG_DEFAULT_OPTIONS, useValue: { hasBackdrop: true, autoFocus: true, disableClose: true, role: 'dialog', width: '700px' } },

View file

@ -259,10 +259,18 @@ body {
margin-top: 1rem !important;
}
.mb-0 {
margin-bottom: 0 !important;
}
.mb-1 {
margin-bottom: 1rem !important;
}
.mb-6 {
margin-bottom: 6rem !important;
}
.ml-1 {
margin-left: 1rem !important;
}
@ -343,6 +351,10 @@ body {
margin: 2rem 0 !important;
}
.my-4 {
margin: 4rem 0 !important;
}
.m-2 {
margin: 2rem !important;
}
@ -435,6 +447,10 @@ body {
padding: 0 2rem !important;
}
.px-3 {
padding: 0 3rem !important;
}
.px-4 {
padding: 0 4rem !important;
}
@ -653,7 +669,7 @@ body {
}
.not-found-box {
min-width: 30%;
min-width: 50%;
}
.w-100 {
@ -771,10 +787,6 @@ table {
width:100%;
}
// .mat-button-focus-overlay {
// background-color: transparent!important;
// }
.green-dot {
display: inline-flex;
width: $dot-size;

View file

@ -13,7 +13,7 @@ import { environment, API_URL } from '../../environments/environment';
import { LoggerService } from '../shared/services/logger.service';
import { SessionService } from '../shared/services/session.service';
import { Settings, RTLConfiguration } from '../shared/models/RTLconfig';
import { AuthenticateWith, CURRENCY_UNITS, AlertTypeEnum } from '../shared/services/consts-enums-functions';
import { AuthenticateWith, CURRENCY_UNITS, AlertTypeEnum, DataTypeEnum } from '../shared/services/consts-enums-functions';
import { SpinnerDialogComponent } from '../shared/components/data-modal/spinner-dialog/spinner-dialog.component';
import { AlertMessageComponent } from '../shared/components/data-modal/alert-message/alert-message.component';
@ -22,6 +22,7 @@ import { ShowPubkeyComponent } from '../shared/components/data-modal/show-pubkey
import * as RTLActions from './rtl.actions';
import * as fromRTLReducer from './rtl.reducers';
import { ErrorMessageComponent } from '../shared/components/data-modal/error-message/error-message.component';
@Injectable()
export class RTLEffects implements OnDestroy {
@ -102,11 +103,8 @@ export class RTLEffects implements OnDestroy {
if (!this.sessionService.getItem('token') || !rootData.nodeData.identity_pubkey) {
this.snackBar.open('Node Pubkey does not exist.');
} else {
this.store.dispatch(new RTLActions.OpenAlert({width: '70%',
data: {
type: AlertTypeEnum.INFORMATION,
alertTitle: '',
message: JSON.stringify(rootData.nodeData),
this.store.dispatch(new RTLActions.OpenAlert({width: '70%', data: {
information: rootData.nodeData,
component: ShowPubkeyComponent
}}));
}
@ -156,7 +154,11 @@ export class RTLEffects implements OnDestroy {
this.logger.info(updateStatus);
return {
type: RTLActions.OPEN_ALERT,
payload: { config : { width: '70%', data: { type: AlertTypeEnum.SUCCESS, titleMessage: (!updateStatus.length) ? updateStatus.message : updateStatus[0].message + '. ' + updateStatus[1].message }}}
payload: { width: '55%', data: {
type: AlertTypeEnum.SUCCESS,
alertTitle: 'Settings updated',
titleMessage: (!updateStatus.length) ? updateStatus.message : updateStatus[0].message + '. ' + updateStatus[1].message
}}
};
},
catchError((err) => {
@ -352,11 +354,11 @@ export class RTLEffects implements OnDestroy {
} else {
this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({
width: '70%', data: {
width: '55%', data: {
type: alertType,
alertTitle: alertTitle,
titleMessage: alertTitle,
message: JSON.stringify({ code: err.status, Message: err.error.error, URL: errURL })
message: { code: err.status, message: err.error.error, URL: errURL },
component: ErrorMessageComponent
}
}));
}

View file

@ -18,7 +18,7 @@ const initNodeAuthentication = { nodeAuthType: 'CUSTOM', configPath: '', bitcoin
const initRootState: RootState = {
effectErrorsRoot: [],
selNode: {settings: initNodeSettings, authentication: initNodeAuthentication},
selNode: {settings: initNodeSettings, authentication: initNodeAuthentication, lnImplementation: 'LND'},
appConfig: {
defaultNodeIndex: -1,
selectedNodeIndex: -1,