dashboard and settings

dashboard and settings
pull/260/head
Shahana Farooqui 4 years ago
parent ff1b7ca74c
commit f02229479e

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

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.338691320cacab894cbc.css"></head>
<link rel="stylesheet" href="styles.7342c1312d7434d854df.css"></head>
<body>
<rtl-app></rtl-app>
<script src="runtime.56a6c127b1339195bd27.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.596829b8f38729cd77e6.js" defer></script></body>
<script src="runtime.3200a96426bdc2028426.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.8060670d53993730b06c.js" defer></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

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

@ -1 +0,0 @@
!function(e){function r(r){for(var n,a,i=r[0],c=r[1],l=r[2],p=0,s=[];p<i.length;p++)a=i[p],Object.prototype.hasOwnProperty.call(o,a)&&o[a]&&s.push(o[a][0]),o[a]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,l||[]),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:"dbfa80f5eb3d9dedcde5",6:"b9be31044349c6986abe",7:"c5834861d28d8736cb69"}[e]+".js"}(e);var c=new Error;u=function(r){i.onerror=i.onload=null,clearTimeout(l);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 l=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 l=0;l<i.length;l++)r(i[l]);var f=c;t()}([]);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -15,7 +15,7 @@
tabindex="1" required #paymentReq="ngModel">
</mat-form-field>
</div>
<div fxFlex="100" fxFlex.gt-sm="30" fxLayout="row" fxLayoutAlign="space-between stretch">
<div fxFlex="100" fxFlex.gt-sm="30" fxLayout="row" fxLayoutAlign="space-between stretch" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary"
[disabled]="paymentReq.invalid" (click)="onSendPayment()" tabindex="2">
<p *ngIf="paymentReq.invalid && (paymentReq.dirty || paymentReq.touched); else sendText">Invalid Req</p>

@ -1,21 +1,16 @@
<div fxLayout="column" fxFlex="40" fxLayoutAlign="start start">
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Lightning</h4>
<div class="foreground-secondary-text">{{balances.lightning | number}} (Sats)</div>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Lightning</h4>
<div class="dashboard-info-value">{{balances.lightning | number}} Sats</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{balances.lightning/balances.total*100}}"></mat-progress-bar>
</div>
<div fxFlex="25" fxLayoutAlign="start start"></div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">On-chain</h4>
<div class="foreground-secondary-text">{{balances.onchain | number}} (Sats)</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">On-chain</h4>
<div class="dashboard-info-value">{{balances.onchain | number}} Sats</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{balances.onchain/balances.total*100}}"></mat-progress-bar>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Total</h4>
<div class="dashboard-info-value">{{balances.total | number}} Sats</div>
</div>
</div>
<div fxLayout="column" fxFlex="60" fxLayoutAlign="start start" *ngIf="flgInfoUpdate">
<ngx-charts-pie-chart class="balances-info-pie-chart" style="margin-top: -5rem;"
[view]="graphView"
[explodeSlices]="true"
[legend]="true"
[legendTitle]="''"
[legendPosition]="'below'"
[results]="totalBalances">
</ngx-charts-pie-chart>
</div>

@ -1,27 +1,13 @@
import { Component, OnChanges, Input } from '@angular/core';
import { Component, Input } from '@angular/core';
@Component({
selector: 'rtl-balances-info',
templateUrl: './balances-info.component.html',
styleUrls: ['./balances-info.component.scss']
})
export class BalancesInfoComponent implements OnChanges {
@Input() balances = { onchain: 0, lightning: 0 };
@Input() flgInfoUpdate = false;
@Input() cardHeight = '';
flgBalanceUpdated = false;
totalBalances = [{'name': 'Lightning', 'value': 0}, {'name': 'On-chain', 'value': 0}];
maxBalanceValue = 0;
xAxisLabel = 'Balance';
graphView = [200, 120];
export class BalancesInfoComponent {
@Input() balances = { onchain: 0, lightning: 0, total: 0 };
constructor() {}
ngOnChanges() {
this.graphView = [200, Math.floor(+this.cardHeight.substring(0, this.cardHeight.length-2))*2];
this.totalBalances = [{'name': 'Lightning', 'value': this.balances.lightning}, {'name': 'On-chain', 'value': this.balances.onchain}];
this.maxBalanceValue = (this.balances.lightning > this.balances.onchain) ? this.balances.lightning : this.balances.onchain;
Object.assign(this, this.totalBalances);
}
}

@ -1,19 +1,20 @@
<div fxLayout="column" fxLayoutAlign="space-between start" fxFlex="100">
<div fxLayout="column" fxFlex="5" fxLayoutAlign="start start" class="w-100">
<div fxLayout="column" fxLayoutAlign="space-between stretch" fxFlex="100">
<div fxLayout="column" fxFlex="10" fxLayoutAlign="end start">
<span class="dashboard-capacity-header this-channel-capacity">Total Capacity</span>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint fxFlex="50" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">Local:</strong>{{channelBalances.localBalance || 0 | number}} Sats</mat-hint>
<mat-hint fxFlex="50" fxLayoutAlign="end center" class="font-size-80"><strong class="font-weight-900">Remote:</strong>{{channelBalances.remoteBalance || 0 | number}} Sats</mat-hint>
<mat-hint fxFlex="50" fxLayoutAlign="start center" class="font-size-90"><strong class="font-weight-900 mr-5px">Local:</strong>{{channelBalances.localBalance || 0 | number}} Sats</mat-hint>
<mat-hint fxFlex="50" fxLayoutAlign="end center" class="font-size-90"><strong class="font-weight-900 mr-5px">Remote:</strong>{{channelBalances.remoteBalance || 0 | number}} Sats</mat-hint>
</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channelBalances.localBalance && channelBalances.localBalance > 0 ? ((+channelBalances.localBalance/((+channelBalances.localBalance)+(+channelBalances.remoteBalance)))*100) : 0}}"></mat-progress-bar>
<mat-progress-bar class="dashboard-progress-bar this-channel-bar" mode="determinate" color="accent" value="{{channelBalances.localBalance && channelBalances.localBalance > 0 ? ((+channelBalances.localBalance/((+channelBalances.localBalance)+(+channelBalances.remoteBalance)))*100) : 0}}"></mat-progress-bar>
<mat-divider class="w-100 dashboard-divider"></mat-divider>
</div>
<div fxLayout="column" fxFlex="92" fxFlex.lt-md="85" fxLayoutAlign="start start" class="channels-capacity-scroll" perfectScrollbar>
<div fxLayout="column" fxFlex="89" fxFlex.lt-md="85" fxLayoutAlign="start start" class="channels-capacity-scroll" perfectScrollbar>
<div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<div *ngFor="let channel of allChannels" class="mt-2">
<h4>{{(channel.remote_alias || channel.remote_pubkey) | slice:0:24}}{{(channel.remote_alias || channel.remote_pubkey).length > 25 ? '...' : ''}}</h4>
<span class="dashboard-capacity-header">{{(channel.remote_alias || channel.remote_pubkey) | slice:0:24}}{{(channel.remote_alias || channel.remote_pubkey).length > 25 ? '...' : ''}}</span>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint fxFlex="50" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">Local:</strong>{{channel.local_balance || 0 | number}} Sats</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}} Sats</mat-hint>
<mat-hint fxFlex="50" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Local:</strong>{{channel.local_balance || 0 | number}} Sats</mat-hint>
<mat-hint fxFlex="50" fxLayoutAlign="end center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Remote:</strong>{{channel.remote_balance || 0 | number}} Sats</mat-hint>
</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channel.balancedness}}"></mat-progress-bar>
</div>
@ -23,26 +24,3 @@
<ng-template #noChannelBlock>
<div fxLayout="column" fxFlex="100" class="w-100 mt-2">No channels available.</div>
</ng-template>
<!-- <div fxLayout="column" fxLayoutAlign="space-between start" fxFlex="100">
<div fxLayout="column" fxFlex="5" fxLayoutAlign="start start" class="w-100">
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint fxFlex="50" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">Local:</strong>{{channelBalances.localBalance || 0 | number}} Sats</mat-hint>
<mat-hint fxFlex="50" fxLayoutAlign="end center" class="font-size-80"><strong class="font-weight-900">Remote:</strong>{{channelBalances.remoteBalance || 0 | number}} Sats</mat-hint>
</div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channelBalances.localBalance && channelBalances.localBalance > 0 ? ((+channelBalances.localBalance/((+channelBalances.localBalance)+(+channelBalances.remoteBalance)))*100) : 0}}"></mat-progress-bar>
<mat-divider class="w-100 dashboard-divider"></mat-divider>
</div>
<div fxLayout="column" fxFlex="92" fxFlex.lt-md="85" fxLayoutAlign="start start" class="channels-capacity-scroll" perfectScrollbar>
<div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<ngx-charts-bar-horizontal-stacked
[xAxis]="true"
[yAxis]="true"
[noBarWhenZero]="false"
[showDataLabel]="true"
[results]="allChannelBalances"></ngx-charts-bar-horizontal-stacked>
</div>
</div>
</div>
<ng-template #noChannelBlock>
<div fxLayout="column" fxFlex="100" class="w-100 mt-2">No channels available.</div>
</ng-template> -->

