Network Information

Network Information
pull/260/head
Shahana Farooqui 5 years ago
parent 79d04a5d7a
commit 98f874cd07

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -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.3b647f02f87dbde63ee9.css"></head>
<link rel="stylesheet" href="styles.8a1ddaedb5da1018195e.css"></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.af78130362f8d52a18b0.js"></script><script src="polyfills-es5.2e75d230d7f9c760eb2f.js" nomodule></script><script src="polyfills.1ebb102854b0ec478c1b.js"></script><script src="main.1a920fe27b5e532dac46.js"></script></body>
<script src="runtime.8de0300ea7cbcf176757.js"></script><script src="polyfills-es5.2e75d230d7f9c760eb2f.js" nomodule></script><script src="polyfills.1ebb102854b0ec478c1b.js"></script><script src="main.54108a6aab5d60775c5e.js"></script></body>
</html>

File diff suppressed because one or more lines are too long

@ -1 +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:"9e71a210a8bdc5ba9df9",6:"af311c76cbdf1165a591",7:"f304a8c9801c62bf8967"}[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()}([]);
!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:"9e71a210a8bdc5ba9df9",6:"9f448ec4afdcbbc42cf2",7:"f304a8c9801c62bf8967"}[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

File diff suppressed because one or more lines are too long

@ -26,6 +26,9 @@ common.getOptions = () => {
};
common.updateSelectedNodeOptions = () => {
if (!common.selectedNode) {
common.selectedNode = {};
}
common.selectedNode.options = {
url: '',
rejectUnauthorized: false,

@ -6,7 +6,7 @@ var common = require('../common');
exports.updateSelectedNode = (req, res, next) => {
const selNodeIndex = req.body.selNodeIndex;
common.selectedNode = common.findNode(selNodeIndex);
const responseVal = common.selectedNode.ln_node ? common.selectedNode.ln_node : common.selectedNode.ln_server_url;
const responseVal = !common.selectedNode ? '' : (common.selectedNode.ln_node ? common.selectedNode.ln_node : common.selectedNode.ln_server_url);
logger.info({fileName: 'RTLConf', msg: 'Selected Node Updated To: ' + JSON.stringify(responseVal)});
res.status(200).json({status: 'Selected Node Updated To: ' + JSON.stringify(responseVal) + '!'});
};

@ -6,7 +6,7 @@ exports.info = (msgJSON, selNode = common.selectedNode) => {
if (msgJSON.fileName !== 'Config Setup Variable') {
console.log('Console: ' + msgStr);
}
if(selNode.enable_logging) {
if(selNode && selNode.enable_logging) {
fs.appendFile(selNode.log_file, msgStr, function(err) {
if (err) {
return ({ error: 'Updating Log Failed!' });
@ -20,7 +20,7 @@ exports.info = (msgJSON, selNode = common.selectedNode) => {
exports.error = (msgJSON, selNode = common.selectedNode) => {
const msgStr = '\r\nERROR: ' + msgJSON.fileName + '(' + msgJSON.lineNum + ') => ' + msgJSON.msg;
console.error('Console: ' + msgStr);
if(selNode.enable_logging) {
if(selNode && selNode.enable_logging) {
fs.appendFile(selNode.log_file, msgStr, function(err) {
if (err) {
return ({ error: 'Updating Log Failed!' });

@ -1,5 +1,6 @@
.mat-progress-bar.dashboard-progress-bar {
height: 6px;
min-height: 6px;
}
.dashboard-divider {

@ -1,5 +1,5 @@
<div fxLayout="column" fxLayoutAlign="space-between start" fxFlex="100">
<div fxLayout="column" fxFlex="8" fxLayoutAlign="end start" class="w-100">
<div fxLayout="column" fxFlex="9" fxLayoutAlign="end start" class="w-100">
<h2>{{totalLiquidity | number}} Sats</h2>
<h4>Max Transaction Amount: {{(maxAmount <= 4200000 ? maxAmount : 4200000) | number}} Sats</h4>
<mat-divider class="w-100 dashboard-divider mt-2"></mat-divider>

@ -1,7 +1,7 @@
<div fxLayout="column" *ngIf="selNode.userPersona === userPersonaEnum.OPERATOR; else merchantDashboard">
<div fxLayout="row" fxLayoutAlign="start end" class="padding-gap-x page-title-container mb-0">
<fa-icon [icon]="faSmile" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Welcome! Your node is up and running.</span>
<fa-icon [icon]="!flgLoading[0] ? faSmile : faFrown" class="page-title-img mr-1"></fa-icon>
<span class="page-title">{{!flgLoading[0] ? 'Welcome! Your node is up and running.' : 'Error! Please check the server connection.'}}</span>
</div>
<mat-grid-list cols="10" rowHeight="330px">
<mat-grid-tile *ngFor="let card of operatorCards | async" [colspan]="card.cols" [rowspan]="card.rows">
@ -30,12 +30,13 @@
<fa-icon [icon]="faSmile" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Welcome! Your node is up and running.</span>
</div>
<mat-grid-list cols="3" rowHeight="220px">
<mat-grid-list cols="3" rowHeight="66px">
<mat-grid-tile *ngFor="let card of merchantCards | async" [colspan]="card.cols" [rowspan]="card.rows">
<mat-card fxLayout="column" fxLayoutAlign="start start" class="dashboard-card" [ngClass]="{'p-16': card.id !== 'transactions'}">
<mat-card-header *ngIf="card.id !== 'transactions'"><mat-card-title>{{card.title}}</mat-card-title></mat-card-header>
<mat-card-content class="dashboard-card-content w-100" fxFlex="{{card.id !== 'transactions' ? 95 : 100}}">
<div [ngSwitch]="card.id" fxLayout="column" fxFlex="100">
<rtl-node-info fxFlex="100" *ngSwitchCase="'node'" [information]="information" [ngClass]="{'error-border': flgLoading[0]==='error'}"></rtl-node-info>
<rtl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [flgInfoUpdate]="flgChildInfoUpdated" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error' || flgLoading[5]==='error'}"></rtl-balances-info>
<rtl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'inboundLiq'" [direction]="'In'" [totalLiquidity]="totalInboundLiquidity" [allChannels]="allInboundChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-channel-liquidity-info>
<rtl-channel-liquidity-info fxFlex="100" *ngSwitchCase="'outboundLiq'" [direction]="'Out'" [totalLiquidity]="totalOutboundLiquidity" [allChannels]="allOutboundChannels" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-channel-liquidity-info>

@ -5,7 +5,7 @@ import { Subject } from 'rxjs';
import { takeUntil, filter } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { faSmile } from '@fortawesome/free-regular-svg-icons';
import { faSmile, faFrown } from '@fortawesome/free-regular-svg-icons';
import { LoggerService } from '../../shared/services/logger.service';
import { CommonService } from '../../shared/services/common.service';
@ -22,6 +22,7 @@ import * as RTLActions from '../../store/rtl.actions';
})
export class HomeComponent implements OnInit, OnDestroy {
public faSmile = faSmile;
public faFrown = faFrown;
public flgChildInfoUpdated = false;
public userPersonaEnum = UserPersonaEnum;
public activeChannels = 0;
@ -67,18 +68,20 @@ export class HomeComponent implements OnInit, OnDestroy {
map(({ matches }) => {
if (matches) {
return [
{ id: 'balance', title: 'Balances', cols: 3, rows: 1 },
{ id: 'transactions', title: 'Transactions', cols: 3, rows: 1 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 3, rows: 1 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 3, rows: 1 }
{ id: 'node', title: 'Node Details', cols: 3, rows: 3 },
{ id: 'balance', title: 'Balances', cols: 3, rows: 3 },
{ id: 'transactions', title: 'Transactions', cols: 3, rows: 4 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 3, rows: 8 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 3, rows: 8 }
];
}
return [
{ id: 'balance', title: 'Balances', cols: 1, rows: 1 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 1, rows: 3 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 1, rows: 3 },
{ id: 'transactions', title: 'Transactions', cols: 1, rows: 2 }
{ id: 'node', title: 'Node Details', cols: 1, rows: 3 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 1, rows: 10 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 1, rows: 10 },
{ id: 'balance', title: 'Balances', cols: 1, rows: 3 },
{ id: 'transactions', title: 'Transactions', cols: 1, rows: 4 }
];
})
);

@ -8,7 +8,7 @@
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Implementation</h4>
<div class="foreground-secondary-text">{{information.lnImplementation + ' v' + information.version}}</div>
<div class="foreground-secondary-text">{{(information.lnImplementation || information.version) ? information.lnImplementation + ' v' + information.version : ''}}</div>
</div>
<div fxFlex="34">
<h4 fxLayoutAlign="start" class="font-bold-500">Chain</h4>

@ -48,6 +48,7 @@ import { MatButtonModule } from '@angular/material/button';
import { LayoutModule } from '@angular/cdk/layout';
import { ChannelLiquidityInfoComponent } from './home/channel-liquidity-info/channel-liquidity-info.component';
import { LoopComponent } from './loop/loop.component';
import { NetworkInfoComponent } from './network-info/network-info.component';
@NgModule({
imports: [
@ -96,7 +97,8 @@ import { LoopComponent } from './loop/loop.component';
ChannelStatusInfoComponent,
ChannelCapacityInfoComponent,
LoopComponent,
ChannelLiquidityInfoComponent
ChannelLiquidityInfoComponent,
NetworkInfoComponent
],
providers: [
{ provide: LoggerService, useClass: ConsoleLoggerService },

@ -9,6 +9,7 @@ import { TransactionsComponent } from './transactions/transactions.component';
import { LookupsComponent } from './lookups/lookups.component';
import { RoutingComponent } from './routing/routing.component';
import { OnChainComponent } from './on-chain/on-chain.component';
import { NetworkInfoComponent } from './network-info/network-info.component';
import { LoopComponent } from './loop/loop.component';
import { AuthGuard, LNDUnlockedGuard } from '../shared/services/auth.guard';
@ -24,6 +25,7 @@ export const LndRoutes: Routes = [
{ path: 'onchain', component: OnChainComponent, canActivate: [LNDUnlockedGuard] },
{ path: 'routing', component: RoutingComponent, canActivate: [LNDUnlockedGuard] },
{ path: 'lookups', component: LookupsComponent, canActivate: [LNDUnlockedGuard] },
{ path: 'network', component: NetworkInfoComponent, canActivate: [LNDUnlockedGuard] },
{ path: 'loop', component: LoopComponent, canActivate: [LNDUnlockedGuard] },
{ path: '**', component: NotFoundComponent }
]}

@ -0,0 +1,54 @@
<div fxLayout="column">
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
<fa-icon [icon]="faNetworkWired" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Network Information</span>
</div>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start start" class="padding-gap-x">
<mat-card fxLayout="row" fxFlex="100" fxLayoutAlign="start start">
<mat-progress-bar *ngIf="flgLoading[1]===true" mode="indeterminate"></mat-progress-bar>
<mat-card-content fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch" class="card-content-gap">
<div fxLayout="row" fxLayoutAlign="start start" fxFlex="100" class="my-2">
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-330">Network Capacity</h4>
<span class="foreground-secondary-text">{{networkInfo.total_network_capacity | number}} Sats</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-330">Number of Nodes</h4>
<span class="foreground-secondary-text">{{networkInfo.num_nodes | number}}</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-330">Number of Channels</h4>
<span class="foreground-secondary-text">{{networkInfo.num_channels | number}}</span>
</div>
<mat-divider fxFlex="100" class="w-100 mt-6"></mat-divider>
</div>
<div fxLayout="row" fxLayoutAlign="start start" fxFlex="100" class="my-2">
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-330">Max Channel Size</h4>
<span class="foreground-secondary-text">{{networkInfo.max_channel_size | number}}</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-330">Avg Channel Size</h4>
<span class="foreground-secondary-text">{{networkInfo.avg_channel_size | number}}</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-330">Min Channel Size</h4>
<span class="foreground-secondary-text">{{networkInfo.min_channel_size | number}}</span>
</div>
<mat-divider fxFlex="100" class="w-100 mt-6"></mat-divider>
</div>
<div fxLayout="row" fxLayoutAlign="start start" fxFlex="100" class="my-2">
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-330">Max Out Degree</h4>
<span class="foreground-secondary-text">{{networkInfo.max_out_degree | number}}</span>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-330">Avg Out Degree</h4>
<span class="foreground-secondary-text">{{networkInfo.avg_out_degree | number:'1.0-2'}}</span>
</div>
<mat-divider fxFlex="100" class="w-100 mt-6"></mat-divider>
</div>
</mat-card-content>
</mat-card>
</div>
</div>

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NetworkInfoComponent } from './network-info.component';
describe('NetworkInfoComponent', () => {
let component: NetworkInfoComponent;
let fixture: ComponentFixture<NetworkInfoComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ NetworkInfoComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(NetworkInfoComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

@ -0,0 +1,61 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { faNetworkWired } from '@fortawesome/free-solid-svg-icons';
import { LoggerService } from '../../shared/services/logger.service';
import { GetInfo, NetworkInfo } from '../../shared/models/lndModels';
import { SelNodeChild } from '../../shared/models/RTLconfig';
import * as fromRTLReducer from '../../store/rtl.reducers';
@Component({
selector: 'rtl-network-info',
templateUrl: './network-info.component.html',
styleUrls: ['./network-info.component.scss']
})
export class NetworkInfoComponent implements OnInit, OnDestroy {
public faNetworkWired = faNetworkWired;
public selNode: SelNodeChild = {};
public information: GetInfo = {};
public networkInfo: NetworkInfo = {};
public flgLoading: Array<Boolean | 'error'> = [true, true];
private unSubs: Array<Subject<void>> = [new Subject()];
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.RTLState>) {}
ngOnInit() {
this.store.select('lnd')
.pipe(takeUntil(this.unSubs[0]))
.subscribe((rtlStore) => {
rtlStore.effectErrorsLnd.forEach(effectsErr => {
if (effectsErr.action === 'FetchInfo') {
this.flgLoading[0] = 'error';
}
if (effectsErr.action === 'FetchNetwork') {
this.flgLoading[1] = 'error';
}
});
this.selNode = rtlStore.nodeSettings;
this.information = rtlStore.information;
if (this.flgLoading[0] !== 'error') {
this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true;
}
this.networkInfo = rtlStore.networkInfo;
if (this.flgLoading[1] !== 'error') {
this.flgLoading[1] = (undefined !== this.networkInfo.num_nodes) ? false : true;
}
this.logger.info(rtlStore);
});
}
ngOnDestroy() {
this.unSubs.forEach(completeSub => {
completeSub.next();
completeSub.complete();
});
}
}

@ -3,22 +3,22 @@
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
<input matInput [(ngModel)]="memo" placeholder="Memo" tabindex="1" name="memo">
</mat-form-field>
<div fxLayout="column" [fxLayout.gt-sm]="showDetails ? 'row wrap' : 'column'" [fxFlex]="showDetails ? 70 : 100" [fxLayoutAlign.gt-sm]="showDetails ? 'space-between center' : 'start stretch'" fxLayoutAlign="space-between center">
<div fxLayout="column" [fxLayout.gt-sm]="showDetails ? 'row wrap' : 'column'" [fxFlex]="showDetails ? 70 : 100" [fxLayoutAlign.gt-sm]="showDetails ? 'space-between center' : 'start stretch'" fxLayoutAlign="start stretch">
<mat-form-field fxFlex="40" fxLayoutAlign="start end">
<input matInput [(ngModel)]="invoiceValue" (keyup)="onInvoiceValueChange()" placeholder="Amount" type="number" step="100" min="1" tabindex="2" name="invoiceValue">
<span matSuffix> {{information?.smaller_currency_unit}} </span>
<mat-hint>{{invoiceValueHint}}</mat-hint>
</mat-form-field>
<mat-form-field fxFlex="15" fxLayoutAlign="start end">
<mat-form-field fxFlex="15" fxLayoutAlign="start end" *ngIf="showDetails">
<input matInput [(ngModel)]="expiry" placeholder="Expiry" type="number" step="{{selTimeUnit === timeUnitEnum.SECS ? 300 : selTimeUnit === timeUnitEnum.MINS ? 10 : selTimeUnit === timeUnitEnum.HOURS ? 2 : 1}}" min="1" tabindex="3" name="expiry">
<span matSuffix> {{selTimeUnit | titlecase}} </span>
</mat-form-field>
<mat-form-field fxFlex="15" fxLayoutAlign="start end">
<mat-form-field fxFlex="15" fxLayoutAlign="start end" *ngIf="showDetails">
<mat-select [value]="selTimeUnit" tabindex="4" required name="timeUnit" (selectionChange)="onTimeUnitChange($event)">
<mat-option *ngFor="let timeUnit of timeUnits" [value]="timeUnit">{{timeUnit | titlecase}}</mat-option>
</mat-select>
</mat-form-field>
<div fxFlex="25" tabindex="4" fxLayoutAlign="start center">
<div fxFlex="25" tabindex="4" fxLayoutAlign="start center" *ngIf="showDetails">
<mat-slide-toggle color="primary" [(ngModel)]="private" matTooltip="Include routing hints for private channels" [matTooltipPosition]="'above'" name="private">Private Routing Hints</mat-slide-toggle>
</div>
</div>

@ -1,4 +1,4 @@
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faProjectDiagram, faCog, faQuestion, faSearch, faTools } from '@fortawesome/free-solid-svg-icons';
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faProjectDiagram, faNetworkWired, faCog, faQuestion, faSearch, faTools } from '@fortawesome/free-solid-svg-icons';
export const MENU_DATA: MenuRootNode = {
LNDChildren: [
@ -8,7 +8,8 @@ export const MENU_DATA: MenuRootNode = {
{id: 31, parentId: 3, name: 'Peers/Channels', iconType: 'FA', icon: faUsers, link: '/lnd/peerschannels'},
{id: 32, parentId: 3, name: 'Transactions', iconType: 'FA', icon: faExchangeAlt, link: '/lnd/transactions'},
{id: 33, parentId: 3, name: 'Lookup', iconType: 'FA', icon: faSearch, link: '/lnd/lookups'},
{id: 34, parentId: 3, name: 'Routing', iconType: 'FA', icon: faProjectDiagram, link: '/lnd/routing'}
{id: 34, parentId: 3, name: 'Routing', iconType: 'FA', icon: faProjectDiagram, link: '/lnd/routing'},
{id: 35, parentId: 3, name: 'Network', iconType: 'FA', icon: faNetworkWired, link: '/lnd/network'}
]},
{id: 4, parentId: 0, name: 'Advanced', iconType: 'FA', icon: faCog, link: '/advanced'},
{id: 5, parentId: 0, name: 'Settings', iconType: 'FA', icon: faTools, link: '/settings'},

@ -326,6 +326,10 @@ body {
margin-top: 4rem !important;
}
.mt-6 {
margin-top: 6rem !important;
}
.mt-minus-1 {
margin-top: -1rem !important;
}

@ -121,12 +121,18 @@ export class RTLEffects implements OnDestroy {
map((rtlConfig: RTLConfiguration) => {
this.logger.info(rtlConfig);
let searchNode = rtlConfig.nodes.find(node => +node.index === rtlConfig.selectedNodeIndex);
searchNode.settings.currencyUnits = [...CURRENCY_UNITS, searchNode.settings.currencyUnit];
this.store.dispatch(new RTLActions.SetSelelectedNode({lnNode: searchNode, isInitialSetup: true}))
return {
type: RTLActions.SET_RTL_CONFIG,
payload: rtlConfig
};
if(searchNode) {
searchNode.settings.currencyUnits = [...CURRENCY_UNITS, searchNode.settings.currencyUnit];
this.store.dispatch(new RTLActions.SetSelelectedNode({lnNode: searchNode, isInitialSetup: true}))
return {
type: RTLActions.SET_RTL_CONFIG,
payload: rtlConfig
};
} else {
return {
type: RTLActions.VOID
}
}
},
catchError((err) => {
this.handleErrorWithoutAlert('FetchRTLConfig', err);
@ -242,6 +248,8 @@ export class RTLEffects implements OnDestroy {
ofType(RTLActions.SIGNIN),
withLatestFrom(this.store.select('root')),
mergeMap(([action, rootStore]: [RTLActions.Signin, fromRTLReducer.RootState]) => {
this.store.dispatch(new RTLActions.ClearEffectErrorLnd('FetchInfo'));
this.store.dispatch(new RTLActions.ClearEffectErrorCl('FetchInfoCL'));
this.store.dispatch(new RTLActions.ClearEffectErrorRoot('Signin'));
return this.httpClient.post(environment.AUTHENTICATE_API, {
authenticateWith: (undefined === action.payload || action.payload == null || action.payload === '') ? AuthenticateWith.TOKEN : AuthenticateWith.PASSWORD,
@ -357,7 +365,7 @@ export class RTLEffects implements OnDestroy {
width: '55%', data: {
type: alertType,
alertTitle: alertTitle,
message: { code: err.status, message: err.error.error, URL: errURL },
message: { code: err.status ? err.status : 'Unknown Error', message: (err.error && err.error.error) ? err.error.error : (err.error) ? err.error : 'Unknown Error', URL: errURL },
component: ErrorMessageComponent
}
}));

@ -13,7 +13,7 @@ export interface RootState {
nodeData: GetInfoRoot;
}
const initNodeSettings = { userPersona: 'Operator', flgSidenavOpened: true, flgSidenavPinned: true, menu: 'vertical', menuType: 'regular', fontSize: 'regular-font', themeMode: 'night', themeColor: 'blue', satsToBTC: false, channelBackupPath: '', selCurrencyUnit: 'USD', currencyUnits: ['Sats', 'BTC', 'USD'] };
const initNodeSettings = { userPersona: 'Operator', flgSidenavOpened: true, flgSidenavPinned: true, menu: 'vertical', menuType: 'regular', fontSize: 'regular-font', themeMode: 'day', themeColor: 'purple', satsToBTC: false, channelBackupPath: '', selCurrencyUnit: 'USD', currencyUnits: ['Sats', 'BTC', 'USD'] };
const initNodeAuthentication = { nodeAuthType: 'CUSTOM', configPath: '', bitcoindConfigPath: '' };
const initRootState: RootState = {

Loading…
Cancel
Save