UX Updates

UX Updates
This commit is contained in:
Shahana Farooqui 2019-12-22 22:07:50 -05:00
parent 160c6645df
commit d256bf07a5
45 changed files with 441 additions and 363 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -9,8 +9,8 @@
<link rel="icon" type="image/png" sizes="32x32" href="assets/images/favicon/favicon-32x32.png"> <link rel="icon" type="image/png" sizes="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.bb61947bc04e5e880316.css"></head> <link rel="stylesheet" href="styles.338691320cacab894cbc.css"></head>
<body> <body>
<rtl-app></rtl-app> <rtl-app></rtl-app>
<script src="runtime.27bfb56ae5ce2eeee2bd.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.e03fbead8d2ea2dcc5eb.js" defer></script></body> <script src="runtime.fd2304027495a03084f4.js" defer></script><script src="polyfills-es5.b8e32dec482ae69710a2.js" nomodule defer></script><script src="polyfills.ebf9033c33aa4a5af12a.js" defer></script><script src="main.3c7c21d18c4a53ccacf8.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

View file

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

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -226,7 +226,6 @@ exports.getCurrencyRates = (req, res, next) => {
options.url = 'https://blockchain.info/ticker'; options.url = 'https://blockchain.info/ticker';
console.log(options); console.log(options);
request(options).then((body) => { request(options).then((body) => {
logger.info({fileName: 'RTLConf', msg: 'Rates Received: ' + JSON.stringify(body)});
if(undefined === body || body.error) { if(undefined === body || body.error) {
res.status(500).json({ res.status(500).json({
message: "Fetching Rates Failed!", message: "Fetching Rates Failed!",
@ -234,6 +233,8 @@ exports.getCurrencyRates = (req, res, next) => {
}); });
} else { } else {
res.status(200).json(body); res.status(200).json(body);
body = JSON.parse(body);
logger.info({fileName: 'RTLConf', msg: 'Rates Received: ' + JSON.stringify(body)});
} }
}) })
.catch(function (err) { .catch(function (err) {

View file

@ -1,9 +1,8 @@
import { Routes, RouterModule } from '@angular/router'; import { Routes, RouterModule } from '@angular/router';
import { ModuleWithProviders } from '@angular/core'; import { ModuleWithProviders } from '@angular/core';
import { AppSettingsComponent } from './shared/components/app-settings/app-settings.component'; import { SettingsComponent } from './shared/components/settings/settings.component';
import { NotFoundComponent } from './shared/components/not-found/not-found.component'; import { NotFoundComponent } from './shared/components/not-found/not-found.component';
import { ServerConfigComponent } from './shared/components/server-config/server-config.component';
import { HelpComponent } from './shared/components/help/help.component'; import { HelpComponent } from './shared/components/help/help.component';
import { SigninComponent } from './shared/components/signin/signin.component'; import { SigninComponent } from './shared/components/signin/signin.component';
import { ErrorComponent } from './shared/components/error/error.component'; import { ErrorComponent } from './shared/components/error/error.component';
@ -12,8 +11,7 @@ import { AuthGuard } from './shared/services/auth.guard';
export const routes: Routes = [ export const routes: Routes = [
{ path: 'lnd', loadChildren: () => import('./lnd/lnd.module').then(childModule => childModule.LNDModule), canActivate: [AuthGuard] }, { path: 'lnd', loadChildren: () => import('./lnd/lnd.module').then(childModule => childModule.LNDModule), canActivate: [AuthGuard] },
{ path: 'cl', loadChildren: () => import('./clightning/cl.module').then(childModule => childModule.CLModule), canActivate: [AuthGuard] }, { path: 'cl', loadChildren: () => import('./clightning/cl.module').then(childModule => childModule.CLModule), canActivate: [AuthGuard] },
{ path: 'advanced', component: ServerConfigComponent, canActivate: [AuthGuard] }, { path: 'settings', component: SettingsComponent, canActivate: [AuthGuard] },
{ path: 'settings', component: AppSettingsComponent, canActivate: [AuthGuard] },
{ path: 'help', component: HelpComponent }, { path: 'help', component: HelpComponent },
{ path: 'login', component: SigninComponent }, { path: 'login', component: SigninComponent },
{ path: 'error', component: ErrorComponent }, { path: 'error', component: ErrorComponent },

View file

@ -45,10 +45,17 @@
</td> </td>
</ng-container> </ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="pr-3"><span fxLayoutAlign="end center">Actions</span></th> <th mat-header-cell *matHeaderCellDef fxLayoutAlign="end center" class="pl-1">
<td mat-cell *matCellDef="let channel" fxLayoutAlign="end center" class="pl-3">
<div fxFlex="100" class="bordered-box table-actions-select" fxLayoutAlign="center center"> <div fxFlex="100" class="bordered-box table-actions-select" fxLayoutAlign="center center">
<mat-select placeholder="Actions" tabindex="1" class="mr-0"> <mat-select placeholder="Table Actions" tabindex="1" class="mr-0">
<mat-select-trigger></mat-select-trigger>
<mat-option (click)="onChannelUpdate('all')">Update Fee Policy</mat-option>
</mat-select>
</div>
</th>
<td mat-cell *matCellDef="let channel" fxLayoutAlign="end center" class="pl-1">
<div fxFlex="100" class="bordered-box table-actions-select" fxLayoutAlign="center center">
<mat-select placeholder="Actions" tabindex="2" class="mr-0">
<mat-select-trigger></mat-select-trigger> <mat-select-trigger></mat-select-trigger>
<mat-option (click)="onChannelClick(channel, $event)">View Info</mat-option> <mat-option (click)="onChannelClick(channel, $event)">View Info</mat-option>
<mat-option (click)="onChannelUpdate(channel)">Update Fee Policy</mat-option> <mat-option (click)="onChannelUpdate(channel)">Update Fee Policy</mat-option>

View file

@ -82,11 +82,11 @@ export class ChannelOpenTableComponent implements OnInit, OnDestroy {
onChannelUpdate(channelToUpdate: any) { onChannelUpdate(channelToUpdate: any) {
if (channelToUpdate === 'all') { if (channelToUpdate === 'all') {
const titleMsg = 'Updated Values for ALL Channels'; const titleMsg = 'Updated fee policy for all the Channels';
const confirmationMsg = []; const confirmationMsg = [];
this.store.dispatch(new RTLActions.OpenConfirmation({ data: { this.store.dispatch(new RTLActions.OpenConfirmation({ data: {
type: AlertTypeEnum.CONFIRM, type: AlertTypeEnum.CONFIRM,
alertTitle: 'Update Channel', alertTitle: 'Update All Channels Fee Policy',
titleMessage: titleMsg, titleMessage: titleMsg,
noBtnText: 'Cancel', noBtnText: 'Cancel',
yesBtnText: 'Update All Channels', yesBtnText: 'Update All Channels',

View file

@ -1,18 +1,21 @@
<div fxLayout="column"> <div fxLayout="column" fxLayoutAlign="start stretch">
<mat-card fxLayout="column" fxLayoutAlign.gt-sm="space-between start" fxLayoutAlign.lt-md="space-between stretch" fxLayout.gt-sm="row wrap"> <div fxLayout="column" fxLayout.gt-md="row" fxFlex="100" fxLayoutAlign="space-between stretch" class="padding-gap-x page-sub-title-container">
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch" class="table-card-content"> <div fxLayout="column" fxFlex="49" fxLayoutAlign="start start">
<div perfectScrollbar class="table-container"> <div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="padding-gap-x page-sub-title-container w-100" [ngClass]="{'mt-2': screenSize === screenSizeEnum.XS, 'mt-1': screenSize === screenSizeEnum.SM}">
<div fxFlex="70">Incoming</div>
<mat-form-field fxFlex="30">
<input matInput (keyup)="applyIncomingFilter($event.target.value)" placeholder="Filter">
</mat-form-field>
</div>
<div perfectScrollbar fxLayout="row" fxLayoutAlign="start start" fxFlex="100" class="table-container w-100">
<table mat-table #tableIn [dataSource]="RoutingPeersIncoming" matSort fxFlex="100" class="overflow-auto incoming-table"> <table mat-table #tableIn [dataSource]="RoutingPeersIncoming" matSort fxFlex="100" class="overflow-auto incoming-table">
<ng-container matColumnDef="incoming">
<th mat-header-cell *matHeaderCellDef colspan="10">Incoming Traffic</th>
</ng-container>
<ng-container matColumnDef="chan_id"> <ng-container matColumnDef="chan_id">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<td mat-cell *matCellDef="let rPeer">{{rPeer.chan_id}}</td> <td mat-cell *matCellDef="let rPeer" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '28rem'}">{{rPeer.chan_id}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="alias"> <ng-container matColumnDef="alias">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th> <th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th>
<td mat-cell *matCellDef="let rPeer">{{rPeer.alias}}</td> <td mat-cell *matCellDef="let rPeer" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '28rem'}">{{rPeer.alias}}</td>
</ng-container> </ng-container>
<ng-container matColumnDef="events"> <ng-container matColumnDef="events">
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Events</th> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Events</th>
@ -24,8 +27,8 @@
<td mat-cell *matCellDef="let rPeer"><span fxLayoutAlign="end center">{{rPeer.total_amount | number}}</span></td> <td mat-cell *matCellDef="let rPeer"><span fxLayoutAlign="end center">{{rPeer.total_amount | number}}</span></td>
</ng-container> </ng-container>
<ng-container matColumnDef="actions"> <ng-container matColumnDef="actions">
<th mat-header-cell *matHeaderCellDef class="pl-4 pr-3"><span fxLayoutAlign="end center">Actions</span></th> <th mat-header-cell *matHeaderCellDef class="pr-3"><span fxLayoutAlign="end center">Actions</span></th>
<td mat-cell *matCellDef="let rPeer" class="pl-4"> <td mat-cell *matCellDef="let rPeer" class="pl-2">
<button mat-stroked-button color="primary" type="button" tabindex="4" (click)="onRoutingPeerClick(rPeer, $event, 'in')">View Info</button> <button mat-stroked-button color="primary" type="button" tabindex="4" (click)="onRoutingPeerClick(rPeer, $event, 'in')">View Info</button>
</td> </td>
</ng-container> </ng-container>
@ -36,52 +39,52 @@
</ng-container> </ng-container>
<tr mat-footer-row *matFooterRowDef="['no_incoming_event']" [ngClass]="{'display-none': RoutingPeersIncoming.data && RoutingPeersIncoming.data.length>0}"></tr> <tr mat-footer-row *matFooterRowDef="['no_incoming_event']" [ngClass]="{'display-none': RoutingPeersIncoming.data && RoutingPeersIncoming.data.length>0}"></tr>
<tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
<tr mat-header-row *matHeaderRowDef="displayIncomingHeader"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table> </table>
</div> </div>
</div> </div>
<div fxLayout="column" fxFlex="100" fxLayoutAlign="start stretch"> <div fxLayout="column" fxFlex="49" fxLayoutAlign="start start">
<mat-card-content class="table-card-content" fxFlex="100"> <div fxLayout="column" fxLayout.gt-sm="row" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="padding-gap-x page-sub-title-container w-100" [ngClass]="{'mt-2': screenSize !== screenSizeEnum.LG}">
<div perfectScrollbar class="table-container"> <div fxFlex="70">Outgoing</div>
<table mat-table #tableOut [dataSource]="RoutingPeersOutgoing" class="overflow-auto outgoing-table"> <mat-form-field fxFlex="30">
<ng-container matColumnDef="outgoing"> <input matInput (keyup)="applyOutgoingFilter($event.target.value)" placeholder="Filter">
<th mat-header-cell *matHeaderCellDef colspan="10">Outgoing Traffic</th> </mat-form-field>
</ng-container> </div>
<ng-container matColumnDef="chan_id"> <div perfectScrollbar fxLayout="row" fxLayoutAlign="start center" fxFlex="100" class="table-container w-100">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th> <table mat-table #tableOut [dataSource]="RoutingPeersOutgoing" matSort fxFlex="100" class="overflow-auto outgoing-table">
<td mat-cell *matCellDef="let rPeer">{{rPeer.chan_id}}</td> <ng-container matColumnDef="chan_id">
</ng-container> <th mat-header-cell *matHeaderCellDef mat-sort-header>Channel ID</th>
<ng-container matColumnDef="alias"> <td mat-cell *matCellDef="let rPeer" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '28rem'}">{{rPeer.chan_id}}</td>
<th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th> </ng-container>
<td mat-cell *matCellDef="let rPeer">{{rPeer.alias}}</td> <ng-container matColumnDef="alias">
</ng-container> <th mat-header-cell *matHeaderCellDef mat-sort-header>Peer Alias</th>
<ng-container matColumnDef="events"> <td mat-cell *matCellDef="let rPeer" [ngStyle]="{'max-width': (screenSize === screenSizeEnum.XS) ? '10rem' : '28rem'}">{{rPeer.alias}}</td>
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Events</th> </ng-container>
<td mat-cell *matCellDef="let rPeer"><span fxLayoutAlign="end center">{{rPeer.events | number}}</span> <ng-container matColumnDef="events">
</td> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Events</th>
</ng-container> <td mat-cell *matCellDef="let rPeer"><span fxLayoutAlign="end center">{{rPeer.events | number}}</span>
<ng-container matColumnDef="total_amount"> </td>
<th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Total Amount (Sats)</th> </ng-container>
<td mat-cell *matCellDef="let rPeer"><span fxLayoutAlign="end center">{{rPeer.total_amount | number}}</span></td> <ng-container matColumnDef="total_amount">
</ng-container> <th mat-header-cell *matHeaderCellDef mat-sort-header arrowPosition="before">Total Amount (Sats)</th>
<ng-container matColumnDef="actions"> <td mat-cell *matCellDef="let rPeer"><span fxLayoutAlign="end center">{{rPeer.total_amount | number}}</span></td>
<th mat-header-cell *matHeaderCellDef class="pl-4 pr-3"><span fxLayoutAlign="end center">Actions</span></th> </ng-container>
<td mat-cell *matCellDef="let rPeer" class="pl-4"> <ng-container matColumnDef="actions">
<button mat-stroked-button color="primary" type="button" tabindex="5" (click)="onRoutingPeerClick(rPeer, $event, 'out')">View Info</button> <th mat-header-cell *matHeaderCellDef class="pr-3"><span fxLayoutAlign="end center">Actions</span></th>
</td> <td mat-cell *matCellDef="let rPeer" class="pl-2">
</ng-container> <button mat-stroked-button color="primary" type="button" tabindex="5" (click)="onRoutingPeerClick(rPeer, $event, 'out')">View Info</button>
<ng-container matColumnDef="no_outgoing_event"> </td>
<td mat-footer-cell *matFooterCellDef colspan="4"> </ng-container>
<p *ngIf="!RoutingPeersOutgoing.data || RoutingPeersOutgoing.data.length<1">No outgoing routing peer available.</p> <ng-container matColumnDef="no_outgoing_event">
</td> <td mat-footer-cell *matFooterCellDef colspan="4">
</ng-container> <p *ngIf="!RoutingPeersOutgoing.data || RoutingPeersOutgoing.data.length<1">No outgoing routing peer available.</p>
<tr mat-footer-row *matFooterRowDef="['no_outgoing_event']" [ngClass]="{'display-none': RoutingPeersOutgoing.data && RoutingPeersOutgoing.data.length>0}"></tr> </td>
<tr mat-header-row *matHeaderRowDef="displayOutgoingHeader"></tr> </ng-container>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> <tr mat-footer-row *matFooterRowDef="['no_outgoing_event']" [ngClass]="{'display-none': RoutingPeersOutgoing.data && RoutingPeersOutgoing.data.length>0}"></tr>
</table> <tr mat-header-row *matHeaderRowDef="displayedColumns; sticky: flgSticky;"></tr>
</div> <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</mat-card-content> </table>
</div>
</div> </div>
</mat-card> </div>
</div> </div>

View file

@ -1,26 +1,6 @@
.mat-column-actions {
flex: 0 0 6%;
width: 6%;
}
.mat-column-chan_id, .mat-column-alias { .mat-column-chan_id, .mat-column-alias {
flex: 0 0 30%; flex: 1 1 25%;
width: 30%; white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
.mat-column-events, .mat-column-total_amount {
flex: 0 0 17%;
width: 17%;
}
table.mat-table.incoming-table {
border-bottom: none !important;
border-bottom-left-radius: 0 !important;
border-bottom-right-radius: 0 !important;
}
table.mat-table.outgoing-table {
border-top: none !important;
border-top-left-radius: 0 !important;
border-top-right-radius: 0 !important;
}

View file

@ -21,26 +21,26 @@ export class RoutingPeersComponent implements OnInit, OnChanges {
@ViewChild(MatSort, { static: true }) sortOut: MatSort; @ViewChild(MatSort, { static: true }) sortOut: MatSort;
@Input() routingPeersData: any; @Input() routingPeersData: any;
public displayedColumns = []; public displayedColumns = [];
public displayIncomingHeader = ['incoming'];
public displayOutgoingHeader = ['outgoing'];
public RoutingPeersIncoming: any; public RoutingPeersIncoming: any;
public RoutingPeersOutgoing: any; public RoutingPeersOutgoing: any;
public flgSticky = false; public flgSticky = false;
public screenSize = '';
public screenSizeEnum = ScreenSizeEnum;
constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) { constructor(private logger: LoggerService, private commonService: CommonService, private store: Store<fromRTLReducer.RTLState>, private actions$: Actions) {
let ss = this.commonService.getScreenSize(); this.screenSize = this.commonService.getScreenSize();
if(ss === ScreenSizeEnum.XS) { if(this.screenSize === ScreenSizeEnum.XS) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['chan_id', 'events', 'actions']; this.displayedColumns = ['chan_id', 'events', 'actions'];
} else if(ss === ScreenSizeEnum.SM) { } else if(this.screenSize === ScreenSizeEnum.SM) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['chan_id', 'events', 'total_amount', 'actions']; this.displayedColumns = ['chan_id', 'alias', 'events', 'total_amount'];
} else if(ss === ScreenSizeEnum.MD) { } else if(this.screenSize === ScreenSizeEnum.MD) {
this.flgSticky = false; this.flgSticky = false;
this.displayedColumns = ['chan_id', 'alias', 'events', 'total_amount', 'actions']; this.displayedColumns = ['chan_id', 'alias', 'events', 'total_amount'];
} else { } else {
this.flgSticky = true; this.flgSticky = true;
this.displayedColumns = ['chan_id', 'alias', 'events', 'total_amount', 'actions']; this.displayedColumns = ['chan_id', 'alias', 'events', 'total_amount'];
} }
} }
@ -115,4 +115,12 @@ export class RoutingPeersComponent implements OnInit, OnChanges {
return [this.commonService.sortDescByKey(incomingResults, 'total_amount'), this.commonService.sortDescByKey(outgoingResults, 'total_amount')]; return [this.commonService.sortDescByKey(incomingResults, 'total_amount'), this.commonService.sortDescByKey(outgoingResults, 'total_amount')];
} }
applyIncomingFilter(selFilter: string) {
this.RoutingPeersIncoming.filter = selFilter;
}
applyOutgoingFilter(selFilter: string) {
this.RoutingPeersOutgoing.filter = selFilter;
}
} }

View file

@ -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 mt-1"> <mat-card-content fxLayout="column" fxFlex="100" fxLayoutAlign="start start" class="card-content-gap mt-1">
<form fxFlex="100" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="w-100" (ngSubmit)="routingForm.form.valid && onEventsFetch()" #routingForm="ngForm"> <form fxFlex="100" fxLayout="column" fxLayout.gt-sm="row wrap" fxLayoutAlign.gt-sm="space-between center" fxLayoutAlign="start stretch" class="w-100 mb-1" (ngSubmit)="routingForm.form.valid && onEventsFetch()" #routingForm="ngForm">
<div fxFlex="100" fxLayoutAlign="space-between stretch"> <div fxFlex="100" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="49" fxLayoutAlign="start"> <mat-form-field fxFlex="49" fxLayoutAlign="start">
<input matInput [matDatepicker]="startDatepicker" placeholder="Start Date" [max]="yesterday" <input matInput [matDatepicker]="startDatepicker" placeholder="Start Date" [max]="yesterday"

View file

@ -7,7 +7,6 @@ import { of, Subject } from 'rxjs';
import { map, mergeMap, catchError, withLatestFrom } from 'rxjs/operators'; import { map, mergeMap, catchError, withLatestFrom } from 'rxjs/operators';
import { Location } from '@angular/common'; import { Location } from '@angular/common';
import { MatDialog } from '@angular/material'; import { MatDialog } from '@angular/material';
import { MatSnackBar } 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';
@ -35,7 +34,6 @@ export class LNDEffects implements OnDestroy {
private logger: LoggerService, private logger: LoggerService,
private sessionService: SessionService, private sessionService: SessionService,
public dialog: MatDialog, public dialog: MatDialog,
private snackBar: MatSnackBar,
private router: Router, private router: Router,
private location: Location) { } private location: Location) { }
@ -170,11 +168,7 @@ export class LNDEffects implements OnDestroy {
map((postRes: any) => { map((postRes: any) => {
this.logger.info(postRes); this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ data: { this.store.dispatch(new RTLActions.OpenSnackBar('Peer Disconnected Successfully.'));
type: AlertTypeEnum.SUCCESS,
alertTitle: 'Peer Disconnected',
titleMessage: 'Peer Disconnected Successfully!'
}}));
return { return {
type: RTLActions.REMOVE_PEER, type: RTLActions.REMOVE_PEER,
payload: { pubkey: action.payload.pubkey } payload: { pubkey: action.payload.pubkey }
@ -261,7 +255,11 @@ export class LNDEffects implements OnDestroy {
map((postRes: any) => { map((postRes: any) => {
this.logger.info(postRes); this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.OpenAlert({ data: { type: AlertTypeEnum.SUCCESS, alertTitle: 'Channel Updated', titleMessage: 'Channel Updated Successfully!' }})); if(action.payload.chanPoint === 'all') {
this.store.dispatch(new RTLActions.OpenSnackBar('All Channels Updated Successfully.'));
} else {
this.store.dispatch(new RTLActions.OpenSnackBar('Channel Updated Successfully!'));
}
return { return {
type: RTLActions.FETCH_ALL_CHANNELS type: RTLActions.FETCH_ALL_CHANNELS
}; };
@ -315,7 +313,7 @@ export class LNDEffects implements OnDestroy {
map((postRes: any) => { map((postRes: any) => {
this.logger.info(postRes); this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
this.snackBar.open(action.payload.showMessage + ' ' + postRes.message); this.store.dispatch(new RTLActions.OpenSnackBar(action.payload.showMessage + ' ' + postRes.message));
return { return {
type: RTLActions.BACKUP_CHANNELS_RES, type: RTLActions.BACKUP_CHANNELS_RES,
payload: postRes.message payload: postRes.message
@ -340,7 +338,7 @@ export class LNDEffects implements OnDestroy {
map((postRes: any) => { map((postRes: any) => {
this.logger.info(postRes); this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
this.snackBar.open(postRes.message); this.store.dispatch(new RTLActions.OpenSnackBar(postRes.message));
return { return {
type: RTLActions.VERIFY_CHANNELS_RES, type: RTLActions.VERIFY_CHANNELS_RES,
payload: postRes.message payload: postRes.message
@ -365,7 +363,7 @@ export class LNDEffects implements OnDestroy {
map((postRes: any) => { map((postRes: any) => {
this.logger.info(postRes); this.logger.info(postRes);
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
this.snackBar.open(postRes.message); this.store.dispatch(new RTLActions.OpenSnackBar(postRes.message));
this.store.dispatch(new RTLActions.SetRestoreChannelsList(postRes.list)); this.store.dispatch(new RTLActions.SetRestoreChannelsList(postRes.list));
return { return {
type: RTLActions.RESTORE_CHANNELS_RES, type: RTLActions.RESTORE_CHANNELS_RES,
@ -752,8 +750,8 @@ export class LNDEffects implements OnDestroy {
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
this.store.dispatch(new RTLActions.FetchBalance('blockchain')); this.store.dispatch(new RTLActions.FetchBalance('blockchain'));
return { return {
type: RTLActions.OPEN_ALERT, type: RTLActions.OPEN_SNACK_BAR,
payload: { data: { type: AlertTypeEnum.SUCCESS, titleMessage: 'Fund Sent Successfully!' } } payload: 'Fund Sent Successfully!'
}; };
}), }),
catchError((err: any) => { catchError((err: any) => {

View file

@ -1,57 +0,0 @@
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
<fa-icon [icon]="faTools" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Application Settings</span>
</div>
<div fxLayout="column" class="padding-gap-x settings-container">
<mat-card>
<mat-card-content fxLayout="column" class="card-content-gap mt-1">
<div fxLayout="column" fxLayout.gt-sm="row" fxFlex="100" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="32" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selNode.settings.userPersona" placeholder="User Persona" tabindex="1" required name="userPersona">
<mat-option *ngFor="let userPersona of userPersonas" [value]="userPersona">
{{userPersona | titlecase}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="32" fxLayoutAlign="start end" *ngIf="appConfig.nodes.length && appConfig.nodes.length > 1">
<mat-select [(ngModel)]="appConfig.defaultNodeIndex" placeholder="Default Node" tabindex="1" required name="defaultNode">
<mat-option *ngFor="let node of appConfig.nodes" [value]="node.index">
{{node.lnNode}} ({{node.lnImplementation}})
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="32" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selNode.settings.currencyUnit" placeholder="Currency Unit" (selectionChange)="onCurrencyChange($event)" tabindex="1" required name="currencyUnit">
<mat-option *ngFor="let currencyUnit of currencyUnits" [value]="currencyUnit.id">
{{currencyUnit.id}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxLayout="column" fxLayout.gt-sm="row" fxFlex="100" fxLayoutAlign="start stretch" class="mt-1">
<div fxLayout="column" fxFlex="25" fxLayoutAlign="start start" fxLayoutAlign.gt-sm="start space-between">
<h4>Mode</h4>
<mat-radio-group color="primary" [(ngModel)]="selectedThemeMode" (change)="chooseThemeMode()">
<mat-radio-button *ngFor="let themeMode of themeModes" [value]="themeMode" [ngClass]="{'mr-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">{{themeMode.name}}
</mat-radio-button>
</mat-radio-group>
</div>
<div fxLayout="column" fxFlex="9"></div>
<div fxLayout="column" fxFlex="40">
<h4>Skins</h4>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between start">
<span *ngFor="let themeColor of themeColors">
<div [class]="themeColor" [ngClass]="{'skin': true, 'selected-color': selectedThemeColor === themeColor}" (click)="changeThemeColor(themeColor)"></div>
</span>
</div>
</div>
</div>
<div fxLayout="row" fxFlex="100" class="mt-4">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="space-between stretch">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" (click)="onResetSettings()" tabindex="12">Reset</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onUpdateSettings()" tabindex="13">Update</button>
</div>
</div>
</mat-card-content>
</mat-card>
</div>

View file

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

View file

@ -1,9 +1,10 @@
import { Component, OnInit, Inject } from '@angular/core'; import { Component, OnInit, Inject } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA, MatSnackBar } from '@angular/material'; import { MatDialogRef, MAT_DIALOG_DATA, MatSnackBar } from '@angular/material';
import { CommonService } from '../../../services/common.service';
import { LoggerService } from '../../../services/logger.service'; import { LoggerService } from '../../../services/logger.service';
import { AlertData, ErrorData } from '../../../models/alertData'; import { AlertData } from '../../../models/alertData';
import { AlertTypeEnum, DataTypeEnum } from '../../../services/consts-enums-functions'; import { AlertTypeEnum, DataTypeEnum, ScreenSizeEnum } from '../../../services/consts-enums-functions';
@Component({ @Component({
selector: 'rtl-alert-message', selector: 'rtl-alert-message',
@ -11,15 +12,23 @@ import { AlertTypeEnum, DataTypeEnum } from '../../../services/consts-enums-func
styleUrls: ['./alert-message.component.scss'] styleUrls: ['./alert-message.component.scss']
}) })
export class AlertMessageComponent implements OnInit { export class AlertMessageComponent implements OnInit {
public showQRField = '';
public showQRName = '';
public errorMessage = ''; public errorMessage = '';
public messageObjs = []; public messageObjs = [];
public alertTypeEnum = AlertTypeEnum; public alertTypeEnum = AlertTypeEnum;
public dataTypeEnum = DataTypeEnum; public dataTypeEnum = DataTypeEnum;
public screenSize = '';
constructor(public dialogRef: MatDialogRef<AlertMessageComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService, private snackBar: MatSnackBar) { } public screenSizeEnum = ScreenSizeEnum;
constructor(public dialogRef: MatDialogRef<AlertMessageComponent>, @Inject(MAT_DIALOG_DATA) public data: AlertData, private logger: LoggerService, private snackBar: MatSnackBar, private commonService: CommonService) { }
ngOnInit() { ngOnInit() {
this.screenSize = this.commonService.getScreenSize();
this.messageObjs = this.data.message; this.messageObjs = this.data.message;
this.showQRField = this.data.showQRField ? this.data.showQRField : '';
this.showQRName = this.data.showQRName ? this.data.showQRName : '';
if (this.data.type === AlertTypeEnum.ERROR) { if (this.data.type === AlertTypeEnum.ERROR) {
if (undefined === this.data.message && undefined === this.data.titleMessage && this.messageObjs.length <= 0) { if (undefined === this.data.message && undefined === this.data.titleMessage && this.messageObjs.length <= 0) {
this.data.titleMessage = 'Please Check Server Connection'; this.data.titleMessage = 'Please Check Server Connection';
@ -28,6 +37,11 @@ export class AlertMessageComponent implements OnInit {
this.logger.info(this.messageObjs); this.logger.info(this.messageObjs);
} }
onCopyField(payload: string) {
this.snackBar.open(this.showQRName + ' copied');
this.logger.info('Copied Text: ' + payload);
}
onClose() { onClose() {
this.dialogRef.close(false); this.dialogRef.close(false);
} }

View file

@ -1,4 +1,4 @@
<div fxLayout="column" fxFlex="100" fxLayoutAlign="space-between start"> <div perfectScrollbar fxLayout="column" fxFlex="100" fxLayoutAlign="space-between start">
<div fxLayout="column" fxFlex="90" fxLayoutAlign="start stretch" class="w-100"> <div fxLayout="column" fxFlex="90" fxLayoutAlign="start stretch" class="w-100">
<mat-select *ngIf="appConfig.nodes.length > 1" [value]="selNode" (selectionChange)="onNodeSelectionChange($event.value)" class="m-2 multi-node-select"> <mat-select *ngIf="appConfig.nodes.length > 1" [value]="selNode" (selectionChange)="onNodeSelectionChange($event.value)" class="m-2 multi-node-select">
<mat-option *ngFor="let node of appConfig.nodes" [value]="node" tabindex="1"> <mat-option *ngFor="let node of appConfig.nodes" [value]="node" tabindex="1">

View file

@ -3,10 +3,6 @@
<fa-icon [icon]="faCodeBranch" class="fa-icon-small mr-1"></fa-icon> <fa-icon [icon]="faCodeBranch" class="fa-icon-small mr-1"></fa-icon>
<span>Version: {{version}}</span> <span>Version: {{version}}</span>
</p> </p>
<a mat-menu-item routerLink="/advanced">
<fa-icon [icon]="faCog" class="fa-icon-small mr-1"></fa-icon>
<span routerLink="/advanced">Node Config</span>
</a>
<a mat-menu-item routerLink="/help"> <a mat-menu-item routerLink="/help">
<fa-icon [icon]="faLifeRing" class="fa-icon-small mr-1"></fa-icon> <fa-icon [icon]="faLifeRing" class="fa-icon-small mr-1"></fa-icon>
<span routerLink="/help">Help</span> <span routerLink="/help">Help</span>

View file

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

View file

@ -1,93 +0,0 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { LightningNode } from '../../models/RTLconfig';
import { RTLEffects } from '../../../store/rtl.effects';
import * as RTLActions from '../../../store/rtl.actions';
import * as fromRTLReducer from '../../../store/rtl.reducers';
import { faCog } from '@fortawesome/free-solid-svg-icons';
@Component({
selector: 'rtl-server-config',
templateUrl: './server-config.component.html',
styleUrls: ['./server-config.component.scss']
})
export class ServerConfigComponent implements OnInit, OnDestroy {
public selNode: LightningNode;
public selectedNodeType = 'rtl';
public showLnConfig = false;
public lnImplementationStr = '';
public showBitcoind = false;
public configData = '';
public fileFormat = 'INI';
public faCog = faCog;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects) {}
ngOnInit() {
this.store.select('root')
.pipe(takeUntil(this.unSubs[0]))
.subscribe((rtlStore) => {
rtlStore.effectErrorsRoot.forEach(effectsErr => {
if (effectsErr.action === 'fetchConfig') { this.resetData(); }
});
this.configData = '';
this.showLnConfig = false;
this.showBitcoind = false;
this.selNode = rtlStore.selNode;
this.lnImplementationStr = this.selNode.lnImplementation.toUpperCase() === 'CLT' ? 'CLT' : 'LND';
if (undefined !== this.selNode.authentication && undefined !== this.selNode.authentication.configPath && this.selNode.authentication.configPath !== '') {
this.showLnConfig = true;
}
if (undefined !== this.selNode.authentication && undefined !== this.selNode.authentication.bitcoindConfigPath && this.selNode.authentication.bitcoindConfigPath !== '') {
this.showBitcoind = true;
}
if (this.selectedNodeType === 'ln' && !this.showLnConfig) {
this.selectedNodeType = 'rtl';
}
if (this.selectedNodeType === 'bitcoind' && !this.showBitcoind) {
this.selectedNodeType = 'rtl';
}
});
}
onSelectionChange(event) {
this.selectedNodeType = event.value;
this.configData = '';
}
onShowConfig() {
this.store.dispatch(new RTLActions.OpenSpinner('Opening Config File...'));
this.store.dispatch(new RTLActions.FetchConfig(this.selectedNodeType));
this.rtlEffects.showLnConfig
.pipe(takeUntil(this.unSubs[1]))
.subscribe((config: any) => {
console.warn(config);
const configFile = config.data;
this.fileFormat = config.format;
if (configFile !== '' && undefined !== configFile && this.fileFormat === 'INI') {
this.configData = configFile.split('\n');
} else if (configFile !== '' && undefined !== configFile && this.fileFormat === 'JSON') {
this.configData = configFile;
} else {
this.configData = '';
}
});
}
resetData() {
this.configData = '';
this.selectedNodeType = 'rtl';
}
ngOnDestroy() {
this.unSubs.forEach(completeSub => {
completeSub.next();
completeSub.complete();
});
}
}

View file

@ -0,0 +1,51 @@
<div fxLayout="column" fxFlex="100" class="overflow-x-hidden">
<div fxLayout="column" class="settings-container mt-1">
<div fxLayout="column" fxLayout.gt-sm="row" fxFlex="100" fxLayoutAlign="space-between stretch">
<mat-form-field fxFlex="32" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selNode.settings.userPersona" placeholder="User Persona" tabindex="1" required name="userPersona">
<mat-option *ngFor="let userPersona of userPersonas" [value]="userPersona">
{{userPersona | titlecase}}
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="32" fxLayoutAlign="start end" *ngIf="appConfig.nodes.length && appConfig.nodes.length > 1">
<mat-select [(ngModel)]="appConfig.defaultNodeIndex" placeholder="Default Node" tabindex="1" required name="defaultNode">
<mat-option *ngFor="let node of appConfig.nodes" [value]="node.index">
{{node.lnNode}} ({{node.lnImplementation}})
</mat-option>
</mat-select>
</mat-form-field>
<mat-form-field fxFlex="32" fxLayoutAlign="start end">
<mat-select [(ngModel)]="selNode.settings.currencyUnit" placeholder="Currency Unit" (selectionChange)="onCurrencyChange($event)" tabindex="1" required name="currencyUnit">
<mat-option *ngFor="let currencyUnit of currencyUnits" [value]="currencyUnit.id">
{{currencyUnit.id}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div fxLayout="column" fxLayout.gt-sm="row" fxFlex="100" fxLayoutAlign="start stretch" class="mt-1">
<div fxLayout="column" fxFlex="25" fxLayoutAlign="start start" fxLayoutAlign.gt-sm="start space-between">
<h4>Mode</h4>
<mat-radio-group color="primary" [(ngModel)]="selectedThemeMode" (change)="chooseThemeMode()">
<mat-radio-button *ngFor="let themeMode of themeModes" [value]="themeMode" [ngClass]="{'mr-4': screenSize === screenSizeEnum.XS || screenSize === screenSizeEnum.SM}">{{themeMode.name}}
</mat-radio-button>
</mat-radio-group>
</div>
<div fxLayout="column" fxFlex="9"></div>
<div fxLayout="column" fxFlex="40">
<h4>Skins</h4>
<div fxLayout="row" fxFlex="100" fxLayoutAlign="space-between start">
<span *ngFor="let themeColor of themeColors">
<div [class]="themeColor" [ngClass]="{'skin': true, 'selected-color': selectedThemeColor === themeColor}" (click)="changeThemeColor(themeColor)"></div>
</span>
</div>
</div>
</div>
<div fxLayout="row" fxFlex="100" class="mt-4">
<div fxLayout="row" fxFlex="100" fxFlex.gt-sm="50" fxLayoutAlign="space-between stretch">
<button fxFlex="48" fxLayoutAlign="center center" mat-stroked-button color="primary" (click)="onResetSettings()" tabindex="12">Reset</button>
<button fxFlex="48" fxLayoutAlign="center center" mat-raised-button color="primary" (click)="onUpdateSettings()" tabindex="13">Update</button>
</div>
</div>
</div>
</div>

View file

@ -3,15 +3,13 @@ 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 { faTools } from '@fortawesome/free-solid-svg-icons'; import { CURRENCY_UNITS, UserPersonaEnum, ScreenSizeEnum, FIAT_CURRENCY_UNITS } from '../../../services/consts-enums-functions';
import { LightningNode, Settings, RTLConfiguration, GetInfoRoot } from '../../../models/RTLconfig';
import { LoggerService } from '../../../services/logger.service';
import { CommonService } from '../../../services/common.service';
import { CURRENCY_UNITS, AlertTypeEnum, UserPersonaEnum, ScreenSizeEnum } from '../../services/consts-enums-functions'; import * as RTLActions from '../../../../store/rtl.actions';
import { LightningNode, Settings, RTLConfiguration, GetInfoRoot } from '../../models/RTLconfig'; import * as fromRTLReducer from '../../../../store/rtl.reducers';
import { LoggerService } from '../../services/logger.service';
import { CommonService } from '../../services/common.service';
import * as RTLActions from '../../../store/rtl.actions';
import * as fromRTLReducer from '../../../store/rtl.reducers';
@Component({ @Component({
selector: 'rtl-app-settings', selector: 'rtl-app-settings',
@ -19,11 +17,10 @@ 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 faTools = faTools;
public selNode: LightningNode; public selNode: LightningNode;
public information: GetInfoRoot = {}; public information: GetInfoRoot = {};
public userPersonas = [UserPersonaEnum.OPERATOR, UserPersonaEnum.MERCHANT]; public userPersonas = [UserPersonaEnum.OPERATOR, UserPersonaEnum.MERCHANT];
public currencyUnits = [{id: 'USD', name: 'United States Dollar'}, {id: 'GBP', name: 'Pound'}, {id: 'INR', name: 'Indian Rupee'}]; public currencyUnits = FIAT_CURRENCY_UNITS;
public menus = [{id: 'vertical', name: 'Vertical'}, {id: 'horizontal', name: 'Horizontal'}]; public menus = [{id: 'vertical', name: 'Vertical'}, {id: 'horizontal', name: 'Horizontal'}];
public selectedMenu = {id: 'vertical', name: 'Vertical'}; public selectedMenu = {id: 'vertical', name: 'Vertical'};
public menuTypes = [{id: 'regular', name: 'Regular'}, {id: 'compact', name: 'Compact'}, {id: 'mini', name: 'Mini'}]; public menuTypes = [{id: 'regular', name: 'Regular'}, {id: 'compact', name: 'Compact'}, {id: 'mini', name: 'Mini'}];

View file

@ -0,0 +1,22 @@
<div fxLayout="column" fxFlex="100">
<div fxLayout="row" fxFlex="100" fxLayoutAlign="start start">
<div *ngIf="configData !== '' && fileFormat === 'JSON'" fxFlex="100" class="mb-6">
<pre class="pre-wrap">{{configData | json}}</pre>
<mat-divider *ngIf="configData !== ''" class="my-1"></mat-divider>
</div>
<div *ngIf="configData !== '' && fileFormat === 'INI'" fxFlex="100">
<mat-list>
<mat-list-item *ngFor="let conf of configData; index as i;">
<mat-card-subtitle class="my-1">
<h2 *ngIf="conf.indexOf('[') >= 0">{{conf}}</h2>
</mat-card-subtitle>
<mat-card-subtitle class="m-0">
<h4 *ngIf="conf.indexOf('[') < 0" class="ml-4">{{conf}}</h4>
</mat-card-subtitle>
<mat-divider [inset]="true" *ngIf="conf.indexOf('[') < 0"></mat-divider>
</mat-list-item>
</mat-list>
</div>
</div>
</div>

View file

@ -0,0 +1,43 @@
import { Component, OnInit, Input } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { RTLEffects } from '../../../../store/rtl.effects';
import * as RTLActions from '../../../../store/rtl.actions';
import * as fromRTLReducer from '../../../../store/rtl.reducers';
import { faCog } from '@fortawesome/free-solid-svg-icons';
@Component({
selector: 'rtl-server-config',
templateUrl: './server-config.component.html',
styleUrls: ['./server-config.component.scss']
})
export class ServerConfigComponent implements OnInit {
@Input() selectedNodeType = '';
public configData = '';
public fileFormat = 'INI';
public faCog = faCog;
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(private store: Store<fromRTLReducer.RTLState>, private rtlEffects: RTLEffects) {}
ngOnInit() {
this.store.dispatch(new RTLActions.OpenSpinner('Opening Config File...'));
this.store.dispatch(new RTLActions.FetchConfig(this.selectedNodeType));
this.rtlEffects.showLnConfig
.pipe(takeUntil(this.unSubs[1]))
.subscribe((config: any) => {
const configFile = config.data;
this.fileFormat = config.format;
if (configFile !== '' && undefined !== configFile && this.fileFormat === 'INI') {
this.configData = configFile.split('\n');
} else if (configFile !== '' && undefined !== configFile && this.fileFormat === 'JSON') {
this.configData = configFile;
} else {
this.configData = '';
}
});
}
}

View file

@ -0,0 +1,24 @@
<div fxLayout="row" fxLayoutAlign="start center" class="padding-gap-x page-title-container">
<fa-icon [icon]="faTools" class="page-title-img mr-1"></fa-icon>
<span class="page-title">Settings</span>
</div>
<div fxLayout="column" class="padding-gap-x">
<mat-card>
<mat-card-content fxLayout="column">
<mat-tab-group>
<mat-tab label="Settings"><rtl-app-settings></rtl-app-settings></mat-tab>
<mat-tab *ngIf="showLnConfig" [label]="lnImplementationStr">
<ng-template matTabContent>
<rtl-server-config [selectedNodeType]="'ln'"></rtl-server-config>
</ng-template>
</mat-tab>
<mat-tab *ngIf="showBitcoind" label="BitcoinD Config">
<ng-template matTabContent>
<rtl-server-config [selectedNodeType]="'bitcoind'"></rtl-server-config>
</ng-template>
</mat-tab>
</mat-tab-group>
</mat-card-content>
</mat-card>
</div>

View file

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

View file

@ -0,0 +1,49 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { Store } from '@ngrx/store';
import { faTools } from '@fortawesome/free-solid-svg-icons';
import { LightningNode } from '../../models/RTLconfig';
import { RTLEffects } from '../../../store/rtl.effects';
import * as fromRTLReducer from '../../../store/rtl.reducers';
@Component({
selector: 'rtl-settings',
templateUrl: './settings.component.html',
styleUrls: ['./settings.component.scss']
})
export class SettingsComponent implements OnInit, OnDestroy{
public faTools = faTools;
public showLnConfig = false;
public showBitcoind = false;
public selNode: LightningNode;
public lnImplementationStr = '';
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
constructor(private store: Store<fromRTLReducer.RTLState>) {}
ngOnInit() {
this.store.select('root')
.pipe(takeUntil(this.unSubs[0]))
.subscribe((rtlStore) => {
this.showLnConfig = false;
this.showBitcoind = false;
this.selNode = rtlStore.selNode;
this.lnImplementationStr = this.selNode.lnImplementation.toUpperCase() === 'CLT' ? 'CLT Config' : 'LND Config';
if (undefined !== this.selNode.authentication && undefined !== this.selNode.authentication.configPath && this.selNode.authentication.configPath !== '') {
this.showLnConfig = true;
}
if (undefined !== this.selNode.authentication && undefined !== this.selNode.authentication.bitcoindConfigPath && this.selNode.authentication.bitcoindConfigPath !== '') {
this.showBitcoind = true;
}
});
}
ngOnDestroy() {
this.unSubs.forEach(completeSub => {
completeSub.next();
completeSub.complete();
});
}
}

View file

@ -12,7 +12,6 @@ export const MENU_DATA: MenuRootNode = {
{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: 36, parentId: 3, name: 'Network', iconType: 'FA', icon: faNetworkWired, link: '/lnd/network'}
]}, ]},
{id: 4, parentId: 0, name: 'Advanced', iconType: 'FA', icon: faCog, link: '/advanced'},
{id: 5, parentId: 0, name: 'Settings', iconType: 'FA', icon: faTools, link: '/settings'}, {id: 5, parentId: 0, name: 'Settings', iconType: 'FA', icon: faTools, link: '/settings'},
{id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help'} {id: 6, parentId: 0, name: 'Help', iconType: 'FA', icon: faQuestion, link: '/help'}
], ],

View file

@ -8,6 +8,16 @@ export function getPaginatorLabel(field: string) {
export const CURRENCY_UNITS = [ 'Sats', 'BTC' ]; export const CURRENCY_UNITS = [ 'Sats', 'BTC' ];
export const CURRENCY_UNIT_FORMATS = { Sats: '1.0-0', BTC: '1.6-6', OTHER: '1.2-2'}; export const CURRENCY_UNIT_FORMATS = { Sats: '1.0-0', BTC: '1.6-6', OTHER: '1.2-2'};
export const FIAT_CURRENCY_UNITS = [
{id: 'USD', name: 'United States Dollar'},
{id: 'AUD', name: 'AUD'}, {id: 'BRL', name: 'BRL'}, {id: 'CAD', name: 'CAD'},
{id: 'CHF', name: 'CHF'}, {id: 'CLP', name: 'CLP'}, {id: 'CNY', name: 'CNY'},
{id: 'DKK', name: 'DKK'}, {id: 'EUR', name: 'EUR'}, {id: 'GBP', name: 'Pound'},
{id: 'HKD', name: 'HKD'}, {id: 'INR', name: 'Indian Rupee'}, {id: 'ISK', name: 'ISK'},
{id: 'JPY', name: 'JPY'}, {id: 'KRW', name: 'KRW'}, {id: 'NZD', name: 'NZD'},
{id: 'PLN', name: 'PLN'}, {id: 'RUB', name: 'RUB'}, {id: 'SEK', name: 'SEK'},
{id: 'SGD', name: 'SGD'}, {id: 'THB', name: 'THB'}, {id: 'TWD', name: 'TWD'}
];
export const TIME_UNITS = ['SECS', 'MINS', 'HOURS', 'DAYS']; export const TIME_UNITS = ['SECS', 'MINS', 'HOURS', 'DAYS'];

View file

@ -26,7 +26,7 @@ const DEFAULT_PERFECT_SCROLLBAR_CONFIG: PerfectScrollbarConfigInterface = {
import { InvoiceInformationComponent } from './components/data-modal/invoice-information/invoice-information.component'; import { InvoiceInformationComponent } from './components/data-modal/invoice-information/invoice-information.component';
import { OnChainGeneratedAddressComponent } from './components/data-modal/on-chain-generated-address/on-chain-generated-address.component'; import { OnChainGeneratedAddressComponent } from './components/data-modal/on-chain-generated-address/on-chain-generated-address.component';
import { AppSettingsComponent } from './components/app-settings/app-settings.component'; import { AppSettingsComponent } from './components/settings/app-settings/app-settings.component';
import { AlertMessageComponent } from './components/data-modal/alert-message/alert-message.component'; import { AlertMessageComponent } from './components/data-modal/alert-message/alert-message.component';
import { ConfirmationMessageComponent } from './components/data-modal/confirmation-message/confirmation-message.component'; import { ConfirmationMessageComponent } from './components/data-modal/confirmation-message/confirmation-message.component';
import { ErrorMessageComponent } from './components/data-modal/error-message/error-message.component'; import { ErrorMessageComponent } from './components/data-modal/error-message/error-message.component';
@ -37,7 +37,8 @@ import { HelpComponent } from './components/help/help.component';
import { SideNavigationComponent } from './components/navigation/side-navigation/side-navigation.component'; import { SideNavigationComponent } from './components/navigation/side-navigation/side-navigation.component';
import { TopMenuComponent } from './components/navigation/top-menu/top-menu.component'; import { TopMenuComponent } from './components/navigation/top-menu/top-menu.component';
import { HorizontalNavigationComponent } from './components/navigation/horizontal-navigation/horizontal-navigation.component'; import { HorizontalNavigationComponent } from './components/navigation/horizontal-navigation/horizontal-navigation.component';
import { ServerConfigComponent } from './components/server-config/server-config.component'; import { SettingsComponent } from './components/settings/settings.component';
import { ServerConfigComponent } from './components/settings/server-config/server-config.component';
import { ErrorComponent } from './components/error/error.component'; import { ErrorComponent } from './components/error/error.component';
import { CurrencyUnitConverterComponent } from './components/currency-unit-converter/currency-unit-converter.component'; import { CurrencyUnitConverterComponent } from './components/currency-unit-converter/currency-unit-converter.component';
import { ClipboardDirective } from './directive/clipboard.directive'; import { ClipboardDirective } from './directive/clipboard.directive';
@ -126,6 +127,7 @@ import { SocketService } from './services/socket.service';
MatTabsModule, MatTabsModule,
MatSnackBarModule, MatSnackBarModule,
AppSettingsComponent, AppSettingsComponent,
SettingsComponent,
InvoiceInformationComponent, InvoiceInformationComponent,
OnChainGeneratedAddressComponent, OnChainGeneratedAddressComponent,
AlertMessageComponent, AlertMessageComponent,
@ -149,6 +151,7 @@ import { SocketService } from './services/socket.service';
], ],
declarations: [ declarations: [
AppSettingsComponent, AppSettingsComponent,
SettingsComponent,
InvoiceInformationComponent, InvoiceInformationComponent,
OnChainGeneratedAddressComponent, OnChainGeneratedAddressComponent,
AlertMessageComponent, AlertMessageComponent,

View file

@ -88,6 +88,7 @@
padding-top: $regular-font-size; padding-top: $regular-font-size;
} }
.mat-tree .mat-tree-node, .mat-tree .mat-nested-tree-node-parent { .mat-tree .mat-tree-node, .mat-tree .mat-nested-tree-node-parent {
min-height: $tree-node-height;
height: $tree-node-height; height: $tree-node-height;
} }
.mat-primary .mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple), .mat-primary .mat-select-panel .mat-option.mat-selected:not(.mat-option-multiple),

View file

@ -98,6 +98,9 @@
.mat-expansion-panel { .mat-expansion-panel {
border: 1px solid $foreground-secondary-text; border: 1px solid $foreground-secondary-text;
} }
.mat-tab-label, .mat-tab-link {
color: $foreground-secondary-text;
}
} }
&.day { &.day {
@ -171,6 +174,13 @@
border-radius: 4px; border-radius: 4px;
background: none; background: none;
} }
.mat-tab-label, .mat-tab-link {
color: $foreground-secondary-text;
}
.mat-card, .mat-card:not([class*='mat-elevation-z']){
box-shadow: none;
border: 1px solid $foreground-divider;
}
} }
.mat-progress-bar-buffer { .mat-progress-bar-buffer {
@ -181,6 +191,7 @@
color: $foreground-secondary-text !important; color: $foreground-secondary-text !important;
white-space: pre-line; white-space: pre-line;
overflow-wrap: break-word; overflow-wrap: break-word;
word-break: break-all;
} }
.foreground.mat-progress-spinner circle, .foreground.mat-spinner circle { .foreground.mat-progress-spinner circle, .foreground.mat-spinner circle {

View file

@ -17,7 +17,7 @@ $settings-nav-width: 150px;
$gap: 8px; $gap: 8px;
$icon-size: 3.6rem; $icon-size: 3.6rem;
$pubkey-info-height: 15px; $pubkey-info-height: 15px;
$tree-node-height:48px; $tree-node-height:44px;
$fa-icon-small-size: 2rem; $fa-icon-small-size: 2rem;
$fa-icon-regular-size: 4rem; $fa-icon-regular-size: 4rem;

View file

@ -526,8 +526,16 @@ body {
overflow: auto; overflow: auto;
} }
.mat-footer-row, .mat-header-row, .mat-row { .mat-footer-row {
border-bottom-width: 0; & .mat-footer-cell {
border-bottom: none !important;
}
}
.mat-row:last-child {
& .mat-cell {
border-bottom: none !important;
}
} }
.flex-ellipsis { .flex-ellipsis {
@ -737,6 +745,8 @@ a {
} }
.mat-tree-node, .mat-nested-tree-node-parent { .mat-tree-node, .mat-nested-tree-node-parent {
min-height: 4rem;
height: 4rem;
padding: 0 1.2rem 0 1.2rem; padding: 0 1.2rem 0 1.2rem;
cursor: pointer; cursor: pointer;
} }

View file

@ -14,6 +14,7 @@ export const UPDATE_SELECTED_NODE_OPTIONS = 'UPDATE_SELECTED_NODE_OPTIONS';
export const RESET_ROOT_STORE = 'RESET_ROOT_STORE'; export const RESET_ROOT_STORE = 'RESET_ROOT_STORE';
export const CLEAR_EFFECT_ERROR_ROOT = 'CLEAR_EFFECT_ERROR_ROOT'; export const CLEAR_EFFECT_ERROR_ROOT = 'CLEAR_EFFECT_ERROR_ROOT';
export const EFFECT_ERROR_ROOT = 'EFFECT_ERROR_ROOT'; export const EFFECT_ERROR_ROOT = 'EFFECT_ERROR_ROOT';
export const OPEN_SNACK_BAR = 'OPEN_SNACKBAR';
export const OPEN_SPINNER = 'OPEN_SPINNER'; export const OPEN_SPINNER = 'OPEN_SPINNER';
export const CLOSE_SPINNER = 'CLOSE_SPINNER'; export const CLOSE_SPINNER = 'CLOSE_SPINNER';
export const OPEN_ALERT = 'OPEN_ALERT'; export const OPEN_ALERT = 'OPEN_ALERT';
@ -186,6 +187,11 @@ export class EffectErrorCl implements Action {
constructor(public payload: ErrorPayload) {} constructor(public payload: ErrorPayload) {}
} }
export class OpenSnackBar implements Action {
readonly type = OPEN_SNACK_BAR;
constructor(public payload: string) {}
}
export class OpenSpinner implements Action { export class OpenSpinner implements Action {
readonly type = OPEN_SPINNER; readonly type = OPEN_SPINNER;
constructor(public payload: string) {} // payload = titleMessage constructor(public payload: string) {} // payload = titleMessage
@ -824,7 +830,7 @@ export class SetChannelTransactionCL implements Action {
export type RTLActions = export type RTLActions =
ClearEffectErrorRoot | EffectErrorRoot | ClearEffectErrorLnd | EffectErrorLnd | ClearEffectErrorCl | EffectErrorCl | ClearEffectErrorRoot | EffectErrorRoot | ClearEffectErrorLnd | EffectErrorLnd | ClearEffectErrorCl | EffectErrorCl |
VoidAction | 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 | SetNodePendingChannelsData | SetChildNodeSettings | FetchInfo | SetInfo |

View file

@ -45,6 +45,14 @@ export class RTLEffects implements OnDestroy {
private snackBar: MatSnackBar, private snackBar: MatSnackBar,
private router: Router) {} private router: Router) {}
@Effect({ dispatch: false })
openSnackBar = this.actions$.pipe(
ofType(RTLActions.OPEN_SNACK_BAR),
map((action: RTLActions.OpenSnackBar) => {
this.snackBar.open(action.payload);
}
));
@Effect({ dispatch: false }) @Effect({ dispatch: false })
openSpinner = this.actions$.pipe( openSpinner = this.actions$.pipe(
ofType(RTLActions.OPEN_SPINNER), ofType(RTLActions.OPEN_SPINNER),
@ -180,12 +188,8 @@ export class RTLEffects implements OnDestroy {
this.store.dispatch(new RTLActions.CloseSpinner()); this.store.dispatch(new RTLActions.CloseSpinner());
this.logger.info(updateStatus); this.logger.info(updateStatus);
return { return {
type: RTLActions.OPEN_ALERT, type: RTLActions.OPEN_SNACK_BAR,
payload: { width: '55%', data: { payload: (!updateStatus.length) ? updateStatus.message + '.' : updateStatus[0].message + '.'
type: AlertTypeEnum.SUCCESS,
alertTitle: 'Settings updated',
titleMessage: (!updateStatus.length) ? updateStatus.message : updateStatus[0].message + '. ' + updateStatus[1].message
}}
}; };
}, },
catchError((err) => { catchError((err) => {