@ -1,15 +1,5 @@
.mat-progress-bar.dashboard-progress-bar {
height: 6px;
min-height: 6px;
}
.dashboard-divider {
margin-top: 4rem;
border-top-width: 2px;
}
.channels-capacity-scroll {
width: 100%;
height: 100%;
overflow-y: hidden;
}
}

@ -1,16 +1,23 @@
<div fxLayout="column" fxLayoutAlign="space-between start" fxFlex="100">
<div fxLayout="column" fxFlex="9" fxLayoutAlign="end start" class="w-100">
<h2>{{totalLiquidity | number}} Sats</h2>
<h4>Max Transaction Amount: {{(maxAmount <= 4294967 ? maxAmount : 4294967) | number}} Sats</h4>
<div fxLayout="column" fxLayoutAlign="space-between stretch" fxFlex="100">
<div fxLayout="column" fxFlex="10" fxLayoutAlign="end stretch">
<div fxLayout="row" fxLayoutAlign="space-between start">
<span class="dashboard-capacity-header this-channel-capacity">Max Transaction</span>
<span class="dashboard-capacity-header this-channel-capacity">Total Capacity</span>
</div>
<div fxLayout="row" fxLayoutAlign="space-between stretch">
<mat-hint class="font-size-90">{{maxAmount | number}} Sats</mat-hint>
<mat-hint class="font-size-90">{{totalLiquidity | number}} Sats</mat-hint>
</div>
<mat-progress-bar class="dashboard-progress-bar this-channel-bar" mode="determinate" color="accent" value="{{maxAmount/totalLiquidity*100 ? maxAmount/totalLiquidity*100 : 0}}"></mat-progress-bar>
<mat-divider class="w-100 dashboard-divider mt-2"></mat-divider>
</div>
<div fxLayout="column" fxFlex="90" fxFlex.lt-md="85" fxLayoutAlign="start start" class="channels-capacity-scroll w-100 mt-2" perfectScrollbar>
<div fxLayout="column" fxFlex="89" fxFlex.lt-md="85" fxLayoutAlign="start start" class="channels-capacity-scroll w-100 mt-2" perfectScrollbar>
<div fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<div *ngFor="let channel of allChannels" class="mt-2">
<h4>{{(channel.remote_alias || channel.remote_pubkey) | slice:0:24}}{{(channel.remote_alias || channel.remote_pubkey).length > 25 ? '...' : ''}}</h4>
<span class="dashboard-capacity-header">{{(channel.remote_alias || channel.remote_pubkey) | slice:0:24}}{{(channel.remote_alias || channel.remote_pubkey).length > 25 ? '...' : ''}}</span>
<div fxLayout="row" fxLayoutAlign="space-between start" class="w-100">
<mat-hint *ngIf="direction === 'In'" fxFlex="100" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">{{channel.remote_balance || 0 | number}} Sats</strong></mat-hint>
<mat-hint *ngIf="direction === 'Out'" fxFlex="100" fxLayoutAlign="start center" class="font-size-80"><strong class="font-weight-900">{{channel.local_balance || 0 | number}} Sats</strong></mat-hint>
<mat-hint *ngIf="direction === 'In'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.remote_balance || 0 | number}} Sats</mat-hint>
<mat-hint *ngIf="direction === 'Out'" fxFlex="100" fxLayoutAlign="start center" class="font-size-90 color-primary"><strong class="font-weight-900 mr-5px">Capacity: </strong>{{channel.local_balance || 0 | number}} Sats</mat-hint>
</div>
<mat-progress-bar *ngIf="direction === 'In'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((+channel.remote_balance || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar>
<mat-progress-bar *ngIf="direction === 'Out'" class="dashboard-progress-bar" mode="determinate" value="{{(totalLiquidity > 0) ? ((+channel.local_balance || 0)/(totalLiquidity) * 100) : 0}}"></mat-progress-bar>

