dashboard and settings

dashboard and settings
pull/260/head
Shahana Farooqui 5 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="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="icon" type="image/png" sizes="16x16" href="assets/images/favicon/favicon-16x16.png">
<link rel="manifest" href="assets/images/favicon/site.webmanifest"> <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> <body>
<rtl-app></rtl-app> <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> </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"> tabindex="1" required #paymentReq="ngModel">
</mat-form-field> </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-raised-button color="primary" <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary"
[disabled]="paymentReq.invalid" (click)="onSendPayment()" tabindex="2"> [disabled]="paymentReq.invalid" (click)="onSendPayment()" tabindex="2">
<p *ngIf="paymentReq.invalid && (paymentReq.dirty || paymentReq.touched); else sendText">Invalid Req</p> <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 fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
<div fxFlex="33"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Lightning</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Lightning</h4>
<div class="foreground-secondary-text">{{balances.lightning | number}} (Sats)</div> <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>
<div fxFlex="25" fxLayoutAlign="start start"></div> <div>
<div fxFlex="33"> <h4 fxLayoutAlign="start" class="dashboard-info-title">On-chain</h4>
<h4 fxLayoutAlign="start" class="font-bold-500">On-chain</h4> <div class="dashboard-info-value">{{balances.onchain | number}} Sats</div>
<div class="foreground-secondary-text">{{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>
<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> </div>

@ -1,27 +1,13 @@
import { Component, OnChanges, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
@Component({ @Component({
selector: 'rtl-balances-info', selector: 'rtl-balances-info',
templateUrl: './balances-info.component.html', templateUrl: './balances-info.component.html',
styleUrls: ['./balances-info.component.scss'] styleUrls: ['./balances-info.component.scss']
}) })
export class BalancesInfoComponent implements OnChanges { export class BalancesInfoComponent {
@Input() balances = { onchain: 0, lightning: 0 }; @Input() balances = { onchain: 0, lightning: 0, total: 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];
constructor() {} 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" fxLayoutAlign="space-between stretch" fxFlex="100">
<div fxLayout="column" fxFlex="5" fxLayoutAlign="start start" class="w-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"> <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="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-80"><strong class="font-weight-900">Remote:</strong>{{channelBalances.remoteBalance || 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> </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> <mat-divider class="w-100 dashboard-divider"></mat-divider>
</div> </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 fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<div *ngFor="let channel of allChannels" class="mt-2"> <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"> <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="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-80"><strong class="font-weight-900">Remote:</strong>{{channel.remote_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> </div>
<mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channel.balancedness}}"></mat-progress-bar> <mat-progress-bar class="dashboard-progress-bar" mode="determinate" value="{{channel.balancedness}}"></mat-progress-bar>
</div> </div>
@ -23,26 +24,3 @@
<ng-template #noChannelBlock> <ng-template #noChannelBlock>
<div fxLayout="column" fxFlex="100" class="w-100 mt-2">No channels available.</div> <div fxLayout="column" fxFlex="100" class="w-100 mt-2">No channels available.</div>
</ng-template> </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 { .channels-capacity-scroll {
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow-y: hidden; overflow-y: hidden;
} }

@ -1,16 +1,23 @@
<div fxLayout="column" fxLayoutAlign="space-between start" fxFlex="100"> <div fxLayout="column" fxLayoutAlign="space-between stretch" fxFlex="100">
<div fxLayout="column" fxFlex="9" fxLayoutAlign="end start" class="w-100"> <div fxLayout="column" fxFlex="10" fxLayoutAlign="end stretch">
<h2>{{totalLiquidity | number}} Sats</h2> <div fxLayout="row" fxLayoutAlign="space-between start">
<h4>Max Transaction Amount: {{(maxAmount <= 4294967 ? maxAmount : 4294967) | number}} Sats</h4> <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> <mat-divider class="w-100 dashboard-divider mt-2"></mat-divider>
</div> </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 fxLayout="column" fxFlex="100" class="w-100" *ngIf="allChannels && allChannels.length > 0; else noChannelBlock">
<div *ngFor="let channel of allChannels" class="mt-2"> <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"> <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 === '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-80"><strong class="font-weight-900">{{channel.local_balance || 0 | number}} Sats</strong></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> </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 === '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> <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() { ngOnChanges() {
if (this.allChannels && this.allChannels.length > 0) { if (this.allChannels && this.allChannels.length > 0) {
if(this.direction === 'In') { 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 { } 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 fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div fxFlex="33"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Active</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Active</h4>
<div class="foreground-secondary-text"><span class="dot tiny-dot green"></span>{{(channelsStatus.active.channels || 0) | number}}</div> <div class="dashboard-info-value"><span class="dot tiny-dot green"></span>{{(channelsStatus.active.channels || 0) | number}}</div>
</div> </div>
<div fxFlex="33"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Pending</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Pending</h4>
<div class="foreground-secondary-text"><span class="dot tiny-dot yellow"></span>{{(channelsStatus.pending.channels || 0) | number}}</div> <div class="dashboard-info-value"><span class="dot tiny-dot yellow"></span>{{(channelsStatus.pending.channels || 0) | number}}</div>
</div> </div>
<div fxFlex="34"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Inactive</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Inactive</h4>
<div class="foreground-secondary-text"><span class="dot tiny-dot red"></span>{{(channelsStatus.inactive.channels || 0) | number}}</div> <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> </div>
<div fxLayout="column" fxFlex="50" fxLayoutAlign="center start"> <div fxLayout="column" fxFlex="50" fxLayoutAlign="space-between stretch">
<div fxFlex="33"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Capacity</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="foreground-secondary-text">{{(channelsStatus.active.capacity || 0) | number}} (Sats)</div> <div class="dashboard-info-value">{{(channelsStatus.active.capacity || 0) | number}} Sats</div>
</div> </div>
<div fxFlex="33"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Capacity</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="foreground-secondary-text">{{(channelsStatus.pending.capacity || 0) | number}} (Sats)</div> <div class="dashboard-info-value">{{(channelsStatus.pending.capacity || 0) | number}} Sats</div>
</div> </div>
<div fxFlex="34"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Capacity</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Capacity</h4>
<div class="foreground-secondary-text">{{(channelsStatus.inactive.capacity || 0) | number}} (Sats)</div> <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>
</div> </div>

@ -1,22 +1,14 @@
<div fxLayout="column" fxFlex="60" fxLayoutAlign="center start"> <div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between stretch">
<div fxFlex="33"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Daily</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Daily</h4>
<div class="foreground-secondary-text">{{fees?.day_fee_sum | number}} (Sats)</div> <div class="dashboard-info-value">{{fees?.day_fee_sum | number}} Sats</div>
</div> </div>
<div fxFlex="33"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Weekly</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Weekly</h4>
<div class="foreground-secondary-text">{{fees?.week_fee_sum | number}} (Sats)</div> <div class="dashboard-info-value">{{fees?.week_fee_sum | number}} Sats</div>
</div> </div>
<div fxFlex="33"> <div>
<h4 fxLayoutAlign="start" class="font-bold-500">Monthly</h4> <h4 fxLayoutAlign="start" class="dashboard-info-title">Monthly</h4>
<div class="foreground-secondary-text">{{fees?.month_fee_sum | number}} (Sats)</div> <div class="dashboard-info-value">{{fees?.month_fee_sum | number}} Sats</div>
</div> </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 { export class FeeInfoComponent implements OnChanges {
@Input() fees: Fees; @Input() fees: Fees;
@Input() flgInfoUpdate = false;
totalFees = [{'name': 'Monthly', 'value': 0}, {'name': 'Weekly', 'value': 0}, {'name': 'Daily', 'value': 0}]; totalFees = [{'name': 'Monthly', 'value': 0}, {'name': 'Weekly', 'value': 0}, {'name': 'Daily', 'value': 0}];
maxFeeValue = 100; maxFeeValue = 100;

@ -5,18 +5,19 @@
</div> </div>
<mat-grid-list cols="10" [rowHeight]="operatorCardHeight"> <mat-grid-list cols="10" [rowHeight]="operatorCardHeight">
<mat-grid-tile *ngFor="let card of operatorCards" [colspan]="card.cols" [rowspan]="card.rows"> <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-header>
<mat-card-title> <mat-card-title>
{{card.title}} <fa-icon [icon]="card.icon" class="mr-1"></fa-icon>
<span>{{card.title}}</span>
</mat-card-title> </mat-card-title>
</mat-card-header> </mat-card-header>
<mat-card-content class="dashboard-card-content w-100" fxFlex="95"> <mat-card-content class="dashboard-card-content w-100" fxFlex="95">
<div [ngSwitch]="card.id" fxLayout="column" fxFlex="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-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-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> <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> <h3 *ngSwitchDefault>Error! Unable to find information!</h3>
</div> </div>
@ -32,12 +33,17 @@
</div> </div>
<mat-grid-list cols="6" [rowHeight]="merchantCardHeight"> <mat-grid-list cols="6" [rowHeight]="merchantCardHeight">
<mat-grid-tile *ngFor="let card of merchantCards" [colspan]="card.cols" [rowspan]="card.rows"> <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 fxLayout="column" fxLayoutAlign="start start" class="dashboard-card" [ngClass]="{'p-24': card.id !== 'transactions'}">
<mat-card-header *ngIf="card.id !== 'transactions'"><mat-card-title>{{card.title}}</mat-card-title></mat-card-header> <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}}"> <mat-card-content class="dashboard-card-content w-100" fxFlex="{{card.id !== 'transactions' ? 95 : 100}}">
<div [ngSwitch]="card.id" fxLayout="column" fxFlex="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-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="'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> <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'"> <span fxLayout="column" fxFlex="100" *ngSwitchCase="'transactions'">

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

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

@ -17,7 +17,7 @@
<mat-form-field fxFlex="68" fxLayoutAlign="start end"> <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> <input matInput name="lookupKey" [placeholder]="lookupFields[selectedFieldId]?.placeholder || 'Lookup Key'" (change)="clearLookupValue()" [(ngModel)]="lookupKey" tabindex="2" required>
</mat-form-field> </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-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> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="4" type="submit" (click)="onLookup()" [disabled]="!form.valid">Lookup</button>
</div> </div>

@ -6,7 +6,7 @@
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start start" class="padding-gap-x"> <div fxLayout="row" fxFlex="100" fxLayoutAlign="start start" class="padding-gap-x">
<mat-card fxLayout="row" fxFlex="100" fxLayoutAlign="start start"> <mat-card fxLayout="row" fxFlex="100" fxLayoutAlign="start start">
<mat-card-content fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="card-content-gap"> <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-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> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="2" (click)="onStartMonitor()">Start Monitor</button>
</div> </div>

@ -27,7 +27,7 @@
</mat-form-field> </mat-form-field>
</div> </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="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-stroked-button color="primary" tabindex="7" type="reset" (click)="resetData()">Clear Fields</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary"
[disabled]="invalidValues" type="submit" tabindex="8" (click)="onSendFunds()"> [disabled]="invalidValues" type="submit" tabindex="8" (click)="onSendFunds()">
@ -60,7 +60,7 @@
</mat-form-field> </mat-form-field>
</div> </div>
<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-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()"> <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> <p *ngIf="invalidValues && (addressSweep.touched || addressSweep.dirty); else sendTextSweep">Invalid Values</p>

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

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

@ -3,7 +3,7 @@
<mat-form-field fxFlex="100" fxLayoutAlign="start end"> <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"> <input matInput placeholder="Lightning Address (pubkey OR pubkey@ip:port)" name="peerAddress" [(ngModel)]="peerAddress" tabindex="1" required #peerAdd="ngModel">
</mat-form-field> </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-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()"> <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> <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-datepicker #endDatepicker [startAt]="endDate"></mat-datepicker>
</mat-form-field> </mat-form-field>
</div> </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-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> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" [disabled]="routingForm.invalid" type="submit" tabindex="4">Fetch Events</button>
</div> </div>

@ -11,7 +11,7 @@ import { MatDialog } from '@angular/material';
import { environment, API_URL } from '../../../environments/environment'; import { environment, API_URL } from '../../../environments/environment';
import { LoggerService } from '../../shared/services/logger.service'; import { LoggerService } from '../../shared/services/logger.service';
import { SessionService } from '../../shared/services/session.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 { InvoiceInformationComponent } from '../../shared/components/data-modal/invoice-information/invoice-information.component';
import { OpenChannelComponent } from '../../shared/components/data-modal/open-channel/open-channel.component'; import { OpenChannelComponent } from '../../shared/components/data-modal/open-channel/open-channel.component';
import { CurrencyUnitEnum, AlertTypeEnum } from '../../shared/services/consts-enums-functions'; import { CurrencyUnitEnum, AlertTypeEnum } from '../../shared/services/consts-enums-functions';
@ -476,23 +476,37 @@ export class LNDEffects implements OnDestroy {
.pipe( .pipe(
map((channels: any) => { map((channels: any) => {
this.logger.info(channels); 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) { if (channels) {
pendingChannels = 0;
if (channels.pending_closing_channels) { 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) { 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) { 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) { 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 { return {
type: RTLActions.SET_PENDING_CHANNELS, type: RTLActions.SET_PENDING_CHANNELS,
payload: channels ? { channels: channels, pendingChannels: pendingChannels } : {channels: {}, pendingChannels: pendingChannels} payload: channels ? { channels: channels, pendingChannels: pendingChannels } : {channels: {}, pendingChannels: pendingChannels}
@ -1073,8 +1087,7 @@ export class LNDEffects implements OnDestroy {
uris: info.uris, uris: info.uris,
version: info.version, version: info.version,
currency_unit: info.currency_unit, currency_unit: info.currency_unit,
smaller_currency_unit: info.smaller_currency_unit, smaller_currency_unit: info.smaller_currency_unit
numberOfPendingChannels: info.num_pending_channels
}; };
this.store.dispatch(new RTLActions.SetNodeData(node_data)); this.store.dispatch(new RTLActions.SetNodeData(node_data));
this.store.dispatch(new RTLActions.FetchFees()); this.store.dispatch(new RTLActions.FetchFees());

@ -1,7 +1,7 @@
import { SelNodeChild } from '../../shared/models/RTLconfig'; import { SelNodeChild } from '../../shared/models/RTLconfig';
import { ErrorPayload } from '../../shared/models/errorPayload'; import { ErrorPayload } from '../../shared/models/errorPayload';
import { 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'; } from '../../shared/models/lndModels';
import * as RTLActions from '../../store/rtl.actions'; import * as RTLActions from '../../store/rtl.actions';
import { UserPersonaEnum } from '../../shared/services/consts-enums-functions'; import { UserPersonaEnum } from '../../shared/services/consts-enums-functions';
@ -20,7 +20,7 @@ export interface LNDState {
pendingChannels: PendingChannels; pendingChannels: PendingChannels;
numberOfActiveChannels: number; numberOfActiveChannels: number;
numberOfInactiveChannels: number; numberOfInactiveChannels: number;
numberOfPendingChannels: number; numberOfPendingChannels: PendingChannelsGroup;
totalCapacityActive: number; totalCapacityActive: number;
totalCapacityInactive: number; totalCapacityInactive: number;
totalLocalBalance: number; totalLocalBalance: number;
@ -46,7 +46,7 @@ export const initLNDState: LNDState = {
pendingChannels: {}, pendingChannels: {},
numberOfActiveChannels: 0, numberOfActiveChannels: 0,
numberOfInactiveChannels: 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, totalCapacityActive: 0,
totalCapacityInactive: 0, totalCapacityInactive: 0,
totalLocalBalance: -1, totalLocalBalance: -1,

@ -20,7 +20,7 @@
<div fxFlex="23" tabindex="4" fxLayoutAlign="start center" *ngIf="showDetails"> <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> <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>
<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-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"> <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> <p *ngIf="addInvoiceForm.form.invalid; else createText">Invalid values</p>

@ -3,7 +3,7 @@
<mat-form-field class="w-100"> <mat-form-field class="w-100">
<input matInput placeholder="Payment Request" name="paymentRequest" [(ngModel)]="paymentRequest" tabindex="1" required #paymentReq="ngModel"> <input matInput placeholder="Payment Request" name="paymentRequest" [(ngModel)]="paymentRequest" tabindex="1" required #paymentReq="ngModel">
</mat-form-field> </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-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"> <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> <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"> <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"> <input matInput placeholder="Amount (Sats)" name="amount" [(ngModel)]="amount" tabindex="2" type="number" step="1000" min="0" required #destAmount="ngModel">
</mat-form-field> </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-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"> <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> <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> <input matInput type="password" placeholder="Password" name="walletPassword" [(ngModel)]="walletPassword" tabindex="1" required>
<mat-hint>Enter Wallet Password</mat-hint> <mat-hint>Enter Wallet Password</mat-hint>
</mat-form-field> </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-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> <button mat-raised-button fxFlex="48" color="primary" [disabled]="walletPassword == ''" (click)="onUnlockWallet()" tabindex="3">Unlock Wallet</button>
</div> </div>

@ -90,7 +90,7 @@
<ng-template #openText><p>Open Channel</p></ng-template> <ng-template #openText><p>Open Channel</p></ng-template>
</button> </button>
</div> </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 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"> <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> <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.information = rtlStore.nodeData;
this.appConfig = rtlStore.appConfig; this.appConfig = rtlStore.appConfig;
this.selNode = rtlStore.selNode; this.selNode = rtlStore.selNode;
this.numPendingChannels = rtlStore.nodeData.numberOfPendingChannels;
if(this.selNode.lnImplementation.toUpperCase() === 'CLT') { if(this.selNode.lnImplementation.toUpperCase() === 'CLT') {
this.menuNodes = MENU_DATA.CLChildren; this.menuNodes = MENU_DATA.CLChildren;
} else { } else {

@ -71,7 +71,6 @@ export class SideNavigationComponent implements OnInit, OnDestroy {
this.selNode = rtlStore.selNode; this.selNode = rtlStore.selNode;
this.settings = this.selNode.settings; this.settings = this.selNode.settings;
this.information = rtlStore.nodeData; this.information = rtlStore.nodeData;
this.numPendingChannels = rtlStore.nodeData.numberOfPendingChannels;
if (undefined !== this.information.identity_pubkey) { if (undefined !== this.information.identity_pubkey) {
if (undefined !== this.information.chains && typeof this.information.chains[0] === 'string') { 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" 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"> <div fxLayout="column" fxLayout.gt-sm="row" fxFlex="100" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="32" fxLayoutAlign="start end"> <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"> <mat-option *ngFor="let userPersona of userPersonas" [value]="userPersona">
{{userPersona | titlecase}} {{userPersona | titlecase}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </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-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"> <mat-option *ngFor="let currencyUnit of currencyUnits" [value]="currencyUnit.id">
{{currencyUnit.id}} {{currencyUnit.id}}
</mat-option> </mat-option>
</mat-select> </mat-select>
</mat-form-field> </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>
<div fxLayout="column" fxLayout.gt-sm="row" fxFlex="100" fxLayoutAlign="start stretch" class="mt-1"> <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"> <mat-divider class="w-100"></mat-divider>
<h4>Mode</h4> <div fxLayout="column" fxLayoutAlign="space-between stretch" class="settings-container page-sub-title-container mt-1 w-100">
<mat-radio-group color="primary" [(ngModel)]="selectedThemeMode" (change)="chooseThemeMode()"> <div fxFlex="100" class="my-1">
<mat-radio-button *ngFor="let themeMode of themeModes" [value]="themeMode" [ngClass]="{'mr-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">{{themeMode.name}} <fa-icon [icon]="faPaintBrush" class="page-title-img mr-1"></fa-icon>
</mat-radio-button> <span class="page-title">Customization</span>
</mat-radio-group> </div>
</div> <div fxLayout="column" fxLayout.gt-xs="row" fxFlex="100" fxLayoutAlign="space-between stretch" fxLayoutAlign.gt-xs="start stretch">
<div fxLayout="column" fxFlex="9"></div> <div fxFlex.gt-xs="20" fxFlex.gt-md="15" fxLayout="column" fxLayoutAlign="space-between stretch">
<div fxLayout="column" fxFlex="40"> <h4>Theme</h4>
<h4>Skins</h4> <mat-radio-group color="primary" [(ngModel)]="selectedThemeMode" (change)="chooseThemeMode()">
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between start"> <mat-radio-button *ngFor="let themeMode of themeModes" [value]="themeMode" [ngClass]="{'mr-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">{{themeMode.name}}
<span *ngFor="let themeColor of themeColors"> </mat-radio-button>
<div [class]="themeColor" [ngClass]="{'skin': true, 'selected-color': selectedThemeColor === themeColor}" (click)="changeThemeColor(themeColor)"></div> </mat-radio-group>
</span> </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>
</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"> <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-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> <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 { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store'; 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 { CURRENCY_UNITS, UserPersonaEnum, ScreenSizeEnum, FIAT_CURRENCY_UNITS } from '../../../services/consts-enums-functions';
import { LightningNode, Settings, RTLConfiguration, GetInfoRoot } from '../../../models/RTLconfig'; import { LightningNode, Settings, RTLConfiguration, GetInfoRoot } from '../../../models/RTLconfig';
@ -17,6 +18,9 @@ import * as fromRTLReducer from '../../../../store/rtl.reducers';
styleUrls: ['./app-settings.component.scss'] styleUrls: ['./app-settings.component.scss']
}) })
export class AppSettingsComponent implements OnInit, OnDestroy { export class AppSettingsComponent implements OnInit, OnDestroy {
public faWrench = faWrench;
public faPaintBrush = faPaintBrush;
public faInfoCircle = faInfoCircle;
public selNode: LightningNode; public selNode: LightningNode;
public information: GetInfoRoot = {}; public information: GetInfoRoot = {};
public userPersonas = [UserPersonaEnum.OPERATOR, UserPersonaEnum.MERCHANT]; public userPersonas = [UserPersonaEnum.OPERATOR, UserPersonaEnum.MERCHANT];

@ -1,6 +1,6 @@
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container"> <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> <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>
<div fxLayout="column" class="padding-gap-x"> <div fxLayout="column" class="padding-gap-x">
<mat-card> <mat-card>

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

@ -12,7 +12,7 @@
tabindex="1" required> tabindex="1" required>
<mat-hint>{{hintStr}}</mat-hint> <mat-hint>{{hintStr}}</mat-hint>
</mat-form-field> </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-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> <button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" tabindex="3" type="submit" [disabled]="!password">Login</button>
</div> </div>

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

@ -7,7 +7,7 @@ export interface ChannelsStatus {
active?: ChannelStatus; active?: ChannelStatus;
inactive?: ChannelStatus; inactive?: ChannelStatus;
pending?: ChannelStatus; pending?: ChannelStatus;
closed?: ChannelStatus; closing?: ChannelStatus;
} }
export interface AddressType { export interface AddressType {
@ -387,3 +387,17 @@ export interface SwitchRes {
last_offset_index?: number; last_offset_index?: number;
forwarding_events?: ForwardingEvent[]; 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 = { export const MENU_DATA: MenuRootNode = {
LNDChildren: [ LNDChildren: [
@ -9,11 +9,11 @@ export const MENU_DATA: MenuRootNode = {
{id: 32, parentId: 3, name: 'Transactions', iconType: 'FA', icon: faExchangeAlt, link: '/lnd/transactions'}, {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: 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: 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: 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: 5, parentId: 0, name: 'Settings', iconType: 'FA', icon: faTools, link: '/settings'}, {id: 5, parentId: 0, name: 'Node/Network', iconType: 'FA', icon: faServer, link: '/lnd/network'},
{id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help'} {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: [ CLChildren: [
{id: 1, parentId: 0, name: 'Home', icon: 'home', link: '/cl/home'}, {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/light-dull-theme.scss';
@import './color-swatches/dark-bright-theme.scss'; @import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss'; @import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming'; @import '~@angular/material/theming';
@include mat-core(); @include mat-core();
$blue-primary: mat-palette($mat-blue, 700, 200, A200); $blue-primary: mat-palette($mat-blue, 700, 200, A200);
$blue-accent: mat-palette($mat-pink, A200, A100, A400); $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-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-night, $blue-warn);
$blue-night-theme: create-dark-bright-theme($blue-primary, $blue-accent, $blue-warn);
$blue-day-theme: mat-light-theme($blue-primary, $blue-accent, $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/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss'; @import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/green-primary.swatch.scss'; @import './color-swatches/green-primary.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming'; @import '~@angular/material/theming';
@include mat-core(); @include mat-core();
$green-primary: mat-palette($green-primary, 500, 300, A200); $green-primary: mat-palette($green-primary, 500, 300, A200);
$green-accent: mat-palette($mat-amber, A200, A100, A700); $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-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-night, $green-warn);
$green-night-theme: create-dark-bright-theme($green-primary, $green-accent, $green-warn);
$green-day-theme: mat-light-theme($green-primary, $green-accent, $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/light-dull-theme.scss';
@import './color-swatches/dark-bright-theme.scss'; @import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss'; @import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming'; @import '~@angular/material/theming';
@include mat-core(); @include mat-core();
$indigo-primary: mat-palette($mat-indigo, 500, 200, A200); $indigo-primary: mat-palette($mat-indigo, 500, 200, A200);
$indigo-accent: mat-palette($mat-pink, A200, A100, A400); $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-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-night, $indigo-warn);
$indigo-night-theme: create-dark-bright-theme($indigo-primary, $indigo-accent, $indigo-warn);
$indigo-day-theme: mat-light-theme($indigo-primary, $indigo-accent, $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/light-dull-theme.scss';
@import './color-swatches/dark-bright-theme.scss'; @import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss'; @import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming'; @import '~@angular/material/theming';
@include mat-core(); @include mat-core();
$pink-primary: mat-palette($mat-pink, 500, 300, A200); $pink-primary: mat-palette($mat-pink, 500, 300, A200);
$pink-accent: mat-palette($mat-blue-grey, 700, 500, 900); $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-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-night, $pink-warn);
$pink-night-theme: create-dark-bright-theme($pink-primary, $pink-accent, $pink-warn);
$pink-day-theme: mat-light-theme($pink-primary, $pink-accent, $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/dark-bright-theme.scss';
@import './color-swatches/purple-primary.swatch.scss'; @import './color-swatches/purple-primary.swatch.scss';
@import './color-swatches/red-warn.swatch.scss'; @import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming'; @import '~@angular/material/theming';
@include mat-core(); @include mat-core();
$purple-primary: mat-palette($purple-primary, 500, 300, A200); $purple-primary: mat-palette($purple-primary, 500, 300, A200);
$purple-accent: mat-palette($mat-gray, 800, 600, 900); $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-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-night, $purple-warn);
$purple-night-theme: create-dark-bright-theme($purple-primary, $purple-accent, $purple-warn);
$purple-day-theme: mat-light-theme($purple-primary, $purple-accent, $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/light-dull-theme.scss';
@import './color-swatches/dark-bright-theme.scss'; @import './color-swatches/dark-bright-theme.scss';
@import './color-swatches/red-warn.swatch.scss'; @import './color-swatches/red-warn.swatch.scss';
@import './color-swatches/white.swatch.scss';
@import '~@angular/material/theming'; @import '~@angular/material/theming';
@include mat-core(); @include mat-core();
$teal-primary: mat-palette($mat-teal, 800, 300, A200); $teal-primary: mat-palette($mat-teal, 800, 300, A200);
$teal-accent: mat-palette($mat-amber, A200, A100, A700); $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-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-night, $teal-warn);
$teal-night-theme: create-dark-bright-theme($teal-primary, $teal-accent, $teal-warn);
$teal-day-theme: mat-light-theme($teal-primary, $teal-accent, $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: map-get($theme, warn);
$warn-color: mat-color($warn); $warn-color: mat-color($warn);
$foreground: map-get($theme, foreground); $foreground: map-get($theme, foreground);
$foreground-base: mat-color($foreground, base); $foreground-base: mat-color($foreground, base); // 1
$foreground-text: mat-color($foreground, text); $foreground-text: mat-color($foreground, text); //.87
$foreground-secondary-text: mat-color($foreground, secondary-text); $foreground-secondary-text: mat-color($foreground, secondary-text); // .54
$foreground-disabled: mat-color($foreground, disabled); $foreground-disabled: mat-color($foreground, disabled); // .38
$foreground-divider: mat-color($foreground, divider); $foreground-divider: mat-color($foreground, divider); // .12
$background: map-get($theme, background); $background: map-get($theme, background);
$background-color: mat-color($background, card); $background-color: mat-color($background, card);
$hover-background: rgba(0, 0, 0, 0.04); $hover-background: rgba(0, 0, 0, 0.04);
@ -101,6 +101,50 @@
.mat-tab-label, .mat-tab-link { .mat-tab-label, .mat-tab-link {
color: $foreground-secondary-text; 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 { &.day {
@ -181,12 +225,34 @@
box-shadow: none; box-shadow: none;
border: 1px solid $foreground-divider; 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 { .mat-progress-bar-buffer {
background-color: mat-color($primary, 100); 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 { .foreground-secondary-text {
color: $foreground-secondary-text !important; color: $foreground-secondary-text !important;
white-space: pre-line; 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; padding: 2rem !important;
} }
.p-24 {
padding: 2.4rem !important;
}
.m-1px { .m-1px {
margin: 1px !important; margin: 1px !important;
} }
@ -602,14 +606,14 @@ body {
margin: 1.2rem 0 0.6rem 0; margin: 1.2rem 0 0.6rem 0;
} }
.skin{ .skin{
width: 4rem; width: 2rem;
height: 4rem; height: 2rem;
border-radius: 50%; border-radius: 50%;
margin-right: 1rem;
cursor: pointer; cursor: pointer;
margin-right: 0.5rem;
&.selected-color { &.selected-color {
width: 3.75rem; width: 1.75rem;
height: 3.75rem; height: 1.75rem;
border: 0.25rem solid; border: 0.25rem solid;
} }
&.purple{ &.purple{
@ -774,6 +778,10 @@ a {
font-weight: 500 !important; font-weight: 500 !important;
} }
.font-bold-700 {
font-weight: 700 !important;
}
.qr-border img { .qr-border img {
border: 1.2rem solid white; border: 1.2rem solid white;
} }
@ -850,8 +858,7 @@ table {
width: $tiny-dot-size; width: $tiny-dot-size;
height: $tiny-dot-size; height: $tiny-dot-size;
border-radius: $tiny-dot-size; border-radius: $tiny-dot-size;
margin-right: 0.6rem; margin: 0 0.6rem 0.1rem 0;
margin-bottom: 0.2rem;
} }
&.green { &.green {
background-color: $green-color; background-color: $green-color;
@ -871,6 +878,10 @@ table {
font-size: 80% !important; font-size: 80% !important;
} }
.font-size-90 {
font-size: 90% !important;
}
.font-weight-900 { .font-weight-900 {
font-weight: 900 !important; font-weight: 900 !important;
} }
@ -903,3 +914,13 @@ table {
@-webkit-keyframes blink-animation { to { visibility: hidden; }} @-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 { GetInfoCL, FeesCL, AddressTypeCL, PeerCL, PaymentCL, PayRequestCL, QueryRoutesCL, ChannelCL, FeeRatesCL, ForwardingHistoryResCL, InvoiceCL, ListInvoicesCL, OnChainCL } from '../shared/models/clModels';
import { import {
GetInfo, Peer, Balance, NetworkInfo, Fees, Channel, Invoice, ListInvoices, Payment, GraphNode, AddressType, 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'; } from '../shared/models/lndModels';
export const VOID = 'VOID'; export const VOID = 'VOID';
@ -29,7 +29,6 @@ export const SET_RTL_CONFIG = 'SET_RTL_CONFIG';
export const SAVE_SETTINGS = 'SAVE_SETTINGS'; export const SAVE_SETTINGS = 'SAVE_SETTINGS';
export const SET_SELECTED_NODE = 'SET_SELECTED_NODE'; export const SET_SELECTED_NODE = 'SET_SELECTED_NODE';
export const SET_NODE_DATA = 'SET_NODE_DATA'; 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 RESET_LND_STORE = 'RESET_LND_STORE';
export const CLEAR_EFFECT_ERROR_LND = 'CLEAR_EFFECT_ERROR_LND'; export const CLEAR_EFFECT_ERROR_LND = 'CLEAR_EFFECT_ERROR_LND';
@ -268,11 +267,6 @@ export class SetNodeData implements Action {
constructor(public payload: GetInfoRoot) {} 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 { export class SetChildNodeSettings implements Action {
readonly type = SET_CHILD_NODE_SETTINGS; readonly type = SET_CHILD_NODE_SETTINGS;
constructor(public payload: SelNodeChild) {} constructor(public payload: SelNodeChild) {}
@ -370,7 +364,7 @@ export class FetchPendingChannels implements Action {
export class SetPendingChannels implements Action { export class SetPendingChannels implements Action {
readonly type = SET_PENDING_CHANNELS; readonly type = SET_PENDING_CHANNELS;
constructor(public payload: {channels: PendingChannels, pendingChannels: number}) {} constructor(public payload: {channels: PendingChannels, pendingChannels: PendingChannelsGroup}) {}
} }
export class FetchClosedChannels implements Action { export class FetchClosedChannels implements Action {
@ -833,7 +827,7 @@ export type RTLActions =
VoidAction | OpenSnackBar | OpenSpinner | CloseSpinner | FetchRTLConfig | SetRTLConfig | SaveSettings | VoidAction | OpenSnackBar | OpenSpinner | CloseSpinner | FetchRTLConfig | SetRTLConfig | SaveSettings |
OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation | ShowPubkey | OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation | ShowPubkey |
UpdateSelectedNodeOptions | ResetRootStore | ResetLNDStore | ResetCLStore | UpdateSelectedNodeOptions | ResetRootStore | ResetLNDStore | ResetCLStore |
SetSelelectedNode | SetNodeData | SetNodePendingChannelsData | SetChildNodeSettings | FetchInfo | SetInfo | SetSelelectedNode | SetNodeData | SetChildNodeSettings | FetchInfo | SetInfo |
FetchPeers | SetPeers | AddPeer | DetachPeer | SaveNewPeer | RemovePeer | FetchPeers | SetPeers | AddPeer | DetachPeer | SaveNewPeer | RemovePeer |
AddInvoice | SaveNewInvoice | GetForwardingHistory | SetForwardingHistory | AddInvoice | SaveNewInvoice | GetForwardingHistory | SetForwardingHistory |
FetchFees | SetFees | FetchFees | SetFees |

@ -63,13 +63,6 @@ export function RootReducer(state = initRootState, action: RTLActions.RTLActions
...state, ...state,
nodeData: action.payload 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: case RTLActions.SET_RTL_CONFIG:
return { return {
...state, ...state,

Loading…
Cancel
Save