@ -18,9 +18,9 @@ export class ChannelLiquidityInfoComponent implements OnChanges {
ngOnChanges() {
if (this.allChannels && this.allChannels.length > 0) {
if(this.direction === 'In') {
this.maxAmount = this.allChannels[0].remote_balance;
this.maxAmount = this.allChannels[0].remote_balance <= 4294967 ? this.allChannels[0].remote_balance : 4294967;
} else {
this.maxAmount = this.allChannels[0].local_balance;
this.maxAmount = this.allChannels[0].local_balance <= 4294967 ? this.allChannels[0].local_balance : 4294967;
}
}
}

@ -1,28 +1,36 @@
<div fxLayout="column" fxFlex="50" fxLayoutAlign="center start">
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Active</h4>
<div class="foreground-secondary-text"><span class="dot tiny-dot green"></span>{{(channelsStatus.active.channels || 0) | number}}</div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Active</h4>
<div class="dashboard-info-value"><span class="dot tiny-dot green"></span>{{(channelsStatus.active.channels || 0) | number}}</div>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Pending</h4>
<div class="foreground-secondary-text"><span class="dot tiny-dot yellow"></span>{{(channelsStatus.pending.channels || 0) | number}}</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Pending</h4>
<div class="dashboard-info-value"><span class="dot tiny-dot yellow"></span>{{(channelsStatus.pending.channels || 0) | number}}</div>
</div>
<div fxFlex="34">
<h4 fxLayoutAlign="start" class="font-bold-500">Inactive</h4>
<div class="foreground-secondary-text"><span class="dot tiny-dot red"></span>{{(channelsStatus.inactive.channels || 0) | number}}</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Inactive</h4>
<div class="dashboard-info-value"><span class="dot tiny-dot grey"></span>{{(channelsStatus.inactive.channels || 0) | number}}</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Closing</h4>
<div class="dashboard-info-value"><span class="dot tiny-dot red"></span>{{(channelsStatus.closing.channels || 0) | number}}</div>
</div>
</div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="center start">
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Capacity</h4>
<div class="foreground-secondary-text">{{(channelsStatus.active.capacity || 0) | number}} (Sats)</div>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Capacity</h4>
<div class="foreground-secondary-text">{{(channelsStatus.pending.capacity || 0) | number}} (Sats)</div>
</div>
<div fxFlex="34">
<h4 fxLayoutAlign="start" class="font-bold-500">Capacity</h4>
<div class="foreground-secondary-text">{{(channelsStatus.inactive.capacity || 0) | number}} (Sats)</div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="dashboard-info-value">{{(channelsStatus.active.capacity || 0) | number}} Sats</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="dashboard-info-value">{{(channelsStatus.pending.capacity || 0) | number}} Sats</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="dashboard-info-value">{{(channelsStatus.inactive.capacity || 0) | number}} Sats</div>
</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="dashboard-info-value">{{(channelsStatus.closing.capacity || 0) | number}} Sats</div>
</div>
</div>

@ -1,22 +1,14 @@
<div fxLayout="column" fxFlex="60" fxLayoutAlign="center start">
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Daily</h4>
<div class="foreground-secondary-text">{{fees?.day_fee_sum | number}} (Sats)</div>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Daily</h4>
<div class="dashboard-info-value">{{fees?.day_fee_sum | number}} Sats</div>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Weekly</h4>
<div class="foreground-secondary-text">{{fees?.week_fee_sum | number}} (Sats)</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Weekly</h4>
<div class="dashboard-info-value">{{fees?.week_fee_sum | number}} Sats</div>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Monthly</h4>
<div class="foreground-secondary-text">{{fees?.month_fee_sum | number}} (Sats)</div>
<div>
<h4 fxLayoutAlign="start" class="dashboard-info-title">Monthly</h4>
<div class="dashboard-info-value">{{fees?.month_fee_sum | number}} Sats</div>
</div>
</div>
<div fxLayout="column" fxFlex="60" fxLayoutAlign="start start" *ngIf="flgInfoUpdate">
<ngx-charts-gauge class="fee-info-gauge-chart" style="margin-top: -2.5rem;margin-left: -8rem;"
[showText]="false"
[max]="maxFeeValue"
[view]="[300, 300]"
[results]="totalFees">
</ngx-charts-gauge>
</div>

@ -8,7 +8,6 @@ import { Fees } from '../../../shared/models/lndModels';
})
export class FeeInfoComponent implements OnChanges {
@Input() fees: Fees;
@Input() flgInfoUpdate = false;
totalFees = [{'name': 'Monthly', 'value': 0}, {'name': 'Weekly', 'value': 0}, {'name': 'Daily', 'value': 0}];
maxFeeValue = 100;

@ -5,18 +5,19 @@
</div>
<mat-grid-list cols="10" [rowHeight]="operatorCardHeight">
<mat-grid-tile *ngFor="let card of operatorCards" [colspan]="card.cols" [rowspan]="card.rows">
<mat-card fxLayout="column" fxLayoutAlign="start start" class="dashboard-card p-16">
<mat-card fxLayout="column" fxLayoutAlign="start start" class="dashboard-card p-24">
<mat-card-header>
<mat-card-title>
{{card.title}}
<fa-icon [icon]="card.icon" class="mr-1"></fa-icon>
<span>{{card.title}}</span>
</mat-card-title>
</mat-card-header>
<mat-card-content class="dashboard-card-content w-100" fxFlex="95">
<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-balances-info fxFlex="100" *ngSwitchCase="'balance'" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error' || flgLoading[5]==='error'}"></rtl-balances-info>
<rtl-channel-capacity-info fxFlex="100" *ngSwitchCase="'capacity'" [channelBalances]="channelBalances" [allChannels]="allChannelsCapacity" [ngClass]="{'error-border': flgLoading[5]==='error'}"></rtl-channel-capacity-info>
<rtl-fee-info fxFlex="100" *ngSwitchCase="'fee'" [flgInfoUpdate]="flgChildInfoUpdated" [fees]="fees" [ngClass]="{'error-border': flgLoading[1]==='error'}"></rtl-fee-info>
<rtl-fee-info fxFlex="100" *ngSwitchCase="'fee'" [fees]="fees" [ngClass]="{'error-border': flgLoading[1]==='error'}"></rtl-fee-info>
<rtl-channel-status-info fxFlex="100" *ngSwitchCase="'status'" [channelsStatus]="channelsStatus" [ngClass]="{'error-border': flgLoading[5]==='error' || flgLoading[6]==='error'}"></rtl-channel-status-info>
<h3 *ngSwitchDefault>Error! Unable to find information!</h3>
</div>
@ -32,12 +33,17 @@
</div>
<mat-grid-list cols="6" [rowHeight]="merchantCardHeight">
<mat-grid-tile *ngFor="let card of merchantCards" [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 fxLayout="column" fxLayoutAlign="start start" class="dashboard-card" [ngClass]="{'p-24': card.id !== 'transactions'}">
<mat-card-header *ngIf="card.id !== 'transactions'">
<mat-card-title>
<fa-icon [icon]="card.icon" class="mr-1"></fa-icon>
<span>{{card.title}}</span>
</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'" [cardHeight]="merchantCardHeight" [flgInfoUpdate]="flgChildInfoUpdated" [balances]="balances" [ngClass]="{'error-border': flgLoading[2]==='error' || flgLoading[5]==='error'}"></rtl-balances-info>
<rtl-balances-info fxFlex="100" *ngSwitchCase="'balance'" [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>
<span fxLayout="column" fxFlex="100" *ngSwitchCase="'transactions'">

@ -4,6 +4,7 @@ import { takeUntil, filter } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { Actions } from '@ngrx/effects';
import { faSmile, faFrown } from '@fortawesome/free-regular-svg-icons';
import { faFileDownload, faFileUpload, faChartPie, faBolt, faInfoCircle, faNetworkWired } from '@fortawesome/free-solid-svg-icons';
import { LoggerService } from '../../shared/services/logger.service';
import { CommonService } from '../../shared/services/common.service';
@ -21,16 +22,21 @@ import * as RTLActions from '../../store/rtl.actions';
export class HomeComponent implements OnInit, OnDestroy {
public faSmile = faSmile;
public faFrown = faFrown;
public faFileDownload = faFileDownload;
public faFileUpload = faFileUpload;
public faChartPie = faChartPie;
public faBolt = faBolt;
public faInfoCircle = faInfoCircle;
public faNetworkWired = faNetworkWired;
public flgChildInfoUpdated = false;
public userPersonaEnum = UserPersonaEnum;
public activeChannels = 0;
public inactiveChannels = 0;
public pendingChannels = 0;
public channelBalances = {localBalance: 0, remoteBalance: 0};
public selNode: SelNodeChild = {};
public fees: Fees;
public information: GetInfo = {};
public balances = { onchain: -1, lightning: -1 };
public balances = { onchain: -1, lightning: -1, total: 0 };
public allChannels: Channel[] = [];
public channelsStatus: ChannelsStatus = {};
public allChannelsCapacity: Channel[] = [];
@ -50,50 +56,47 @@ export class HomeComponent implements OnInit, OnDestroy {
this.screenSize = this.commonService.getScreenSize();
if(this.screenSize === ScreenSizeEnum.XS) {
this.operatorCards = [
{ id: 'node', title: 'Node Details', cols: 10, rows: 1 },
{ id: 'balance', title: 'Balances', cols: 10, rows: 1 },
{ id: 'fee', title: 'Routing Fee Earned', cols: 10, rows: 1 },
{ id: 'status', title: 'Channel Status', cols: 10, rows: 1 },
{ id: 'capacity', title: 'Channel Capacity', cols: 10, rows: 2 }
{ id: 'node', icon: this.faInfoCircle, title: 'Node Information', cols: 10, rows: 1 },
{ id: 'balance', icon: this.faChartPie, title: 'Balances', cols: 10, rows: 1 },
{ id: 'fee', icon: this.faBolt, title: 'Routing Fee Report', cols: 10, rows: 1 },
{ id: 'status', icon: this.faNetworkWired, title: 'Channels', cols: 10, rows: 1 },
{ id: 'capacity', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 10, rows: 2 }
];
this.merchantCards = [
{ id: 'node', title: 'Node Details', cols: 6, rows: 3 },
{ id: 'balance', title: 'Balances', cols: 6, rows: 3 },
{ id: 'balance', icon: this.faChartPie, title: 'Balances', cols: 6, rows: 4 },
{ id: 'transactions', title: 'Transactions', cols: 6, rows: 4 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 6, rows: 8 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 6, rows: 8 }
{ id: 'inboundLiq', icon: this.faFileDownload, title: 'In-Bound Liquidity', cols: 6, rows: 8 },
{ id: 'outboundLiq', icon: this.faFileUpload, title: 'Out-Bound Liquidity', cols: 6, rows: 8 }
];
} else if(this.screenSize === ScreenSizeEnum.SM || this.screenSize === ScreenSizeEnum.MD) {
this.operatorCards = [
{ id: 'node', title: 'Node Details', cols: 5, rows: 1 },
{ id: 'balance', title: 'Balances', cols: 5, rows: 1 },
{ id: 'fee', title: 'Routing Fee Earned', cols: 5, rows: 1 },
{ id: 'status', title: 'Channel Status', cols: 5, rows: 1 },
{ id: 'capacity', title: 'Channel Capacity', cols: 10, rows: 2 }
{ id: 'node', icon: this.faInfoCircle, title: 'Node Information', cols: 5, rows: 1 },
{ id: 'balance', icon: this.faChartPie, title: 'Balances', cols: 5, rows: 1 },
{ id: 'fee', icon: this.faBolt, title: 'Routing Fee Report', cols: 5, rows: 1 },
{ id: 'status', icon: this.faNetworkWired, title: 'Channels', cols: 5, rows: 1 },
{ id: 'capacity', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 10, rows: 2 }
];
this.merchantCards = [
{ id: 'node', title: 'Node Details', cols: 3, rows: 3 },
{ id: 'balance', title: 'Balances', cols: 3, rows: 3 },
{ id: 'transactions', title: 'Transactions', cols: 6, rows: 4 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 3, rows: 8 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 3, rows: 8 }
{ id: 'balance', icon: this.faChartPie, title: 'Balances', cols: 3, rows: 4 },
{ id: 'transactions', title: 'Transactions', cols: 3, rows: 4 },
{ id: 'inboundLiq', icon: this.faFileDownload, title: 'In-Bound Liquidity', cols: 3, rows: 8 },
{ id: 'outboundLiq', icon: this.faFileUpload, title: 'Out-Bound Liquidity', cols: 3, rows: 8 }
];
} else {
this.operatorCardHeight = ((window.screen.height - 200) / 2) + 'px';
this.merchantCardHeight = ((window.screen.height - 210) / 10) + 'px';
this.operatorCards = [
{ id: 'node', title: 'Node Details', cols: 3, rows: 1 },
{ id: 'balance', title: 'Balances', cols: 3, rows: 1 },
{ id: 'capacity', title: 'Channel Capacity', cols: 4, rows: 2 },
{ id: 'fee', title: 'Routing Fee Earned', cols: 3, rows: 1 },
{ id: 'status', title: 'Channel Status', cols: 3, rows: 1 }
{ id: 'node', icon: this.faInfoCircle, title: 'Node Information', cols: 3, rows: 1 },
{ id: 'balance', icon: this.faChartPie, title: 'Balances', cols: 3, rows: 1 },
{ id: 'capacity', icon: this.faNetworkWired, title: 'Channels Capacity', cols: 4, rows: 2 },
{ id: 'fee', icon: this.faBolt, title: 'Routing Fee Report', cols: 3, rows: 1 },
{ id: 'status', icon: this.faNetworkWired, title: 'Channels', cols: 3, rows: 1 }
];
this.merchantCards = [
{ id: 'node', title: 'Node Details', cols: 2, rows: 3 },
{ id: 'inboundLiq', title: 'In-Bound Liquidity', cols: 2, rows: 10 },
{ id: 'outboundLiq', title: 'Out-Bound Liquidity', cols: 2, rows: 10 },
{ id: 'balance', title: 'Balances', cols: 2, rows: 3 },
{ id: 'transactions', title: 'Transactions', cols: 2, rows: 4 }
{ id: 'balance', icon: this.faChartPie, title: 'Balances', cols: 2, rows: 5 },
{ id: 'inboundLiq', icon: this.faFileDownload, title: 'In-Bound Liquidity', cols: 2, rows: 10 },
{ id: 'outboundLiq', icon: this.faFileUpload, title: 'Out-Bound Liquidity', cols: 2, rows: 10 },
{ id: 'transactions', title: 'Transactions', cols: 2, rows: 5 }
];
}
}
@ -143,19 +146,19 @@ export class HomeComponent implements OnInit, OnDestroy {
if (this.flgLoading[5] !== 'error') {
this.flgLoading[5] = false;
}
this.balances.total = this.balances.lightning + this.balances.onchain;
this.balances = Object.assign({}, this.balances);
this.activeChannels = rtlStore.numberOfActiveChannels;
this.inactiveChannels = rtlStore.numberOfInactiveChannels;
this.pendingChannels = (undefined !== rtlStore.pendingChannels.pending_open_channels) ? rtlStore.pendingChannels.pending_open_channels.length : 0;
this.pendingChannels = this.pendingChannels + ((undefined !== rtlStore.pendingChannels.waiting_close_channels) ? rtlStore.pendingChannels.waiting_close_channels.length : 0);
this.pendingChannels = this.pendingChannels + ((undefined !== rtlStore.pendingChannels.pending_closing_channels) ? rtlStore.pendingChannels.pending_closing_channels.length : 0);
this.pendingChannels = this.pendingChannels + ((undefined !== rtlStore.pendingChannels.pending_force_closing_channels) ? rtlStore.pendingChannels.pending_force_closing_channels.length : 0);
this.channelsStatus = {
active: { channels: rtlStore.numberOfActiveChannels, capacity: rtlStore.totalCapacityActive },
inactive: { channels: rtlStore.numberOfInactiveChannels, capacity: rtlStore.totalCapacityInactive },
pending: { channels: this.pendingChannels, capacity: rtlStore.pendingChannels.total_limbo_balance },
closed: { channels: (rtlStore.closedChannels && rtlStore.closedChannels.length) ? rtlStore.closedChannels.length : 0, capacity: 0 }
pending: { channels: rtlStore.numberOfPendingChannels.open.num_channels, capacity: rtlStore.numberOfPendingChannels.open.limbo_balance },
closing: {
channels: rtlStore.numberOfPendingChannels.closing.num_channels + rtlStore.numberOfPendingChannels.force_closing.num_channels + rtlStore.numberOfPendingChannels.waiting_close.num_channels,
capacity: rtlStore.numberOfPendingChannels.closing.limbo_balance + rtlStore.numberOfPendingChannels.force_closing.limbo_balance + rtlStore.numberOfPendingChannels.waiting_close.limbo_balance
}
};
if (rtlStore.totalLocalBalance >= 0 && rtlStore.totalRemoteBalance >= 0 && this.flgLoading[5] !== 'error') {
this.flgLoading[5] = false;

@ -1,17 +1,17 @@
<div fxLayout="column" fxFlex="100" fxLayoutAlign="center start">
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Alias</h4>
<div class="foreground-secondary-text">
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
<div>
<h4 class="dashboard-info-title">Alias</h4>
<div class="dashboard-info-value">
{{information.alias}}
<span class="dot ml-1" [ngStyle]="{'backgroundColor': information.color}"></span>
<span class="dashboard-node-dot dot" [ngStyle]="{'backgroundColor': information.color}"></span>
</div>
</div>
<div fxFlex="33">
<h4 fxLayoutAlign="start" class="font-bold-500">Implementation</h4>
<div class="foreground-secondary-text">{{(information.lnImplementation || information.version) ? information.lnImplementation + ' v' + information.version : ''}}</div>
<div>
<h4 class="dashboard-info-title">Implementation</h4>
<div class="dashboard-info-value">{{(information.lnImplementation || information.version) ? information.lnImplementation + ' v' + information.version : ''}}</div>
</div>
<div fxFlex="34">
<h4 fxLayoutAlign="start" class="font-bold-500">Chain</h4>
<span class="overflow-wrap foreground-secondary-text" *ngFor="let chain of chains">{{chain}}</span>
<div>
<h4 class="dashboard-info-title">Chain</h4>
<span class="overflow-wrap dashboard-info-value" *ngFor="let chain of chains">{{chain}}</span>
</div>
</div>

@ -17,7 +17,7 @@
<mat-form-field fxFlex="68" fxLayoutAlign="start end">
<input matInput name="lookupKey" [placeholder]="lookupFields[selectedFieldId]?.placeholder || 'Lookup Key'" (change)="clearLookupValue()" [(ngModel)]="lookupKey" tabindex="2" required>
</mat-form-field>
<div fxFlex="30" fxLayoutAlign="space-between stretch">
<div fxFlex="30" fxLayoutAlign="space-between stretch" class="mt-2">
<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>

@ -6,7 +6,7 @@
<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">
<div fxFlex="30" fxLayoutAlign="space-between center">
<div fxFlex="30" fxLayoutAlign="space-between center" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="1" (click)="onStopMonitor()">Stop Monitor</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="2" (click)="onStartMonitor()">Start Monitor</button>
</div>

@ -27,7 +27,7 @@
</mat-form-field>
</div>
<div fxLayout="column" fxFlex="100" fxFlex.gt-sm="40" fxLayout.gt-sm="row wrap" fxLayoutAlign="start stretch" fxLayoutAlign.gt-sm="space-between start"></div>
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Fields</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary"
[disabled]="invalidValues" type="submit" tabindex="8" (click)="onSendFunds()">
@ -60,7 +60,7 @@
</mat-form-field>
</div>
<div>
<div fxFlex="100" fxFlex.gt-sm="30" fxLayout="row" fxLayoutAlign="space-between stretch">
<div fxFlex="100" fxFlex.gt-sm="30" fxLayout="row" fxLayoutAlign="space-between stretch" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Fields</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" [disabled]="invalidValues" type="submit" tabindex="8" (click)="onSendFunds()">
<p *ngIf="invalidValues && (addressSweep.touched || addressSweep.dirty); else sendTextSweep">Invalid Values</p>

@ -105,10 +105,9 @@ export class ChannelManageComponent implements OnInit, OnDestroy {
addNewPeer() {
this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM,
alertTitle: 'Add Peer',
titleMessage: 'Enter Peer Address',
alertTitle: 'Add peer',
message: '',
noBtnText: 'Cancel',
noBtnText: 'Do it Later',
yesBtnText: 'Add Peer',
flgShowInput: true,
getInputs: [

@ -24,7 +24,7 @@ export class ChannelsTablesComponent implements OnInit, OnDestroy {
.pipe(takeUntil(this.unSubs[0]))
.subscribe((rtlStore) => {
this.openChannels = (rtlStore.allChannels && rtlStore.allChannels.length) ? rtlStore.allChannels.length : 0;
this.pendingChannels = (rtlStore.numberOfPendingChannels) ? rtlStore.numberOfPendingChannels : 0;
this.pendingChannels = (rtlStore.numberOfPendingChannels.total_channels) ? rtlStore.numberOfPendingChannels.total_channels : 0;
this.closedChannels = (rtlStore.closedChannels && rtlStore.closedChannels.length) ? rtlStore.closedChannels.length : 0;
this.logger.info(rtlStore);
});

@ -3,7 +3,7 @@
<mat-form-field fxFlex="100" fxLayoutAlign="start end">
<input matInput placeholder="Lightning Address (pubkey OR pubkey@ip:port)" name="peerAddress" [(ngModel)]="peerAddress" tabindex="1" required #peerAdd="ngModel">
</mat-form-field>
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" [disabled]="peerAdd.invalid" type="submit" tabindex="3" (click)="onConnectPeer()">
<p *ngIf="peerAdd.invalid && (peerAdd.dirty || peerAdd.touched); else connectText">Invalid Address</p>

@ -21,7 +21,7 @@
<mat-datepicker #endDatepicker [startAt]="endDate"></mat-datepicker>
</mat-form-field>
</div>
<div fxFlex="30" fxLayoutAlign="space-between stretch">
<div fxFlex="30" fxLayoutAlign="space-between stretch" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()">Clear</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" [disabled]="routingForm.invalid" type="submit" tabindex="4">Fetch Events</button>
</div>

@ -11,7 +11,7 @@ import { MatDialog } from '@angular/material';
import { environment, API_URL } from '../../../environments/environment';
import { LoggerService } from '../../shared/services/logger.service';
import { SessionService } from '../../shared/services/session.service';
import { GetInfo, GetInfoChain, Fees, Balance, NetworkInfo, Payment, GraphNode, Transaction, SwitchReq, ListInvoices } from '../../shared/models/lndModels';
import { GetInfo, GetInfoChain, Fees, Balance, NetworkInfo, Payment, GraphNode, Transaction, SwitchReq, ListInvoices, PendingChannelsGroup } from '../../shared/models/lndModels';
import { InvoiceInformationComponent } from '../../shared/components/data-modal/invoice-information/invoice-information.component';
import { OpenChannelComponent } from '../../shared/components/data-modal/open-channel/open-channel.component';
import { CurrencyUnitEnum, AlertTypeEnum } from '../../shared/services/consts-enums-functions';
@ -476,23 +476,37 @@ export class LNDEffects implements OnDestroy {
.pipe(
map((channels: any) => {
this.logger.info(channels);
let pendingChannels = -1;
let pendingChannels: PendingChannelsGroup = { open: {num_channels: 0, limbo_balance: 0}, closing: {num_channels: 0, limbo_balance: 0}, force_closing: {num_channels: 0, limbo_balance: 0}, waiting_close: {num_channels: 0, limbo_balance: 0}, total_channels: 0, total_limbo_balance: 0};
if (channels) {
pendingChannels = 0;
if (channels.pending_closing_channels) {
pendingChannels = pendingChannels + channels.pending_closing_channels.length;
pendingChannels.closing.num_channels = channels.pending_closing_channels.length;
pendingChannels.total_channels = pendingChannels.total_channels + channels.pending_closing_channels.length;
channels.pending_closing_channels.forEach(closingChannel => {
pendingChannels.closing.limbo_balance = pendingChannels.closing.limbo_balance + closingChannel.channel.local_balance;
});
}
if (channels.pending_force_closing_channels) {
pendingChannels = pendingChannels + channels.pending_force_closing_channels.length;
pendingChannels.force_closing.num_channels = channels.pending_force_closing_channels.length;
pendingChannels.total_channels = pendingChannels.total_channels + channels.pending_force_closing_channels.length;
channels.pending_force_closing_channels.forEach(closingChannel => {
pendingChannels.force_closing.limbo_balance = pendingChannels.force_closing.limbo_balance + closingChannel.channel.local_balance;
});
}
if (channels.pending_open_channels) {
pendingChannels = pendingChannels + channels.pending_open_channels.length;
pendingChannels.open.num_channels = channels.pending_open_channels.length;
pendingChannels.total_channels = pendingChannels.total_channels + channels.pending_open_channels.length;
channels.pending_open_channels.forEach(openingChannel => {
pendingChannels.open.limbo_balance = pendingChannels.open.limbo_balance + openingChannel.channel.local_balance;
});
}
if (channels.waiting_close_channels) {
pendingChannels = pendingChannels + channels.waiting_close_channels.length;
pendingChannels.waiting_close.num_channels = channels.waiting_close_channels.length;
pendingChannels.total_channels = pendingChannels.total_channels + channels.waiting_close_channels.length;
channels.waiting_close_channels.forEach(closingChannel => {
pendingChannels.waiting_close.limbo_balance = pendingChannels.waiting_close.limbo_balance + closingChannel.channel.local_balance;
});
}
}
this.store.dispatch(new RTLActions.SetNodePendingChannelsData(pendingChannels));
return {
type: RTLActions.SET_PENDING_CHANNELS,
payload: channels ? { channels: channels, pendingChannels: pendingChannels } : {channels: {}, pendingChannels: pendingChannels}
@ -1073,8 +1087,7 @@ export class LNDEffects implements OnDestroy {
uris: info.uris,
version: info.version,
currency_unit: info.currency_unit,
smaller_currency_unit: info.smaller_currency_unit,
numberOfPendingChannels: info.num_pending_channels
smaller_currency_unit: info.smaller_currency_unit
};
this.store.dispatch(new RTLActions.SetNodeData(node_data));
this.store.dispatch(new RTLActions.FetchFees());

@ -1,7 +1,7 @@
import { SelNodeChild } from '../../shared/models/RTLconfig';
import { ErrorPayload } from '../../shared/models/errorPayload';
import {
GetInfo, Peer, Fees, NetworkInfo, Balance, Channel, Payment, ListInvoices, PendingChannels, ClosedChannel, Transaction, SwitchRes, QueryRoutes
GetInfo, Peer, Fees, NetworkInfo, Balance, Channel, Payment, ListInvoices, PendingChannels, ClosedChannel, Transaction, SwitchRes, PendingChannelsGroup
} from '../../shared/models/lndModels';
import * as RTLActions from '../../store/rtl.actions';
import { UserPersonaEnum } from '../../shared/services/consts-enums-functions';
@ -20,7 +20,7 @@ export interface LNDState {
pendingChannels: PendingChannels;
numberOfActiveChannels: number;
numberOfInactiveChannels: number;
numberOfPendingChannels: number;
numberOfPendingChannels: PendingChannelsGroup;
totalCapacityActive: number;
totalCapacityInactive: number;
totalLocalBalance: number;
@ -46,7 +46,7 @@ export const initLNDState: LNDState = {
pendingChannels: {},
numberOfActiveChannels: 0,
numberOfInactiveChannels: 0,
numberOfPendingChannels: -1,
numberOfPendingChannels: { open: {num_channels: 0, limbo_balance: 0}, closing: {num_channels: 0, limbo_balance: 0}, force_closing: {num_channels: 0, limbo_balance: 0}, waiting_close: {num_channels: 0, limbo_balance: 0}, total_channels: 0, total_limbo_balance: 0},
totalCapacityActive: 0,
totalCapacityInactive: 0,
totalLocalBalance: -1,

@ -20,7 +20,7 @@
<div fxFlex="23" 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 fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between start" *ngIf="showDetails">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between start" *ngIf="showDetails" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="5" type="reset" (click)="resetData()">Clear Field</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" [disabled]="addInvoiceForm.form.invalid" (click)="onAddInvoice(addInvoiceForm)" tabindex="6">
<p *ngIf="addInvoiceForm.form.invalid; else createText">Invalid values</p>

@ -3,7 +3,7 @@
<mat-form-field class="w-100">
<input matInput placeholder="Payment Request" name="paymentRequest" [(ngModel)]="paymentRequest" tabindex="1" required #paymentReq="ngModel">
</mat-form-field>
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" *ngIf="showDetails">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" *ngIf="showDetails" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" [disabled]="paymentReq.invalid" (click)="onSendPayment();" tabindex="3">
<p *ngIf="paymentReq.invalid && (paymentReq.dirty || paymentReq.touched); else sendText">Invalid Req</p>

@ -6,7 +6,7 @@
<mat-form-field fxFlex="29" fxLayoutAlign="start end">
<input matInput placeholder="Amount (Sats)" name="amount" [(ngModel)]="amount" tabindex="2" type="number" step="1000" min="0" required #destAmount="ngModel">
</mat-form-field>
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="3" type="reset" (click)="resetData()">Clear</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" [disabled]="destPubkey.invalid || destAmount.invalid" type="submit" tabindex="4">
<p *ngIf="(destPubkey.invalid && (destPubkey.dirty || destPubkey.touched) || (destAmount.invalid && (destAmount.dirty || destAmount.touched))); else queryText">Invalid Pubkey/Amount</p>

@ -4,7 +4,7 @@
<input matInput type="password" placeholder="Password" name="walletPassword" [(ngModel)]="walletPassword" tabindex="1" required>
<mat-hint>Enter Wallet Password</mat-hint>
</mat-form-field>
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear Field</button>
<button mat-raised-button fxFlex="48" color="primary" [disabled]="walletPassword == ''" (click)="onUnlockWallet()" tabindex="3">Unlock Wallet</button>
</div>

@ -90,7 +90,7 @@
<ng-template #openText><p>Open Channel</p></ng-template>
</button>
</div>
<div *ngIf="!newlyAdded" fxLayout="row" fxLayoutAlign="space-between stretch" fxFlex="30">
<div *ngIf="!newlyAdded" fxLayout="row" fxLayoutAlign="space-between stretch" fxFlex="30" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Field</button>
<button autoFocus fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onOpenChannel()" [disabled]="fundingAmount == null || (totalBalance - ((fundingAmount) ? fundingAmount : 0) < 0)" type="submit" tabindex="8">
<p *ngIf="(fundingAmount == null) && (amount.touched || amount.dirty); else openText">Invalid Values</p>

@ -38,7 +38,6 @@ export class HorizontalNavigationComponent implements OnInit, OnDestroy {
this.information = rtlStore.nodeData;
this.appConfig = rtlStore.appConfig;
this.selNode = rtlStore.selNode;
this.numPendingChannels = rtlStore.nodeData.numberOfPendingChannels;
if(this.selNode.lnImplementation.toUpperCase() === 'CLT') {
this.menuNodes = MENU_DATA.CLChildren;
} else {

@ -71,7 +71,6 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
this.selNode = rtlStore.selNode;
this.settings = this.selNode.settings;
this.information = rtlStore.nodeData;
this.numPendingChannels = rtlStore.nodeData.numberOfPendingChannels;
if (undefined !== this.information.identity_pubkey) {
if (undefined !== this.information.chains && typeof this.information.chains[0] === 'string') {

@ -1,47 +1,68 @@
<div fxLayout="column" fxFlex="100" class="overflow-x-hidden">
<div fxLayout="column" class="settings-container mt-1">
<div fxLayout="column" fxLayoutAlign="start stretch" class="settings-container page-sub-title-container mt-1">
<div fxFlex="100" class="mb-2">
<fa-icon [icon]="faWrench" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Node Layout</span>
</div>
<div fxLayout="column" fxLayout.gt-sm="row" fxFlex="100" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="32" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selNode.settings.userPersona" placeholder="User Persona" tabindex="1" required name="userPersona">
<mat-label>User Persona</mat-label>
<mat-select [(ngModel)]="selNode.settings.userPersona" tabindex="1" required name="userPersona">
<mat-option *ngFor="let userPersona of userPersonas" [value]="userPersona">
{{userPersona | titlecase}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="32" fxLayoutAlign="start end" *ngIf="appConfig.nodes.length && appConfig.nodes.length > 1">
<mat-select [(ngModel)]="appConfig.defaultNodeIndex" placeholder="Default Node" tabindex="1" required name="defaultNode">
<mat-option *ngFor="let node of appConfig.nodes" [value]="node.index">
{{node.lnNode}} ({{node.lnImplementation}})
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="32" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selNode.settings.currencyUnit" placeholder="Currency Unit" (selectionChange)="onCurrencyChange($event)" tabindex="1" required name="currencyUnit">
<mat-label>Currency Unit</mat-label>
<mat-select [(ngModel)]="selNode.settings.currencyUnit" (selectionChange)="onCurrencyChange($event)" tabindex="1" required name="currencyUnit">
<mat-option *ngFor="let currencyUnit of currencyUnits" [value]="currencyUnit.id">
{{currencyUnit.id}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="32" fxLayoutAlign="start end" *ngIf="appConfig.nodes.length && appConfig.nodes.length > 1">
<mat-label>Default Node</mat-label>
<mat-select [(ngModel)]="appConfig.defaultNodeIndex" tabindex="1" required name="defaultNode">
<mat-option *ngFor="let node of appConfig.nodes" [value]="node.index">
{{node.lnNode}} ({{node.lnImplementation}})
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxFlex="100" class="alert alert-info">
<fa-icon [icon]="faInfoCircle" class="mr-1"></fa-icon>
<span>Application layout will be tailored based upon user persona, this will affect the information displayed.</span>
</div>
<div fxLayout="column" fxLayout.gt-sm="row" fxFlex="100" fxLayoutAlign="start stretch" class="mt-1">
<div fxLayout="column" fxFlex="25" fxLayoutAlign="start start" fxLayoutAlign.gt-sm="start space-between">
<h4>Mode</h4>
<mat-radio-group color="primary" [(ngModel)]="selectedThemeMode" (change)="chooseThemeMode()">
<mat-radio-button *ngFor="let themeMode of themeModes" [value]="themeMode" [ngClass]="{'mr-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">{{themeMode.name}}
</mat-radio-button>
</mat-radio-group>
</div>
<div fxLayout="column" fxFlex="9"></div>
<div fxLayout="column" fxFlex="40">
<h4>Skins</h4>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between start">
<span *ngFor="let themeColor of themeColors">
<div [class]="themeColor" [ngClass]="{'skin': true, 'selected-color': selectedThemeColor === themeColor}" (click)="changeThemeColor(themeColor)"></div>
</span>
<mat-divider class="w-100"></mat-divider>
<div fxLayout="column" fxLayoutAlign="space-between stretch" class="settings-container page-sub-title-container mt-1 w-100">
<div fxFlex="100" class="my-1">
<fa-icon [icon]="faPaintBrush" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Customization</span>
</div>
<div fxLayout="column" fxLayout.gt-xs="row" fxFlex="100" fxLayoutAlign="space-between stretch" fxLayoutAlign.gt-xs="start stretch">
<div fxFlex.gt-xs="20" fxFlex.gt-md="15" fxLayout="column" fxLayoutAlign="space-between stretch">
<h4>Theme</h4>
<mat-radio-group color="primary" [(ngModel)]="selectedThemeMode" (change)="chooseThemeMode()">
<mat-radio-button *ngFor="let themeMode of themeModes" [value]="themeMode" [ngClass]="{'mr-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">{{themeMode.name}}
</mat-radio-button>
</mat-radio-group>
</div>
<div fxLayout="column" fxFlex.gt-xs="20" fxFlex.gt-md="15" fxLayoutAlign="space-between stretch"></div>
<div fxLayout="column" fxFlex.gt-xs="50" fxFlex.gt-md="30" fxLayoutAlign="space-between stretch">
<h4>Colors</h4>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between start">
<span *ngFor="let themeColor of themeColors" fxLayout="row">
<div [class]="themeColor" [ngClass]="{'skin': true, 'selected-color': selectedThemeColor === themeColor}" (click)="changeThemeColor(themeColor)"></div>
{{themeColor | titlecase}}
</span>
</div>
</div>
</div>
</div>
</div>
<div fxLayout="row" fxFlex="100" class="mt-4">
<div fxLayout="row" fxFlex="100" class="mt-2">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" (click)="onResetSettings()" tabindex="12">Reset</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onUpdateSettings()" tabindex="13">Update</button>

@ -2,6 +2,7 @@ import { Component, OnInit, OnDestroy, Output, EventEmitter } from '@angular/cor
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { faWrench, faPaintBrush, faInfoCircle } from '@fortawesome/free-solid-svg-icons';
import { CURRENCY_UNITS, UserPersonaEnum, ScreenSizeEnum, FIAT_CURRENCY_UNITS } from '../../../services/consts-enums-functions';
import { LightningNode, Settings, RTLConfiguration, GetInfoRoot } from '../../../models/RTLconfig';
@ -17,6 +18,9 @@ import * as fromRTLReducer from '../../../../store/rtl.reducers';
styleUrls: ['./app-settings.component.scss']
})
export class AppSettingsComponent implements OnInit, OnDestroy {
public faWrench = faWrench;
public faPaintBrush = faPaintBrush;
public faInfoCircle = faInfoCircle;
public selNode: LightningNode;
public information: GetInfoRoot = {};
public userPersonas = [UserPersonaEnum.OPERATOR, UserPersonaEnum.MERCHANT];

@ -1,6 +1,6 @@
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
<fa-icon [icon]="faTools" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Settings</span>
<span class="page-title">Global Settings</span>
</div>
<div fxLayout="column" class="padding-gap-x">
<mat-card>

@ -5,7 +5,6 @@ import { Store } from '@ngrx/store';
import { faTools } from '@fortawesome/free-solid-svg-icons';
import { LightningNode } from '../../models/RTLconfig';
import { RTLEffects } from '../../../store/rtl.effects';
import * as fromRTLReducer from '../../../store/rtl.reducers';
@Component({

@ -12,7 +12,7 @@
tabindex="1" required>
<mat-hint>{{hintStr}}</mat-hint>
</mat-form-field>
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="30" fxLayoutAlign="space-between stretch" class="mt-2">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" tabindex="2" type="reset" (click)="resetData()">Clear</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="3" type="submit" [disabled]="!password">Login</button>
</div>

@ -63,7 +63,6 @@ export interface GetInfoRoot {
version?: string;
currency_unit?: string;
smaller_currency_unit?: string;
numberOfPendingChannels?: number;
}
export interface SelNodeChild {

@ -7,7 +7,7 @@ export interface ChannelsStatus {
active?: ChannelStatus;
inactive?: ChannelStatus;
pending?: ChannelStatus;
closed?: ChannelStatus;
closing?: ChannelStatus;
}
export interface AddressType {
@ -387,3 +387,17 @@ export interface SwitchRes {
last_offset_index?: number;
forwarding_events?: ForwardingEvent[];
}
export interface PendingChannelsGroup {
open?: PendingChannelsData;
closing?: PendingChannelsData;
force_closing?: PendingChannelsData;
waiting_close?: PendingChannelsData;
total_channels?: number;
total_limbo_balance?: number;
}
export interface PendingChannelsData {
num_channels: number;
limbo_balance: number;
}

@ -1,4 +1,4 @@
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faArchive, faProjectDiagram, faNetworkWired, faCog, faQuestion, faSearch, faTools } from '@fortawesome/free-solid-svg-icons';
import { faTachometerAlt, faLink, faBolt, faExchangeAlt, faUsers, faArchive, faProjectDiagram, faNetworkWired, faCog, faQuestion, faSearch, faTools, faServer } from '@fortawesome/free-solid-svg-icons';
export const MENU_DATA: MenuRootNode = {
LNDChildren: [
@ -9,11 +9,11 @@ export const MENU_DATA: MenuRootNode = {
{id: 32, parentId: 3, name: 'Transactions', iconType: 'FA', icon: faExchangeAlt, link: '/lnd/transactions'},
{id: 33, parentId: 3, name: 'Backup', iconType: 'FA', icon: faArchive, link: '/lnd/backup'},
{id: 34, parentId: 3, name: 'Routing', iconType: 'FA', icon: faProjectDiagram, link: '/lnd/routing'},
{id: 35, parentId: 3, name: 'Graph Lookup', iconType: 'FA', icon: faSearch, link: '/lnd/lookups'},
{id: 36, parentId: 3, name: 'Network', iconType: 'FA', icon: faNetworkWired, link: '/lnd/network'}
{id: 35, parentId: 3, name: 'Graph Lookup', iconType: 'FA', icon: faSearch, link: '/lnd/lookups'}
]},
{id: 5, parentId: 0, name: 'Settings', iconType: 'FA', icon: faTools, link: '/settings'},
{id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help'}
{id: 5, parentId: 0, name: 'Node/Network', iconType: 'FA', icon: faServer, link: '/lnd/network'},
{id: 6, parentId: 0, name: 'Settings', iconType: 'FA', icon: faTools, link: '/settings'},
{id: 7, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help'}
],
CLChildren: [
{id: 1, parentId: 0, name: 'Home', icon: 'home', link: '/cl/home'},

@ -1,15 +1,15 @@
@import './color-swatches/light-dull-theme.scss';
@import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming';
@include mat-core();
$blue-primary: mat-palette($mat-blue, 700, 200, A200);
$blue-accent: mat-palette($mat-pink, A200, A100, A400);
$blue-accent-night: mat-palette($mat-white, 300, 600, 900);
$blue-warn: mat-palette($red-warn, 500);
// $blue-day-theme: create-light-dull-theme($blue-primary, $blue-accent, $blue-warn);
$blue-night-theme: create-dark-bright-theme($blue-primary, $blue-accent, $blue-warn);
$blue-night-theme: create-dark-bright-theme($blue-primary, $blue-accent-night, $blue-warn);
$blue-day-theme: mat-light-theme($blue-primary, $blue-accent, $blue-warn);
// $blue-night-theme: mat-dark-theme($blue-primary, $blue-accent, $blue-warn);

@ -0,0 +1,32 @@
$mat-white: (
50 : #ffffff,
100 : #ffffff,
200 : #eeeeee,
300 : #eeeeee,
400 : #bbbbbb,
500 : #aaaaaa,
600 : #999999,
700 : #888888,
800 : #777777,
900 : #666666,
A100 : #555555,
A200 : #444444,
A400 : #333333,
A700 : #222222,
contrast: (
50 : #000000,
100 : #000000,
200 : #000000,
300 : #000000,
400 : #000000,
500 : #000000,
600 : #000000,
700 : #000000,
800 : #000000,
900 : #000000,
A100 : #000000,
A200 : #000000,
A400 : #000000,
A700 : #000000,
)
);

@ -2,15 +2,15 @@
@import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/green-primary.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming';
@include mat-core();
$green-primary: mat-palette($green-primary, 500, 300, A200);
$green-accent: mat-palette($mat-amber, A200, A100, A700);
$green-accent-night: mat-palette($mat-white, 300, 600, 900);
$green-warn: mat-palette($red-warn, 500);
// $green-day-theme: create-light-dull-theme($green-primary, $green-accent, $green-warn);
$green-night-theme: create-dark-bright-theme($green-primary, $green-accent, $green-warn);
$green-night-theme: create-dark-bright-theme($green-primary, $green-accent-night, $green-warn);
$green-day-theme: mat-light-theme($green-primary, $green-accent, $green-warn);
// $green-night-theme: mat-dark-theme($green-primary, $green-accent, $green-warn);

@ -1,16 +1,16 @@
@import './color-swatches/light-dull-theme.scss';
@import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming';
@include mat-core();
$indigo-primary: mat-palette($mat-indigo, 500, 200, A200);
$indigo-accent: mat-palette($mat-pink, A200, A100, A400);
$indigo-accent-night: mat-palette($mat-white, 300, 600, 900);
$indigo-warn: mat-palette($red-warn, 500);
// $indigo-day-theme: create-light-dull-theme($indigo-primary, $indigo-accent, $indigo-warn);
$indigo-night-theme: create-dark-bright-theme($indigo-primary, $indigo-accent, $indigo-warn);
$indigo-night-theme: create-dark-bright-theme($indigo-primary, $indigo-accent-night, $indigo-warn);
$indigo-day-theme: mat-light-theme($indigo-primary, $indigo-accent, $indigo-warn);
// $indigo-night-theme: mat-dark-theme($indigo-primary, $indigo-accent, $indigo-warn);

@ -1,15 +1,15 @@
@import './color-swatches/light-dull-theme.scss';
@import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming';
@include mat-core();
$pink-primary: mat-palette($mat-pink, 500, 300, A200);
$pink-accent: mat-palette($mat-blue-grey, 700, 500, 900);
$pink-accent-night: mat-palette($mat-white, 300, 600, 900);
$pink-warn: mat-palette($red-warn, 500);
// $pink-day-theme: create-light-dull-theme($pink-primary, $pink-accent, $pink-warn);
$pink-night-theme: create-dark-bright-theme($pink-primary, $pink-accent, $pink-warn);
$pink-night-theme: create-dark-bright-theme($pink-primary, $pink-accent-night, $pink-warn);
$pink-day-theme: mat-light-theme($pink-primary, $pink-accent, $pink-warn);
// $pink-night-theme: mat-dark-theme($pink-primary, $pink-accent, $pink-warn);

@ -2,15 +2,15 @@
@import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/purple-primary.swatch.scss';
@import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming';
@include mat-core();
$purple-primary: mat-palette($purple-primary, 500, 300, A200);
$purple-accent: mat-palette($mat-gray, 800, 600, 900);
$purple-accent-night: mat-palette($mat-white, 300, 600, 900);
$purple-warn: mat-palette($red-warn, 500);
// $purple-day-theme: create-light-dull-theme($purple-primary, $purple-accent, $purple-warn);
$purple-night-theme: create-dark-bright-theme($purple-primary, $purple-accent, $purple-warn);
$purple-night-theme: create-dark-bright-theme($purple-primary, $purple-accent-night, $purple-warn);
$purple-day-theme: mat-light-theme($purple-primary, $purple-accent, $purple-warn);
// $purple-night-theme: mat-dark-theme($purple-primary, $purple-accent, $purple-warn);

@ -1,15 +1,15 @@
@import './color-swatches/light-dull-theme.scss';
@import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming';
@include mat-core();
$teal-primary: mat-palette($mat-teal, 800, 300, A200);
$teal-accent: mat-palette($mat-amber, A200, A100, A700);
$teal-accent-night: mat-palette($mat-white, 300, 600, 900);
$teal-warn: mat-palette($red-warn, 500);
// $teal-day-theme: create-light-dull-theme($teal-primary, $teal-accent, $teal-warn);
$teal-night-theme: create-dark-bright-theme($teal-primary, $teal-accent, $teal-warn);
$teal-night-theme: create-dark-bright-theme($teal-primary, $teal-accent-night, $teal-warn);
$teal-day-theme: mat-light-theme($teal-primary, $teal-accent, $teal-warn);
// $teal-night-theme: mat-dark-theme($teal-primary, $teal-accent, $teal-warn);

@ -10,11 +10,11 @@
$warn: map-get($theme, warn);
$warn-color: mat-color($warn);
$foreground: map-get($theme, foreground);
$foreground-base: mat-color($foreground, base);
$foreground-text: mat-color($foreground, text);
$foreground-secondary-text: mat-color($foreground, secondary-text);
$foreground-disabled: mat-color($foreground, disabled);
$foreground-divider: mat-color($foreground, divider);
$foreground-base: mat-color($foreground, base); // 1
$foreground-text: mat-color($foreground, text); //.87
$foreground-secondary-text: mat-color($foreground, secondary-text); // .54
$foreground-disabled: mat-color($foreground, disabled); // .38
$foreground-divider: mat-color($foreground, divider); // .12
$background: map-get($theme, background);
$background-color: mat-color($background, card);
$hover-background: rgba(0, 0, 0, 0.04);
@ -101,6 +101,50 @@
.mat-tab-label, .mat-tab-link {
color: $foreground-secondary-text;
}
.dashboard-card .mat-card-header .mat-card-title {
font-size: 180%;
color: $foreground-text;
& .ng-fa-icon {
color: $foreground-text;
}
}
& .dashboard-info-value {
font-weight: 700;
color: $foreground-text;
}
& .dashboard-capacity-header {
color: $foreground-text;
}
.alert.alert-info {
border: 1px solid $primary-darker;
background-color: $hover-background-white;
color: $primary-darker;
& .ng-fa-icon {
fill: $primary-darker;
color: $primary-darker;
}
}
.alert.alert-warn {
border: 1px solid #856404;
background-color: #fff3cd;
color: #856404;
& .ng-fa-icon {
fill: #856404;
color: #856404;
}
}
.alert.alert-danger {
border: 1px solid $warn-color;
background-color: mat-color($warn, 50);
color: $warn-color;
& .ng-fa-icon {
fill: $warn-color;
color: $warn-color;
}
}
}
&.day {
@ -181,12 +225,34 @@
box-shadow: none;
border: 1px solid $foreground-divider;
}
.dashboard-card .mat-card-header .mat-card-title {
font-size: 180%;
color: $foreground-disabled;
& .ng-fa-icon {
color: $foreground-disabled;
}
}
& .dashboard-info-value {
font-weight: 700;
color: $foreground-secondary-text;
}
}
.color-primary {
color: $primary-color;
}
.mat-progress-bar-buffer {
background-color: mat-color($primary, 100);
}
.foreground-text {
color: $foreground-text !important;
white-space: pre-line;
overflow-wrap: break-word;
word-break: break-all;
}
.foreground-secondary-text {
color: $foreground-secondary-text !important;
white-space: pre-line;
@ -447,4 +513,61 @@
}
}
.dashboard-card {
& .dashboard-divider {
margin-top: 2rem;
border-top-width: 2px;
}
& .mat-card-header .mat-card-title {
margin-bottom: 2.4rem;
}
& .dashboard-info-title {
font-weight: 500;
color: $primary-color;
}
& .dashboard-node-dot {
margin: 0 0 -2px 1rem;
border: 1px solid $foreground-secondary-text;
}
& .dashboard-capacity-header {
font-size: 130%;
font-weight: 700;
color: $foreground-secondary-text;
}
}
.alert.alert-info {
border: 1px solid $primary-color;
background-color: mat-color($primary, 50);
color: $primary-color;
& .ng-fa-icon {
fill: $primary-color;
color: $primary-color;
}
}
.alert.alert-warn {
border: 1px solid #856404;
background-color: #fff3cd;
color: #856404;
& .ng-fa-icon {
fill: #856404;
color: #856404;
}
}
.alert.alert-danger {
border: 1px solid $warn-color;
background-color: mat-color($warn, 50);
color: $warn-color;
& .ng-fa-icon {
fill: $warn-color;
color: $warn-color;
}
}
}

@ -502,6 +502,10 @@ body {
padding: 2rem !important;
}
.p-24 {
padding: 2.4rem !important;
}
.m-1px {
margin: 1px !important;
}
@ -602,14 +606,14 @@ body {
margin: 1.2rem 0 0.6rem 0;
}
.skin{
width: 4rem;
height: 4rem;
width: 2rem;
height: 2rem;
border-radius: 50%;
margin-right: 1rem;
cursor: pointer;
margin-right: 0.5rem;
&.selected-color {
width: 3.75rem;
height: 3.75rem;
width: 1.75rem;
height: 1.75rem;
border: 0.25rem solid;
}
&.purple{
@ -774,6 +778,10 @@ a {
font-weight: 500 !important;
}
.font-bold-700 {
font-weight: 700 !important;
}
.qr-border img {
border: 1.2rem solid white;
}
@ -850,8 +858,7 @@ table {
width: $tiny-dot-size;
height: $tiny-dot-size;
border-radius: $tiny-dot-size;
margin-right: 0.6rem;
margin-bottom: 0.2rem;
margin: 0 0.6rem 0.1rem 0;
}
&.green {
background-color: $green-color;
@ -871,6 +878,10 @@ table {
font-size: 80% !important;
}
.font-size-90 {
font-size: 90% !important;
}
.font-weight-900 {
font-weight: 900 !important;
}
@ -903,3 +914,13 @@ table {
@-webkit-keyframes blink-animation { to { visibility: hidden; }}
.mat-progress-bar.dashboard-progress-bar {
height: 6px;
min-height: 6px;
}
.alert {
margin-bottom: 1rem;
padding: 1.2rem 2rem;
border-radius: 4px;
}

@ -6,7 +6,7 @@ import { RTLConfiguration, Settings, LightningNode, GetInfoRoot, SelNodeChild }
import { GetInfoCL, FeesCL, AddressTypeCL, PeerCL, PaymentCL, PayRequestCL, QueryRoutesCL, ChannelCL, FeeRatesCL, ForwardingHistoryResCL, InvoiceCL, ListInvoicesCL, OnChainCL } from '../shared/models/clModels';
import {
GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode, AddressType,
PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes
PayRequest, ChannelsTransaction, PendingChannels, ClosedChannel, Transaction, SwitchReq, SwitchRes, QueryRoutes, PendingChannelsGroup
} from '../shared/models/lndModels';
export const VOID = 'VOID';
@ -29,7 +29,6 @@ export const SET_RTL_CONFIG = 'SET_RTL_CONFIG';
export const SAVE_SETTINGS = 'SAVE_SETTINGS';
export const SET_SELECTED_NODE = 'SET_SELECTED_NODE';
export const SET_NODE_DATA = 'SET_NODE_DATA';
export const SET_NODE_PENDING_CHANNELS_DATA = 'SET_NODE_PENDING_CHANNELS_DATA';
export const RESET_LND_STORE = 'RESET_LND_STORE';
export const CLEAR_EFFECT_ERROR_LND = 'CLEAR_EFFECT_ERROR_LND';
@ -268,11 +267,6 @@ export class SetNodeData implements Action {
constructor(public payload: GetInfoRoot) {}
}
export class SetNodePendingChannelsData implements Action {
readonly type = SET_NODE_PENDING_CHANNELS_DATA;
constructor(public payload: number) {}
}
export class SetChildNodeSettings implements Action {
readonly type = SET_CHILD_NODE_SETTINGS;
constructor(public payload: SelNodeChild) {}
@ -370,7 +364,7 @@ export class FetchPendingChannels implements Action {
export class SetPendingChannels implements Action {
readonly type = SET_PENDING_CHANNELS;
constructor(public payload: {channels: PendingChannels, pendingChannels: number}) {}
constructor(public payload: {channels: PendingChannels, pendingChannels: PendingChannelsGroup}) {}
}
export class FetchClosedChannels implements Action {
@ -833,7 +827,7 @@ export type RTLActions =
VoidAction | OpenSnackBar | OpenSpinner | CloseSpinner | FetchRTLConfig | SetRTLConfig | SaveSettings |
OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation | ShowPubkey |
UpdateSelectedNodeOptions | ResetRootStore | ResetLNDStore | ResetCLStore |
SetSelelectedNode | SetNodeData | SetNodePendingChannelsData | SetChildNodeSettings | FetchInfo | SetInfo |
SetSelelectedNode | SetNodeData | SetChildNodeSettings | FetchInfo | SetInfo |
FetchPeers | SetPeers | AddPeer | DetachPeer | SaveNewPeer | RemovePeer |
AddInvoice | SaveNewInvoice | GetForwardingHistory | SetForwardingHistory |
FetchFees | SetFees |

@ -63,13 +63,6 @@ export function RootReducer(state = initRootState, action: RTLActions.RTLActions
...state,
nodeData: action.payload
};
case RTLActions.SET_NODE_PENDING_CHANNELS_DATA:
const newNodeData = state.nodeData;
newNodeData.numberOfPendingChannels = action.payload;
return {
...state,
nodeData: newNodeData
};
case RTLActions.SET_RTL_CONFIG:
return {
...state,

Loading…
Cancel
Save