parent
0948ea139c
commit
75a50e83d5
File diff suppressed because it is too large
Load Diff
@ -1,4 +0,0 @@
|
|||||||
.inline-spinner {
|
|
||||||
display: inline-flex !important;
|
|
||||||
top: 0px !important;
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
|
||||||
import { Subject } from 'rxjs';
|
|
||||||
import { takeUntil, filter } from 'rxjs/operators';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { Actions } from '@ngrx/effects';
|
|
||||||
|
|
||||||
import * as CLActions from './store/cl.actions';
|
|
||||||
import * as RTLActions from '../store/rtl.actions';
|
|
||||||
import * as fromApp from '../store/rtl.reducers';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'rtl-cl-root-app',
|
|
||||||
templateUrl: './cl-root.component.html',
|
|
||||||
styleUrls: ['./cl-root.component.scss']
|
|
||||||
})
|
|
||||||
export class ClRootComponent implements OnInit, OnDestroy {
|
|
||||||
unsubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
|
||||||
|
|
||||||
constructor(private store: Store<fromApp.AppState>, private actions$: Actions, private router: Router, private activatedRoute: ActivatedRoute) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
console.warn('CL ROOT');
|
|
||||||
// this.store.dispatch(new CLActions.FetchCLInfo());
|
|
||||||
this.router.navigate(['./home'], {relativeTo: this.activatedRoute});
|
|
||||||
// this.store.select('cl')
|
|
||||||
// .pipe(takeUntil(this.unsubs[0]))
|
|
||||||
// .subscribe(clStore => {
|
|
||||||
// console.warn(clStore);
|
|
||||||
// if (undefined !== clStore.information.identity_pubkey) {
|
|
||||||
// this.initializeRemainingData();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
// this.actions$
|
|
||||||
// .pipe(
|
|
||||||
// takeUntil(this.unSubs[3]),
|
|
||||||
// filter(action => action.type === RTLActions.INIT_APP_DATA || action.type === LNDActions.SET_INFO || action.type === CLActions.SET_CL_INFO)
|
|
||||||
// ).subscribe((actionPayload: RTLActions.InitAppData | LNDActions.SetInfo | CLActions.SetCLInfo) => {
|
|
||||||
// // if (actionPayload.type === RTLActions.INIT_APP_DATA) {
|
|
||||||
// if(this.information.identity_pubkey) {
|
|
||||||
// this.initializeRemainingData();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeRemainingData() {
|
|
||||||
console.warn('SOMETHING IS WRONG HERE');
|
|
||||||
// this.store.dispatch(new CLActions.FetchCLFees());
|
|
||||||
|
|
||||||
// this.store.dispatch(new CLActions.FetchPeers());
|
|
||||||
// this.store.dispatch(new CLActions.FetchBalance('channels'));
|
|
||||||
// this.store.dispatch(new CLActions.FetchFees());
|
|
||||||
// this.store.dispatch(new CLActions.FetchNetwork());
|
|
||||||
// this.store.dispatch(new CLActions.FetchChannels({routeParam: 'all'}));
|
|
||||||
// this.store.dispatch(new CLActions.FetchChannels({routeParam: 'pending'}));
|
|
||||||
// this.store.dispatch(new CLActions.FetchInvoices({num_max_invoices: 25, reversed: true}));
|
|
||||||
// this.store.dispatch(new CLActions.FetchPayments());
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.unsubs.forEach(unsub => {
|
|
||||||
unsub.next();
|
|
||||||
unsub.complete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
import { CommonModule } from '@angular/common';
|
|
||||||
import { NgxChartsModule } from '@swimlane/ngx-charts';
|
|
||||||
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
|
|
||||||
|
|
||||||
import { environment } from '../../environments/environment';
|
|
||||||
import { SharedModule } from '../shared/shared.module';
|
|
||||||
|
|
||||||
import { clRouting } from './cl.routing';
|
|
||||||
import { ClRootComponent } from './cl-root.component';
|
|
||||||
import { HomeComponent } from './home/home.component';
|
|
||||||
|
|
||||||
@NgModule({
|
|
||||||
imports: [
|
|
||||||
CommonModule,
|
|
||||||
SharedModule,
|
|
||||||
clRouting,
|
|
||||||
NgxChartsModule,
|
|
||||||
!environment.production ? StoreDevtoolsModule.instrument() : []
|
|
||||||
],
|
|
||||||
declarations: [
|
|
||||||
ClRootComponent,
|
|
||||||
HomeComponent
|
|
||||||
],
|
|
||||||
providers: [],
|
|
||||||
bootstrap: [ClRootComponent]
|
|
||||||
})
|
|
||||||
export class ClModule {}
|
|
@ -1,19 +0,0 @@
|
|||||||
import { Routes, RouterModule } from '@angular/router';
|
|
||||||
import { ModuleWithProviders } from '@angular/core';
|
|
||||||
|
|
||||||
import { AuthGuard } from '../shared/services/auth.guard';
|
|
||||||
import { NotFoundComponent } from '../shared/components/not-found/not-found.component';
|
|
||||||
|
|
||||||
import { ClRootComponent } from './cl-root.component';
|
|
||||||
import { HomeComponent } from './home/home.component';
|
|
||||||
|
|
||||||
export const clRoutes: Routes = [
|
|
||||||
{ path: '', component: ClRootComponent,
|
|
||||||
children: [
|
|
||||||
{ path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
|
|
||||||
{ path: '**', component: NotFoundComponent }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
export const clRouting: ModuleWithProviders = RouterModule.forChild(clRoutes);
|
|
@ -1,2 +0,0 @@
|
|||||||
<h4>CL Home</h4>
|
|
||||||
<p>{{information | json}}</p>
|
|
@ -1,56 +0,0 @@
|
|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
|
||||||
import { Subject } from 'rxjs';
|
|
||||||
import { takeUntil } from 'rxjs/operators';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
|
|
||||||
import { LoggerService } from '../../shared/services/logger.service';
|
|
||||||
import { GetInfo } from '../../shared/models/clModels';
|
|
||||||
|
|
||||||
import * as fromApp from '../../store/rtl.reducers';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'rtl-home',
|
|
||||||
templateUrl: './home.component.html',
|
|
||||||
styleUrls: ['./home.component.scss']
|
|
||||||
})
|
|
||||||
export class HomeComponent implements OnInit, OnDestroy {
|
|
||||||
public information: GetInfo = {};
|
|
||||||
private unsubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
|
||||||
|
|
||||||
constructor(private logger: LoggerService, private store: Store<fromApp.AppState>) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
console.warn('CL HOME');
|
|
||||||
this.store.select('cl')
|
|
||||||
.pipe(takeUntil(this.unsubs[1]))
|
|
||||||
.subscribe(clStore => {
|
|
||||||
this.information = clStore.information;
|
|
||||||
if (undefined !== this.information.identity_pubkey) {
|
|
||||||
this.initializeRemainingData();
|
|
||||||
}
|
|
||||||
this.logger.info(clStore);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
initializeRemainingData() {
|
|
||||||
console.warn('SOMETHING IS WRONG HERE');
|
|
||||||
// this.store.dispatch(new CLActions.FetchCLFees());
|
|
||||||
|
|
||||||
// this.store.dispatch(new CLActions.FetchPeers());
|
|
||||||
// this.store.dispatch(new CLActions.FetchBalance('channels'));
|
|
||||||
// this.store.dispatch(new CLActions.FetchFees());
|
|
||||||
// this.store.dispatch(new CLActions.FetchNetwork());
|
|
||||||
// this.store.dispatch(new CLActions.FetchChannels({routeParam: 'all'}));
|
|
||||||
// this.store.dispatch(new CLActions.FetchChannels({routeParam: 'pending'}));
|
|
||||||
// this.store.dispatch(new CLActions.FetchInvoices({num_max_invoices: 25, reversed: true}));
|
|
||||||
// this.store.dispatch(new CLActions.FetchPayments());
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.unsubs.forEach(completeSub => {
|
|
||||||
completeSub.next();
|
|
||||||
completeSub.complete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
import { Action } from '@ngrx/store';
|
|
||||||
import { GetInfo } from '../../shared/models/clModels';
|
|
||||||
|
|
||||||
export const RESET_CL_STORE = 'RESET_CL_STORE';
|
|
||||||
export const FETCH_CL_INFO = 'FETCH_CL_INFO';
|
|
||||||
export const SET_CL_INFO = 'SET_CL_INFO';
|
|
||||||
export const FETCH_CL_FEES = 'FETCH_CL_FEES';
|
|
||||||
export const SET_CL_FEES = 'SET_CL_FEES';
|
|
||||||
|
|
||||||
export class ResetCLStore implements Action {
|
|
||||||
readonly type = RESET_CL_STORE;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class FetchCLInfo implements Action {
|
|
||||||
readonly type = FETCH_CL_INFO;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SetCLInfo implements Action {
|
|
||||||
readonly type = SET_CL_INFO;
|
|
||||||
constructor(public payload: GetInfo) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class FetchCLFees implements Action {
|
|
||||||
readonly type = FETCH_CL_FEES;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SetCLFees implements Action {
|
|
||||||
readonly type = SET_CL_FEES;
|
|
||||||
constructor(public payload: {}) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CLActions =
|
|
||||||
ResetCLStore | FetchCLInfo | SetCLInfo | FetchCLFees | SetCLFees;
|
|
@ -1,102 +0,0 @@
|
|||||||
import { Injectable, OnDestroy } from '@angular/core';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { Actions, Effect, ofType } from '@ngrx/effects';
|
|
||||||
import { of, Subject } from 'rxjs';
|
|
||||||
import { map, mergeMap, catchError, withLatestFrom } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { MatDialog } from '@angular/material';
|
|
||||||
|
|
||||||
import { environment } from '../../../environments/environment';
|
|
||||||
import { LoggerService } from '../../shared/services/logger.service';
|
|
||||||
import { GetInfo } from '../../shared/models/clModels';
|
|
||||||
|
|
||||||
import * as RTLActions from '../../store/rtl.actions';
|
|
||||||
import * as CLActions from './cl.actions';
|
|
||||||
import * as fromApp from '../../store/rtl.reducers';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class CLEffects implements OnDestroy {
|
|
||||||
dialogRef: any;
|
|
||||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private actions$: Actions,
|
|
||||||
private httpClient: HttpClient,
|
|
||||||
private store: Store<fromApp.AppState>,
|
|
||||||
private logger: LoggerService,
|
|
||||||
public dialog: MatDialog,
|
|
||||||
private router: Router,
|
|
||||||
private activatedRoute: ActivatedRoute) { }
|
|
||||||
|
|
||||||
@Effect()
|
|
||||||
infoFetch = this.actions$.pipe(
|
|
||||||
ofType(CLActions.FETCH_CL_INFO),
|
|
||||||
withLatestFrom(this.store.select('rtlRoot')),
|
|
||||||
mergeMap(([action, store]: [CLActions.FetchCLInfo, fromApp.RootState]) => {
|
|
||||||
this.store.dispatch(new RTLActions.ClearEffectError('FetchInfo'));
|
|
||||||
return this.httpClient.get<GetInfo>(environment.GETINFO_API)
|
|
||||||
.pipe(
|
|
||||||
map((info) => {
|
|
||||||
this.logger.info(info);
|
|
||||||
if (undefined === info.identity_pubkey) {
|
|
||||||
sessionStorage.removeItem('clUnlocked');
|
|
||||||
return {
|
|
||||||
type: CLActions.SET_CL_INFO,
|
|
||||||
payload: {}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
sessionStorage.setItem('clUnlocked', 'true');
|
|
||||||
return {
|
|
||||||
type: CLActions.SET_CL_INFO,
|
|
||||||
payload: (undefined !== info) ? info : {}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
catchError((err) => {
|
|
||||||
this.logger.error(err);
|
|
||||||
this.store.dispatch(new RTLActions.EffectError({ action: 'FetchInfo', code: err.status, message: err.error.error }));
|
|
||||||
if (+store.appConfig.sso.rtlSSO) {
|
|
||||||
this.router.navigate(['../ssoerror'], {relativeTo: this.activatedRoute});
|
|
||||||
} else {
|
|
||||||
if (err.status === 401) {
|
|
||||||
this.logger.info('Redirecting to Signin');
|
|
||||||
this.router.navigate([store.appConfig.sso.logoutRedirectLink], {relativeTo: this.activatedRoute});
|
|
||||||
return of();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
@Effect()
|
|
||||||
fetchFees = this.actions$.pipe(
|
|
||||||
ofType(CLActions.FETCH_CL_FEES),
|
|
||||||
mergeMap((action: CLActions.FetchCLFees) => {
|
|
||||||
this.store.dispatch(new RTLActions.ClearEffectError('FetchCLFees'));
|
|
||||||
return this.httpClient.get(environment.FEES_API);
|
|
||||||
}),
|
|
||||||
map((fees) => {
|
|
||||||
this.logger.info(fees);
|
|
||||||
return {
|
|
||||||
type: CLActions.SET_CL_FEES,
|
|
||||||
payload: (undefined !== fees) ? fees : {}
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
catchError((err: any) => {
|
|
||||||
this.logger.error(err);
|
|
||||||
this.store.dispatch(new RTLActions.EffectError({ action: 'FetchCLFees', code: err.status, message: err.error.error }));
|
|
||||||
return of();
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.unSubs.forEach(completeSub => {
|
|
||||||
completeSub.next();
|
|
||||||
completeSub.complete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
import * as CLActions from './cl.actions';
|
|
||||||
import { GetInfo, GetInfoChain } from '../../shared/models/clModels';
|
|
||||||
|
|
||||||
export interface CLState {
|
|
||||||
information: GetInfo;
|
|
||||||
fees: {};
|
|
||||||
}
|
|
||||||
|
|
||||||
export const CLInitialState: CLState = {
|
|
||||||
information: {},
|
|
||||||
fees: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
export function CLReducer(state = CLInitialState, action: CLActions.CLActions) {
|
|
||||||
switch (action.type) {
|
|
||||||
case CLActions.RESET_CL_STORE:
|
|
||||||
return {
|
|
||||||
...CLInitialState
|
|
||||||
};
|
|
||||||
case CLActions.SET_CL_INFO:
|
|
||||||
if (undefined !== action.payload.chains) {
|
|
||||||
if (typeof action.payload.chains[0] === 'string') {
|
|
||||||
action.payload.smaller_currency_unit = (action.payload.chains[0].toString().toLowerCase().indexOf('bitcoin') < 0) ? 'Litoshis' : 'Sats';
|
|
||||||
action.payload.currency_unit = (action.payload.chains[0].toString().toLowerCase().indexOf('bitcoin') < 0) ? 'LTC' : 'BTC';
|
|
||||||
} else if (typeof action.payload.chains[0] === 'object' && action.payload.chains[0].hasOwnProperty('chain')) {
|
|
||||||
const getInfoChain = <GetInfoChain>action.payload.chains[0];
|
|
||||||
action.payload.smaller_currency_unit = (getInfoChain.chain.toLowerCase().indexOf('bitcoin') < 0) ? 'Litoshis' : 'Sats';
|
|
||||||
action.payload.currency_unit = (getInfoChain.chain.toLowerCase().indexOf('bitcoin') < 0) ? 'LTC' : 'BTC';
|
|
||||||
}
|
|
||||||
action.payload.version = (undefined === action.payload.version) ? '' : action.payload.version.split(' ')[0];
|
|
||||||
} else {
|
|
||||||
action.payload.smaller_currency_unit = 'Sats';
|
|
||||||
action.payload.currency_unit = 'BTC';
|
|
||||||
action.payload.version = (undefined === action.payload.version) ? '' : action.payload.version.split(' ')[0];
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
information: action.payload
|
|
||||||
};
|
|
||||||
case CLActions.SET_CL_FEES:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
fees: action.payload
|
|
||||||
};
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,166 @@
|
|||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'rtl-cl-root',
|
||||||
|
templateUrl: './cl-root.component.html',
|
||||||
|
styleUrls: ['./cl-root.component.scss']
|
||||||
|
})
|
||||||
|
export class CLRootComponent implements OnInit {
|
||||||
|
|
||||||
|
constructor(private router: Router, private activatedRoute: ActivatedRoute) {}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
console.warn('CL ROOT');
|
||||||
|
this.router.navigate(['./home'], {relativeTo: this.activatedRoute});
|
||||||
|
}
|
||||||
|
|
||||||
|
// @ViewChild('sideNavigation', { static: false }) sideNavigation: any;
|
||||||
|
// @ViewChild('settingSidenav', { static: true }) settingSidenav: any;
|
||||||
|
// public selNode: Node;
|
||||||
|
// public settings: Settings;
|
||||||
|
// public information: GetInfo = {};
|
||||||
|
// public flgLoading: Array<Boolean | 'error'> = [true]; // 0: Info
|
||||||
|
// public flgCopied = false;
|
||||||
|
// public appConfig: RTLConfiguration;
|
||||||
|
// public accessKey = '';
|
||||||
|
// public smallScreen = false;
|
||||||
|
// unsubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
|
||||||
|
|
||||||
|
// constructor(private logger: LoggerService, private store: Store<fromRTLReducer.State>, private actions$: Actions,
|
||||||
|
// private userIdle: UserIdleService, private router: Router) {}
|
||||||
|
|
||||||
|
// ngOnInit() {
|
||||||
|
// this.store.dispatch(new RTLActions.FetchRTLConfig());
|
||||||
|
// this.accessKey = this.readAccessKey();
|
||||||
|
// this.store.select('rtlRoot')
|
||||||
|
// .pipe(takeUntil(this.unsubs[0]))
|
||||||
|
// .subscribe(rtlStore => {
|
||||||
|
// this.selNode = rtlStore.selNode;
|
||||||
|
// this.settings = this.selNode.settings;
|
||||||
|
// this.appConfig = rtlStore.appConfig;
|
||||||
|
// this.information = rtlStore.information;
|
||||||
|
// this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true;
|
||||||
|
// if (window.innerWidth <= 768) {
|
||||||
|
// this.settings.menu = 'Vertical';
|
||||||
|
// this.settings.flgSidenavOpened = false;
|
||||||
|
// this.settings.flgSidenavPinned = false;
|
||||||
|
// }
|
||||||
|
// if (window.innerWidth <= 414) {
|
||||||
|
// this.smallScreen = true;
|
||||||
|
// }
|
||||||
|
// this.logger.info(this.settings);
|
||||||
|
// if (!sessionStorage.getItem('token')) {
|
||||||
|
// this.flgLoading[0] = false;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// if (sessionStorage.getItem('token')) {
|
||||||
|
// this.store.dispatch(new RTLActions.FetchInfo());
|
||||||
|
// }
|
||||||
|
// this.actions$
|
||||||
|
// .pipe(
|
||||||
|
// takeUntil(this.unsubs[1]),
|
||||||
|
// filter((action) => action.type === RTLActions.INIT_APP_DATA || action.type === RTLActions.SET_RTL_CONFIG)
|
||||||
|
// ).subscribe((actionPayload: (RTLActions.InitAppData | RTLActions.SetRTLConfig)) => {
|
||||||
|
// if (actionPayload.type === RTLActions.SET_RTL_CONFIG) {
|
||||||
|
// if (!sessionStorage.getItem('token')) {
|
||||||
|
// if (+actionPayload.payload.sso.rtlSSO) {
|
||||||
|
// this.store.dispatch(new RTLActions.Signin(sha256(this.accessKey)));
|
||||||
|
// } else {
|
||||||
|
// this.router.navigate([this.appConfig.sso.logoutRedirectLink]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (
|
||||||
|
// this.settings.menu === 'Horizontal' ||
|
||||||
|
// this.settings.menuType === 'Compact' ||
|
||||||
|
// this.settings.menuType === 'Mini') {
|
||||||
|
// this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed
|
||||||
|
// setTimeout(() => { this.settingSidenav.toggle(); }, 100);
|
||||||
|
// }
|
||||||
|
// } else if (actionPayload.type === RTLActions.INIT_APP_DATA) {
|
||||||
|
// this.store.dispatch(new RTLActions.FetchInfo());
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// this.actions$
|
||||||
|
// .pipe(
|
||||||
|
// takeUntil(this.unsubs[1]),
|
||||||
|
// filter((action) => action.type === RTLActions.SET_INFO)
|
||||||
|
// ).subscribe((infoData: RTLActions.SetInfo) => {
|
||||||
|
// if (undefined !== infoData.payload.identity_pubkey) {
|
||||||
|
// this.initializeRemainingData();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// this.userIdle.startWatching();
|
||||||
|
// this.userIdle.onTimerStart().subscribe(count => {});
|
||||||
|
// this.userIdle.onTimeout().subscribe(() => {
|
||||||
|
// if (sessionStorage.getItem('token')) {
|
||||||
|
// this.logger.warn('Time limit exceeded for session inactivity! Logging out!');
|
||||||
|
// this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
|
||||||
|
// type: 'WARN',
|
||||||
|
// titleMessage: 'Time limit exceeded for session inactivity! Logging out!'
|
||||||
|
// }}));
|
||||||
|
// this.store.dispatch(new RTLActions.Signout());
|
||||||
|
// this.userIdle.resetTimer();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private readAccessKey() {
|
||||||
|
// const url = window.location.href;
|
||||||
|
// return url.substring(url.lastIndexOf('access-key=') + 11).trim();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// initializeRemainingData() {
|
||||||
|
// this.store.dispatch(new RTLActions.FetchPeers());
|
||||||
|
// this.store.dispatch(new RTLActions.FetchBalance('channels'));
|
||||||
|
// this.store.dispatch(new RTLActions.FetchFees());
|
||||||
|
// this.store.dispatch(new RTLActions.FetchNetwork());
|
||||||
|
// this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all'}));
|
||||||
|
// this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'pending'}));
|
||||||
|
// this.store.dispatch(new RTLActions.FetchInvoices({num_max_invoices: 25, reversed: true}));
|
||||||
|
// this.store.dispatch(new RTLActions.FetchPayments());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ngAfterViewInit() {
|
||||||
|
// if (!this.settings.flgSidenavPinned) {
|
||||||
|
// this.sideNavigation.close();
|
||||||
|
// this.settingSidenav.toggle();
|
||||||
|
// }
|
||||||
|
// if (window.innerWidth <= 768) {
|
||||||
|
// this.sideNavigation.close();
|
||||||
|
// this.settingSidenav.toggle();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @HostListener('window:resize')
|
||||||
|
// public onWindowResize(): void {
|
||||||
|
// if (window.innerWidth <= 768) {
|
||||||
|
// this.settings.menu = 'Vertical';
|
||||||
|
// this.settings.flgSidenavOpened = false;
|
||||||
|
// this.settings.flgSidenavPinned = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// sideNavToggle() {
|
||||||
|
// this.sideNavigation.toggle();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// onNavigationClicked(event: any) {
|
||||||
|
// if (window.innerWidth <= 414) {
|
||||||
|
// this.sideNavigation.close();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// copiedText(payload) {
|
||||||
|
// this.flgCopied = true;
|
||||||
|
// setTimeout(() => {this.flgCopied = false; }, 5000);
|
||||||
|
// this.logger.info('Copied Text: ' + payload);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ngOnDestroy() {
|
||||||
|
// this.unsubs.forEach(unsub => {
|
||||||
|
// unsub.next();
|
||||||
|
// unsub.complete();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
|
import { CLRouting } from './cl.routing';
|
||||||
|
import { SharedModule } from '../shared/shared.module';
|
||||||
|
|
||||||
|
import { CLRootComponent } from './cl-root.component';
|
||||||
|
import { CLHomeComponent } from './home/home.component';
|
||||||
|
|
||||||
|
import { CommonService } from '../shared/services/common.service';
|
||||||
|
import { LoggerService, ConsoleLoggerService } from '../shared/services/logger.service';
|
||||||
|
import { CLUnlockedGuard } from '../shared/services/auth.guard';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
CommonModule,
|
||||||
|
SharedModule,
|
||||||
|
CLRouting
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
CLRootComponent,
|
||||||
|
CLHomeComponent
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: LoggerService, useClass: ConsoleLoggerService },
|
||||||
|
CLUnlockedGuard,
|
||||||
|
CommonService
|
||||||
|
],
|
||||||
|
bootstrap: [CLRootComponent]
|
||||||
|
})
|
||||||
|
export class CLModule {}
|
@ -0,0 +1,18 @@
|
|||||||
|
import { Routes, RouterModule } from '@angular/router';
|
||||||
|
import { ModuleWithProviders } from '@angular/core';
|
||||||
|
|
||||||
|
import { CLRootComponent } from './cl-root.component';
|
||||||
|
import { CLHomeComponent } from './home/home.component';
|
||||||
|
|
||||||
|
import { CLUnlockedGuard } from '../shared/services/auth.guard';
|
||||||
|
import { NotFoundComponent } from '../shared/components/not-found/not-found.component';
|
||||||
|
|
||||||
|
export const ClRoutes: Routes = [
|
||||||
|
{ path: '', component: CLRootComponent,
|
||||||
|
children: [
|
||||||
|
{ path: 'home', component: CLHomeComponent, canActivate: [CLUnlockedGuard] },
|
||||||
|
{ path: '**', component: NotFoundComponent }
|
||||||
|
]}
|
||||||
|
];
|
||||||
|
|
||||||
|
export const CLRouting: ModuleWithProviders = RouterModule.forChild(ClRoutes);
|
@ -0,0 +1,237 @@
|
|||||||
|
<div fxLayout="column" fxLayout.gt-sm="row wrap">
|
||||||
|
<div fxFlex="25" class="padding-gap">
|
||||||
|
<mat-card [ngClass]="{'custom-card error-border': flgLoading[2]==='error','custom-card': true}">
|
||||||
|
<mat-card-header class="bg-primary" fxLayoutAlign="center end">
|
||||||
|
<mat-card-title class="m-0 pt-2">
|
||||||
|
<h5>Wallet Balance</h5>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content fxLayout="column" fxLayoutAlign="center center">
|
||||||
|
<mat-card-content class="mt-1">
|
||||||
|
<mat-icon class="icon-large">account_balance_wallet</mat-icon>
|
||||||
|
</mat-card-content>
|
||||||
|
<span *ngIf="information?.currency_unit; else withoutData">
|
||||||
|
<h3 *ngIf="selNode?.settings?.satsToBTC; else smallerUnit1">{{BTCtotalBalance | number}} {{information?.currency_unit}}</h3>
|
||||||
|
<ng-template #smallerUnit1><h3>{{totalBalance | number}} {{information?.smaller_currency_unit}}</h3></ng-template>
|
||||||
|
</span>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-progress-bar class="mt-minus-5" *ngIf="flgLoading[2]===true" mode="indeterminate"></mat-progress-bar>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
<div fxFlex="25" class="padding-gap">
|
||||||
|
<mat-card [ngClass]="{'custom-card error-border': flgLoading[0]==='error','custom-card': true}">
|
||||||
|
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
|
||||||
|
<mat-card-title class="m-0 pt-2">
|
||||||
|
<h5>Peers</h5>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content fxLayout="column" fxLayoutAlign="center center">
|
||||||
|
<mat-card-content class="mt-1">
|
||||||
|
<mat-icon class="icon-large">group</mat-icon>
|
||||||
|
</mat-card-content>
|
||||||
|
<h3 *ngIf="information.num_peers; else zeroPeers">{{totalPeers | number}}</h3>
|
||||||
|
<ng-template #zeroPeers>
|
||||||
|
<h3>0</h3>
|
||||||
|
</ng-template>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-progress-bar class="mt-minus-5" *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
<div fxFlex="25" class="padding-gap">
|
||||||
|
<mat-card [ngClass]="{'custom-card error-border': flgLoading[3]==='error','custom-card': true}">
|
||||||
|
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
|
||||||
|
<mat-card-title class="m-0 pt-2">
|
||||||
|
<h5>Channel Balance</h5>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content fxLayout="column" fxLayoutAlign="center center">
|
||||||
|
<mat-card-content class="mt-1">
|
||||||
|
<mat-icon class="icon-large">linear_scale</mat-icon>
|
||||||
|
</mat-card-content>
|
||||||
|
<span *ngIf="information?.currency_unit; else withoutData">
|
||||||
|
<h3 *ngIf="selNode?.settings?.satsToBTC; else smallerUnit2">{{BTCchannelBalance | number}} {{information?.currency_unit}}</h3>
|
||||||
|
<ng-template #smallerUnit2><h3>{{channelBalance | number}} {{information?.smaller_currency_unit}}</h3></ng-template>
|
||||||
|
</span>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-progress-bar class="mt-minus-5" *ngIf="flgLoading[3]===true || flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
<div fxFlex="25" class="padding-gap">
|
||||||
|
<mat-card [ngClass]="{'custom-card error-border': flgLoading[0]==='error','custom-card': true}">
|
||||||
|
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
|
||||||
|
<mat-card-title class="m-0 pt-2">
|
||||||
|
<h5>Chain Sync Status</h5>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content fxLayout="column" fxLayoutAlign="center center">
|
||||||
|
<mat-card-content class="mt-1">
|
||||||
|
<mat-icon class="icon-large">sync</mat-icon>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-icon *ngIf="information?.synced_to_chain; else notSynced" class="size-30 green sync-to-chain">check_circle</mat-icon>
|
||||||
|
<ng-template #notSynced>
|
||||||
|
<mat-icon class="size-30 red">cancel</mat-icon>
|
||||||
|
</ng-template>
|
||||||
|
</mat-card-content>
|
||||||
|
<mat-progress-bar class="mt-minus-5" *ngIf="flgLoading[0]===true" mode="indeterminate"></mat-progress-bar>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div fxLayout="column" fxLayout.gt-sm="row wrap">
|
||||||
|
<div fxFlex="25" class="padding-gap">
|
||||||
|
<div fxLayout="column">
|
||||||
|
<mat-card fxFlex="100" [ngClass]="{'custom-card error-border': flgLoading[1]==='error','custom-card': true}">
|
||||||
|
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
|
||||||
|
<mat-card-title class="m-0 pt-2">
|
||||||
|
<h5>Fee Report</h5>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<div fxLayout="column" class="pl-4">
|
||||||
|
<mat-list fxFlex="100" fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Daily ({{information?.smaller_currency_unit}})</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start">{{fees?.day_fee_sum}}</mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxFlex="100" fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Weekly ({{information?.smaller_currency_unit}})</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start">{{fees?.week_fee_sum}}</mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxFlex="100" fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Monthly ({{information?.smaller_currency_unit}})</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start">{{fees?.month_fee_sum}}</mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
</div>
|
||||||
|
<mat-progress-bar *ngIf="flgLoading[1]===true" mode="indeterminate"></mat-progress-bar>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
<mat-card fxFlex="100" [ngClass]="{'mt-2 custom-card error-border': flgLoading[5]==='error','mt-2 custom-card': true}">
|
||||||
|
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
|
||||||
|
<mat-card-title class="m-0 pt-2">
|
||||||
|
<h5>Channel Status</h5>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<div fxLayout="column" class="pl-4">
|
||||||
|
<mat-list fxFlex="100" fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Active</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start"><p class="mat-button-text pt-2">{{activeChannels}}</p></mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxFlex="100" fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Inactive</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start"><p class="mat-button-text pt-2">{{inactiveChannels}}</p></mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxFlex="100" fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Pending</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start"><p class="mat-button-text pt-2">{{pendingChannels}}</p></mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
</div>
|
||||||
|
<mat-progress-bar *ngIf="flgLoading[6]===true" mode="indeterminate" class="mt-minus-5"></mat-progress-bar>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div fxFlex="40" class="padding-gap">
|
||||||
|
<mat-card [ngClass]="{'custom-card error-border': flgLoading[5]==='error','custom-card': true}">
|
||||||
|
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
|
||||||
|
<mat-card-title class="m-0 pt-2">
|
||||||
|
<h5>Local-Remote Channel Capacity</h5>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<div fxLayout="row" class="card-chnl-balances">
|
||||||
|
<div fxFlex="100" fxLayoutAlign="center center" *ngIf="flgTotalCalculated">
|
||||||
|
<ngx-charts-bar-vertical
|
||||||
|
[view]="view"
|
||||||
|
[scheme]="colorScheme"
|
||||||
|
[results]="totalBalances"
|
||||||
|
[yAxisLabel]="yAxisLabel"
|
||||||
|
[yScaleMax]="maxBalanceValue"
|
||||||
|
xAxis="false"
|
||||||
|
yAxis="true"
|
||||||
|
showYAxis="true"
|
||||||
|
showDataLabel="true"
|
||||||
|
tooltipDisabled="true">
|
||||||
|
</ngx-charts-bar-vertical>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mat-progress-bar *ngIf="flgLoading[5]===true" mode="indeterminate" class="mt-minus-5"></mat-progress-bar>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
<div fxFlex="35" class="padding-gap">
|
||||||
|
<mat-card [ngClass]="{'custom-card error-border': flgLoading[5]==='error','custom-card': true}">
|
||||||
|
<mat-card-header class="bg-primary" fxLayoutAlign="center center">
|
||||||
|
<mat-card-title class="m-0 pt-2">
|
||||||
|
<h5>Network Information</h5>
|
||||||
|
</mat-card-title>
|
||||||
|
</mat-card-header>
|
||||||
|
<mat-card-content>
|
||||||
|
<div fxLayout="column" class="pl-4 network-info-list">
|
||||||
|
<mat-list fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start" *ngIf="selNode?.settings?.satsToBTC; else smallerUnit6">Network Capacity ({{information?.currency_unit}})</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start" *ngIf="selNode?.settings?.satsToBTC; else smallerData6">{{networkInfo?.btc_total_network_capacity | number}}</mat-list-item>
|
||||||
|
<ng-template #smallerUnit6><mat-list-item fxFlex="65" fxLayoutAlign="start start">Network Capacity ({{information?.smaller_currency_unit}})</mat-list-item></ng-template>
|
||||||
|
<ng-template #smallerData6><mat-list-item fxFlex="25" fxLayoutAlign="end start">{{networkInfo?.total_network_capacity | number}}</mat-list-item></ng-template>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Number of Nodes</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start">{{networkInfo?.num_nodes | number}}</mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Number of Channels</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start">{{networkInfo?.num_channels | number}}</mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Max Out Degree</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start">{{networkInfo?.max_out_degree | number}}</mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start">Avg Out Degree</mat-list-item>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start">{{networkInfo?.avg_out_degree | number:'1.0-2'}}</mat-list-item>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start" *ngIf="selNode?.settings?.satsToBTC; else smallerUnit7">Max Channel Size ({{information?.currency_unit}})</mat-list-item>
|
||||||
|
<ng-template #smallerUnit7><mat-list-item fxFlex="65" fxLayoutAlign="start start">Max Channel Size ({{information?.smaller_currency_unit}})</mat-list-item></ng-template>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start" *ngIf="selNode?.settings?.satsToBTC; else smallerData7">{{networkInfo?.btc_max_channel_size | number}}</mat-list-item>
|
||||||
|
<ng-template #smallerData7><mat-list-item fxFlex="25" fxLayoutAlign="end start">{{networkInfo?.max_channel_size | number}}</mat-list-item></ng-template>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start" *ngIf="selNode?.settings?.satsToBTC; else smallerUnit8">Avg Channel Size ({{information?.currency_unit}})</mat-list-item>
|
||||||
|
<ng-template #smallerUnit8><mat-list-item fxFlex="65" fxLayoutAlign="start start">Avg Channel Size ({{information?.smaller_currency_unit}})</mat-list-item></ng-template>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start" *ngIf="selNode?.settings?.satsToBTC; else smallerData8">{{networkInfo?.btc_avg_channel_size | number}}</mat-list-item>
|
||||||
|
<ng-template #smallerData8><mat-list-item fxFlex="25" fxLayoutAlign="end start">{{networkInfo?.avg_channel_size | number:'1.0-2'}}</mat-list-item></ng-template>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
<mat-list fxLayoutAlign="start start">
|
||||||
|
<mat-list-item fxFlex="65" fxLayoutAlign="start start" *ngIf="selNode?.settings?.satsToBTC; else smallerUnit9">Min Channel Size ({{information?.currency_unit}})</mat-list-item>
|
||||||
|
<ng-template #smallerUnit9><mat-list-item fxFlex="65" fxLayoutAlign="start start">Min Channel Size ({{information?.smaller_currency_unit}})</mat-list-item></ng-template>
|
||||||
|
<mat-list-item fxFlex="25" fxLayoutAlign="end start" *ngIf="selNode?.settings?.satsToBTC; else smallerData9">{{networkInfo?.btc_min_channel_size | number}}</mat-list-item>
|
||||||
|
<ng-template #smallerData9><mat-list-item fxFlex="25" fxLayoutAlign="end start">{{networkInfo?.min_channel_size | number}}</mat-list-item></ng-template>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-list>
|
||||||
|
</div>
|
||||||
|
<mat-progress-bar *ngIf="flgLoading[4]===true" mode="indeterminate"></mat-progress-bar>
|
||||||
|
<mat-divider></mat-divider>
|
||||||
|
</mat-card-content>
|
||||||
|
</mat-card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ng-template #withoutData><h3>Sats</h3></ng-template>
|
@ -0,0 +1,12 @@
|
|||||||
|
.network-info-list .mat-list-item {
|
||||||
|
height: 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mat-column-bytes_sent, .mat-column-bytes_recv, .mat-column-sat_sent, .mat-column-sat_recv, .mat-column-inbound, .mat-column-ping_time {
|
||||||
|
flex: 0 0 8%;
|
||||||
|
min-width: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-chnl-balances {
|
||||||
|
min-height: 354px;
|
||||||
|
}
|
@ -0,0 +1,148 @@
|
|||||||
|
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||||
|
import { Subject } from 'rxjs';
|
||||||
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
import { Store } from '@ngrx/store';
|
||||||
|
|
||||||
|
import { LoggerService } from '../../shared/services/logger.service';
|
||||||
|
import { GetInfo, NetworkInfo, Fees, Peer } from '../../shared/models/lndModels';
|
||||||
|
import { Node } from '../../shared/models/RTLconfig';
|
||||||
|
|
||||||
|
import * as fromRTLReducer from '../../shared/store/rtl.reducers';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'rtl-cl-home',
|
||||||
|
templateUrl: './home.component.html',
|
||||||
|
styleUrls: ['./home.component.scss']
|
||||||
|
})
|
||||||
|
export class CLHomeComponent implements OnInit, OnDestroy {
|
||||||
|
public selNode: Node;
|
||||||
|
public fees: Fees;
|
||||||
|
public information: GetInfo = {};
|
||||||
|
public remainder = 0;
|
||||||
|
public totalPeers = -1;
|
||||||
|
public totalBalance = '';
|
||||||
|
public channelBalance = '';
|
||||||
|
public BTCtotalBalance = '';
|
||||||
|
public BTCchannelBalance = '';
|
||||||
|
public networkInfo: NetworkInfo = {};
|
||||||
|
public flgLoading: Array<Boolean | 'error'> = [true, true, true, true, true, true, true, true]; // 0: Info, 1: Fee, 2: Wallet, 3: Channel, 4: Network
|
||||||
|
private unsub: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
|
||||||
|
public channels: any;
|
||||||
|
public position = 'below';
|
||||||
|
public activeChannels = 0;
|
||||||
|
public inactiveChannels = 0;
|
||||||
|
public pendingChannels = 0;
|
||||||
|
public peers: Peer[] = [];
|
||||||
|
barPadding = 0;
|
||||||
|
maxBalanceValue = 0;
|
||||||
|
totalBalances = [...[{'name': 'Local Balance', 'value': 0}, {'name': 'Remote Balance', 'value': 0}]];
|
||||||
|
flgTotalCalculated = false;
|
||||||
|
view = [];
|
||||||
|
yAxisLabel = 'Balance';
|
||||||
|
colorScheme = {domain: ['#FFFFFF']};
|
||||||
|
|
||||||
|
constructor(private logger: LoggerService, private store: Store<fromRTLReducer.State>) {
|
||||||
|
switch (true) {
|
||||||
|
case (window.innerWidth <= 730):
|
||||||
|
this.view = [250, 352];
|
||||||
|
break;
|
||||||
|
case (window.innerWidth > 415 && window.innerWidth <= 730):
|
||||||
|
this.view = [280, 352];
|
||||||
|
break;
|
||||||
|
case (window.innerWidth > 730 && window.innerWidth <= 1024):
|
||||||
|
this.view = [300, 352];
|
||||||
|
break;
|
||||||
|
case (window.innerWidth > 1024 && window.innerWidth <= 1280):
|
||||||
|
this.view = [350, 352];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.view = [300, 352];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Object.assign(this, this.totalBalances);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.flgTotalCalculated = false;
|
||||||
|
this.store.select('rtlRoot')
|
||||||
|
.pipe(takeUntil(this.unsub[0]))
|
||||||
|
.subscribe((rtlStore: fromRTLReducer.State) => {
|
||||||
|
rtlStore.effectErrors.forEach(effectsErr => {
|
||||||
|
if (effectsErr.action === 'FetchInfo') {
|
||||||
|
this.flgLoading[0] = 'error';
|
||||||
|
}
|
||||||
|
if (effectsErr.action === 'FetchFees') {
|
||||||
|
this.flgLoading[1] = 'error';
|
||||||
|
}
|
||||||
|
if (effectsErr.action === 'FetchBalance/blockchain') {
|
||||||
|
this.flgLoading[2] = 'error';
|
||||||
|
}
|
||||||
|
if (effectsErr.action === 'FetchBalance/channels') {
|
||||||
|
this.flgLoading[3] = 'error';
|
||||||
|
}
|
||||||
|
if (effectsErr.action === 'FetchNetwork') {
|
||||||
|
this.flgLoading[4] = 'error';
|
||||||
|
}
|
||||||
|
if (effectsErr.action === 'FetchChannels/all') {
|
||||||
|
this.flgLoading[5] = 'error';
|
||||||
|
this.flgLoading[6] = 'error';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.selNode = rtlStore.selNode;
|
||||||
|
this.information = rtlStore.information;
|
||||||
|
if (this.flgLoading[0] !== 'error') {
|
||||||
|
this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.fees = rtlStore.fees;
|
||||||
|
if (this.flgLoading[1] !== 'error') {
|
||||||
|
this.flgLoading[1] = (undefined !== this.fees.day_fee_sum) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.totalBalance = rtlStore.blockchainBalance.total_balance;
|
||||||
|
this.BTCtotalBalance = rtlStore.blockchainBalance.btc_total_balance;
|
||||||
|
if (this.flgLoading[2] !== 'error') {
|
||||||
|
this.flgLoading[2] = ('' !== this.totalBalance) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.channelBalance = rtlStore.channelBalance.balance;
|
||||||
|
this.BTCchannelBalance = rtlStore.channelBalance.btc_balance;
|
||||||
|
if (this.flgLoading[3] !== 'error') {
|
||||||
|
this.flgLoading[3] = ('' !== this.channelBalance) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.networkInfo = rtlStore.networkInfo;
|
||||||
|
if (this.flgLoading[4] !== 'error') {
|
||||||
|
this.flgLoading[4] = (undefined !== this.networkInfo.num_nodes) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.totalBalances = [...[{'name': 'Local Balance', 'value': +rtlStore.totalLocalBalance}, {'name': 'Remote Balance', 'value': +rtlStore.totalRemoteBalance}]];
|
||||||
|
this.maxBalanceValue = (rtlStore.totalLocalBalance > rtlStore.totalRemoteBalance) ? rtlStore.totalLocalBalance : rtlStore.totalRemoteBalance;
|
||||||
|
if (rtlStore.totalLocalBalance >= 0 && rtlStore.totalRemoteBalance >= 0) {
|
||||||
|
this.flgTotalCalculated = true;
|
||||||
|
if (this.flgLoading[5] !== 'error') {
|
||||||
|
this.flgLoading[5] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.activeChannels = rtlStore.numberOfActiveChannels;
|
||||||
|
this.inactiveChannels = rtlStore.numberOfInactiveChannels;
|
||||||
|
this.pendingChannels = (undefined !== rtlStore.pendingChannels.pending_open_channels) ? rtlStore.pendingChannels.pending_open_channels.length : 0;
|
||||||
|
if (rtlStore.totalLocalBalance >= 0 && rtlStore.totalRemoteBalance >= 0 && this.flgLoading[6] !== 'error') {
|
||||||
|
this.flgLoading[6] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.totalPeers = (rtlStore.peers !== null) ? rtlStore.peers.length : 0;
|
||||||
|
|
||||||
|
this.logger.info(rtlStore);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy() {
|
||||||
|
this.unsub.forEach(completeSub => {
|
||||||
|
completeSub.next();
|
||||||
|
completeSub.complete();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +0,0 @@
|
|||||||
.inline-spinner {
|
|
||||||
display: inline-flex !important;
|
|
||||||
top: 0px !important;
|
|
||||||
}
|
|
@ -1,71 +1,166 @@
|
|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
import { Router, ActivatedRoute } from '@angular/router';
|
||||||
import { Subject } from 'rxjs';
|
|
||||||
import { takeUntil, filter } from 'rxjs/operators';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { Actions } from '@ngrx/effects';
|
|
||||||
|
|
||||||
import * as LNDActions from './store/lnd.actions';
|
|
||||||
import * as fromApp from '../store/rtl.reducers';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'rtl-lnd-root-app',
|
selector: 'rtl-lnd-root',
|
||||||
templateUrl: './lnd-root.component.html',
|
templateUrl: './lnd-root.component.html',
|
||||||
styleUrls: ['./lnd-root.component.scss']
|
styleUrls: ['./lnd-root.component.scss']
|
||||||
})
|
})
|
||||||
export class LndRootComponent implements OnInit, OnDestroy {
|
export class LNDRootComponent implements OnInit {
|
||||||
unsubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
|
|
||||||
|
constructor(private router: Router, private activatedRoute: ActivatedRoute) {}
|
||||||
constructor(private store: Store<fromApp.AppState>, private router: Router, private activatedRoute: ActivatedRoute, private actions$: Actions) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
console.warn('LND ROOT');
|
console.warn('LND ROOT')
|
||||||
// this.store.dispatch(new LNDActions.FetchInfo());
|
|
||||||
this.router.navigate(['./home'], {relativeTo: this.activatedRoute});
|
this.router.navigate(['./home'], {relativeTo: this.activatedRoute});
|
||||||
this.store.select('lnd')
|
|
||||||
.pipe(takeUntil(this.unsubs[0]))
|
|
||||||
.subscribe(lndStore => {
|
|
||||||
console.warn(lndStore);
|
|
||||||
if (undefined !== lndStore.information.identity_pubkey) {
|
|
||||||
this.initializeRemainingData();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.actions$.pipe(takeUntil(this.unsubs[2]), filter((action) => action.type === LNDActions.SET_INFO))
|
|
||||||
.subscribe((infoData: LNDActions.SetInfo) => {
|
|
||||||
console.warn(infoData);
|
|
||||||
if (undefined !== infoData.payload.identity_pubkey) {
|
|
||||||
this.initializeRemainingData();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// this.actions$
|
|
||||||
// .pipe(
|
|
||||||
// takeUntil(this.unSubs[3]),
|
|
||||||
// filter(action => action.type === RTLActions.INIT_APP_DATA || action.type === LNDActions.SET_INFO || action.type === CLActions.SET_CL_INFO)
|
|
||||||
// ).subscribe((actionPayload: RTLActions.InitAppData | LNDActions.SetInfo | CLActions.SetCLInfo) => {
|
|
||||||
// // if (actionPayload.type === RTLActions.INIT_APP_DATA) {
|
|
||||||
// if(this.information.identity_pubkey) {
|
|
||||||
// this.initializeRemainingData();
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initializeRemainingData() {
|
// @ViewChild('sideNavigation', { static: false }) sideNavigation: any;
|
||||||
console.warn('SOMETHING IS WRONG HERE');
|
// @ViewChild('settingSidenav', { static: true }) settingSidenav: any;
|
||||||
// this.store.dispatch(new LNDActions.FetchPeers());
|
// public selNode: Node;
|
||||||
// this.store.dispatch(new LNDActions.FetchBalance('channels'));
|
// public settings: Settings;
|
||||||
// this.store.dispatch(new LNDActions.FetchFees());
|
// public information: GetInfo = {};
|
||||||
// this.store.dispatch(new LNDActions.FetchNetwork());
|
// public flgLoading: Array<Boolean | 'error'> = [true]; // 0: Info
|
||||||
// this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'all'}));
|
// public flgCopied = false;
|
||||||
// this.store.dispatch(new LNDActions.FetchChannels({routeParam: 'pending'}));
|
// public appConfig: RTLConfiguration;
|
||||||
// this.store.dispatch(new LNDActions.FetchInvoices({num_max_invoices: 25, reversed: true}));
|
// public accessKey = '';
|
||||||
// this.store.dispatch(new LNDActions.FetchPayments());
|
// public smallScreen = false;
|
||||||
}
|
// unsubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject()];
|
||||||
|
|
||||||
ngOnDestroy() {
|
// constructor(private logger: LoggerService, private store: Store<fromRTLReducer.State>, private actions$: Actions,
|
||||||
this.unsubs.forEach(unsub => {
|
// private userIdle: UserIdleService, private router: Router) {}
|
||||||
unsub.next();
|
|
||||||
unsub.complete();
|
// ngOnInit() {
|
||||||
});
|
// this.store.dispatch(new RTLActions.FetchRTLConfig());
|
||||||
}
|
// this.accessKey = this.readAccessKey();
|
||||||
|
// this.store.select('rtlRoot')
|
||||||
|
// .pipe(takeUntil(this.unsubs[0]))
|
||||||
|
// .subscribe(rtlStore => {
|
||||||
|
// this.selNode = rtlStore.selNode;
|
||||||
|
// this.settings = this.selNode.settings;
|
||||||
|
// this.appConfig = rtlStore.appConfig;
|
||||||
|
// this.information = rtlStore.information;
|
||||||
|
// this.flgLoading[0] = (undefined !== this.information.identity_pubkey) ? false : true;
|
||||||
|
// if (window.innerWidth <= 768) {
|
||||||
|
// this.settings.menu = 'Vertical';
|
||||||
|
// this.settings.flgSidenavOpened = false;
|
||||||
|
// this.settings.flgSidenavPinned = false;
|
||||||
|
// }
|
||||||
|
// if (window.innerWidth <= 414) {
|
||||||
|
// this.smallScreen = true;
|
||||||
|
// }
|
||||||
|
// this.logger.info(this.settings);
|
||||||
|
// if (!sessionStorage.getItem('token')) {
|
||||||
|
// this.flgLoading[0] = false;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// if (sessionStorage.getItem('token')) {
|
||||||
|
// this.store.dispatch(new RTLActions.FetchInfo());
|
||||||
|
// }
|
||||||
|
// this.actions$
|
||||||
|
// .pipe(
|
||||||
|
// takeUntil(this.unsubs[1]),
|
||||||
|
// filter((action) => action.type === RTLActions.INIT_APP_DATA || action.type === RTLActions.SET_RTL_CONFIG)
|
||||||
|
// ).subscribe((actionPayload: (RTLActions.InitAppData | RTLActions.SetRTLConfig)) => {
|
||||||
|
// if (actionPayload.type === RTLActions.SET_RTL_CONFIG) {
|
||||||
|
// if (!sessionStorage.getItem('token')) {
|
||||||
|
// if (+actionPayload.payload.sso.rtlSSO) {
|
||||||
|
// this.store.dispatch(new RTLActions.Signin(sha256(this.accessKey)));
|
||||||
|
// } else {
|
||||||
|
// this.router.navigate([this.appConfig.sso.logoutRedirectLink]);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (
|
||||||
|
// this.settings.menu === 'Horizontal' ||
|
||||||
|
// this.settings.menuType === 'Compact' ||
|
||||||
|
// this.settings.menuType === 'Mini') {
|
||||||
|
// this.settingSidenav.toggle(); // To dynamically update the width to 100% after side nav is closed
|
||||||
|
// setTimeout(() => { this.settingSidenav.toggle(); }, 100);
|
||||||
|
// }
|
||||||
|
// } else if (actionPayload.type === RTLActions.INIT_APP_DATA) {
|
||||||
|
// this.store.dispatch(new RTLActions.FetchInfo());
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// this.actions$
|
||||||
|
// .pipe(
|
||||||
|
// takeUntil(this.unsubs[1]),
|
||||||
|
// filter((action) => action.type === RTLActions.SET_INFO)
|
||||||
|
// ).subscribe((infoData: RTLActions.SetInfo) => {
|
||||||
|
// if (undefined !== infoData.payload.identity_pubkey) {
|
||||||
|
// this.initializeRemainingData();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// this.userIdle.startWatching();
|
||||||
|
// this.userIdle.onTimerStart().subscribe(count => {});
|
||||||
|
// this.userIdle.onTimeout().subscribe(() => {
|
||||||
|
// if (sessionStorage.getItem('token')) {
|
||||||
|
// this.logger.warn('Time limit exceeded for session inactivity! Logging out!');
|
||||||
|
// this.store.dispatch(new RTLActions.OpenAlert({ width: '75%', data: {
|
||||||
|
// type: 'WARN',
|
||||||
|
// titleMessage: 'Time limit exceeded for session inactivity! Logging out!'
|
||||||
|
// }}));
|
||||||
|
// this.store.dispatch(new RTLActions.Signout());
|
||||||
|
// this.userIdle.resetTimer();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private readAccessKey() {
|
||||||
|
// const url = window.location.href;
|
||||||
|
// return url.substring(url.lastIndexOf('access-key=') + 11).trim();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// initializeRemainingData() {
|
||||||
|
// this.store.dispatch(new RTLActions.FetchPeers());
|
||||||
|
// this.store.dispatch(new RTLActions.FetchBalance('channels'));
|
||||||
|
// this.store.dispatch(new RTLActions.FetchFees());
|
||||||
|
// this.store.dispatch(new RTLActions.FetchNetwork());
|
||||||
|
// this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'all'}));
|
||||||
|
// this.store.dispatch(new RTLActions.FetchChannels({routeParam: 'pending'}));
|
||||||
|
// this.store.dispatch(new RTLActions.FetchInvoices({num_max_invoices: 25, reversed: true}));
|
||||||
|
// this.store.dispatch(new RTLActions.FetchPayments());
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ngAfterViewInit() {
|
||||||
|
// if (!this.settings.flgSidenavPinned) {
|
||||||
|
// this.sideNavigation.close();
|
||||||
|
// this.settingSidenav.toggle();
|
||||||
|
// }
|
||||||
|
// if (window.innerWidth <= 768) {
|
||||||
|
// this.sideNavigation.close();
|
||||||
|
// this.settingSidenav.toggle();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// @HostListener('window:resize')
|
||||||
|
// public onWindowResize(): void {
|
||||||
|
// if (window.innerWidth <= 768) {
|
||||||
|
// this.settings.menu = 'Vertical';
|
||||||
|
// this.settings.flgSidenavOpened = false;
|
||||||
|
// this.settings.flgSidenavPinned = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// sideNavToggle() {
|
||||||
|
// this.sideNavigation.toggle();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// onNavigationClicked(event: any) {
|
||||||
|
// if (window.innerWidth <= 414) {
|
||||||
|
// this.sideNavigation.close();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// copiedText(payload) {
|
||||||
|
// this.flgCopied = true;
|
||||||
|
// setTimeout(() => {this.flgCopied = false; }, 5000);
|
||||||
|
// this.logger.info('Copied Text: ' + payload);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ngOnDestroy() {
|
||||||
|
// this.unsubs.forEach(unsub => {
|
||||||
|
// unsub.next();
|
||||||
|
// unsub.complete();
|
||||||
|
// });
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
@ -1,47 +1,40 @@
|
|||||||
import { Component, OnInit, Input, OnDestroy } from '@angular/core';
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { formatDate } from '@angular/common';
|
import { formatDate } from '@angular/common';
|
||||||
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 { ChannelEdge } from '../../../shared/models/lndModels';
|
import { ChannelEdge } from '../../../shared/models/lndModels';
|
||||||
import * as fromLNDReducer from '../../store/lnd.reducers';
|
import * as fromRTLReducer from '../../../shared/store/rtl.reducers';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'rtl-channel-lookup',
|
selector: 'rtl-channel-lookup',
|
||||||
templateUrl: './channel-lookup.component.html',
|
templateUrl: './channel-lookup.component.html',
|
||||||
styleUrls: ['./channel-lookup.component.css']
|
styleUrls: ['./channel-lookup.component.css']
|
||||||
})
|
})
|
||||||
export class ChannelLookupComponent implements OnInit, OnDestroy {
|
export class ChannelLookupComponent implements OnInit {
|
||||||
@Input() lookupResult: ChannelEdge;
|
@Input() lookupResult: ChannelEdge;
|
||||||
public node1_match = false;
|
public node1_match = false;
|
||||||
public node2_match = false;
|
public node2_match = false;
|
||||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
private unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject()];
|
||||||
|
|
||||||
constructor(private lndStore: Store<fromLNDReducer.LNDState>) { }
|
constructor(private store: Store<fromRTLReducer.State>) { }
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
if (undefined !== this.lookupResult && undefined !== this.lookupResult.last_update_str) {
|
if (undefined !== this.lookupResult && undefined !== this.lookupResult.last_update_str) {
|
||||||
this.lookupResult.last_update_str = (this.lookupResult.last_update_str === '') ?
|
this.lookupResult.last_update_str = (this.lookupResult.last_update_str === '') ?
|
||||||
'' : formatDate(this.lookupResult.last_update_str, 'MMM/dd/yy HH:mm:ss', 'en-US');
|
'' : formatDate(this.lookupResult.last_update_str, 'MMM/dd/yy HH:mm:ss', 'en-US');
|
||||||
}
|
}
|
||||||
this.lndStore.select('lnd')
|
this.store.select('rtlRoot')
|
||||||
.pipe(takeUntil(this.unSubs[1]))
|
.pipe(takeUntil(this.unSubs[0]))
|
||||||
.subscribe(lndStore => {
|
.subscribe((rtlStore: fromRTLReducer.State) => {
|
||||||
if (this.lookupResult.node1_pub === lndStore.information.identity_pubkey) {
|
if (this.lookupResult.node1_pub === rtlStore.information.identity_pubkey) {
|
||||||
this.node1_match = true;
|
this.node1_match = true;
|
||||||
}
|
}
|
||||||
if (this.lookupResult.node2_pub === lndStore.information.identity_pubkey) {
|
if (this.lookupResult.node2_pub === rtlStore.information.identity_pubkey) {
|
||||||
this.node2_match = true;
|
this.node2_match = true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.unSubs.forEach(unsub => {
|
|
||||||
unsub.next();
|
|
||||||
unsub.complete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,16 @@
|
|||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'rtl-not-found',
|
selector: 'rtl-not-found',
|
||||||
templateUrl: './not-found.component.html'
|
templateUrl: './not-found.component.html'
|
||||||
})
|
})
|
||||||
export class NotFoundComponent {}
|
export class NotFoundComponent {
|
||||||
|
|
||||||
|
constructor(public router: Router) {}
|
||||||
|
|
||||||
|
goToHelp(): void {
|
||||||
|
this.router.navigate(['/help']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
// export interface GetInfoAddress {
|
|
||||||
// type?: string;
|
|
||||||
// address?: string;
|
|
||||||
// port?: number;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// export interface GetInfo {
|
|
||||||
// id?: string;
|
|
||||||
// alias?: string;
|
|
||||||
// color?: string;
|
|
||||||
// num_peers?: number;
|
|
||||||
// num_pending_channels?: number;
|
|
||||||
// num_active_channels?: number;
|
|
||||||
// num_inactive_channels?: number;
|
|
||||||
// address?: GetInfoAddress[];
|
|
||||||
// binding?: GetInfoAddress[];
|
|
||||||
// version?: string;
|
|
||||||
// blockheight?: number;
|
|
||||||
// network?: string;
|
|
||||||
// msatoshi_fees_collected?: number;
|
|
||||||
// fees_collected_msat?: string;
|
|
||||||
// }
|
|
||||||
|
|
||||||
export interface GetInfoChain {
|
|
||||||
chain?: string;
|
|
||||||
network?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface GetInfo {
|
|
||||||
identity_pubkey?: string;
|
|
||||||
alias?: string;
|
|
||||||
num_pending_channels?: number;
|
|
||||||
num_active_channels?: number;
|
|
||||||
num_inactive_channels?: number;
|
|
||||||
num_peers?: number;
|
|
||||||
block_height?: number;
|
|
||||||
synced_to_chain?: boolean;
|
|
||||||
testnet?: boolean;
|
|
||||||
chains?: GetInfoChain[];
|
|
||||||
version?: string;
|
|
||||||
currency_unit?: string;
|
|
||||||
smaller_currency_unit?: string;
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
import { Action } from '@ngrx/store';
|
|
||||||
import { RTLConfiguration, Settings, Node } from '../shared/models/RTLconfig';
|
|
||||||
import { ErrorPayload } from '../shared/models/errorPayload';
|
|
||||||
import { MatDialogConfig } from '@angular/material';
|
|
||||||
|
|
||||||
export const RESET_STORE = 'RESET_STORE';
|
|
||||||
export const CLEAR_EFFECT_ERROR = 'CLEAR_EFFECT_ERROR';
|
|
||||||
export const EFFECT_ERROR = 'EFFECT_ERROR';
|
|
||||||
export const OPEN_SPINNER = 'OPEN_SPINNER';
|
|
||||||
export const CLOSE_SPINNER = 'CLOSE_SPINNER';
|
|
||||||
export const OPEN_ALERT = 'OPEN_ALERT';
|
|
||||||
export const CLOSE_ALERT = 'CLOSE_ALERT';
|
|
||||||
export const OPEN_CONFIRMATION = 'OPEN_CONFIRMATION';
|
|
||||||
export const CLOSE_CONFIRMATION = 'CLOSE_CONFIRMATION';
|
|
||||||
export const FETCH_STORE = 'FETCH_STORE';
|
|
||||||
export const SET_STORE = 'SET_STORE';
|
|
||||||
export const FETCH_RTL_CONFIG = 'FETCH_RTL_CONFIG';
|
|
||||||
export const SET_RTL_CONFIG = 'SET_RTL_CONFIG';
|
|
||||||
export const SAVE_SETTINGS = 'SAVE_SETTINGS';
|
|
||||||
export const SET_SELECTED_NODE = 'SET_SELECTED_NODE';
|
|
||||||
export const IS_AUTHORIZED = 'IS_AUTHORIZED';
|
|
||||||
export const IS_AUTHORIZED_RES = 'IS_AUTHORIZED_RES';
|
|
||||||
export const SIGNIN = 'SIGNIN';
|
|
||||||
export const SIGNOUT = 'SIGNOUT';
|
|
||||||
export const INIT_APP_DATA = 'INIT_APP_DATA';
|
|
||||||
|
|
||||||
export class ClearEffectError implements Action {
|
|
||||||
readonly type = CLEAR_EFFECT_ERROR;
|
|
||||||
constructor(public payload: string) {} // payload = errorAction
|
|
||||||
}
|
|
||||||
|
|
||||||
export class EffectError implements Action {
|
|
||||||
readonly type = EFFECT_ERROR;
|
|
||||||
constructor(public payload: ErrorPayload) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class OpenSpinner implements Action {
|
|
||||||
readonly type = OPEN_SPINNER;
|
|
||||||
constructor(public payload: string) {} // payload = titleMessage
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CloseSpinner implements Action {
|
|
||||||
readonly type = CLOSE_SPINNER;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class OpenAlert implements Action {
|
|
||||||
readonly type = OPEN_ALERT;
|
|
||||||
constructor(public payload: MatDialogConfig) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CloseAlert implements Action {
|
|
||||||
readonly type = CLOSE_ALERT;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class OpenConfirmation implements Action {
|
|
||||||
readonly type = OPEN_CONFIRMATION;
|
|
||||||
constructor(public payload: MatDialogConfig) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CloseConfirmation implements Action {
|
|
||||||
readonly type = CLOSE_CONFIRMATION;
|
|
||||||
constructor(public payload: boolean) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class ResetStore implements Action {
|
|
||||||
readonly type = RESET_STORE;
|
|
||||||
constructor(public payload: Node) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class FetchRTLConfig implements Action {
|
|
||||||
readonly type = FETCH_RTL_CONFIG;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SetRTLConfig implements Action {
|
|
||||||
readonly type = SET_RTL_CONFIG;
|
|
||||||
constructor(public payload: RTLConfiguration) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SaveSettings implements Action {
|
|
||||||
readonly type = SAVE_SETTINGS;
|
|
||||||
constructor(public payload: Settings) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SetSelelectedNode implements Action {
|
|
||||||
readonly type = SET_SELECTED_NODE;
|
|
||||||
constructor(public payload: Node) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class IsAuthorized implements Action {
|
|
||||||
readonly type = IS_AUTHORIZED;
|
|
||||||
constructor(public payload: string) {} // payload = password
|
|
||||||
}
|
|
||||||
|
|
||||||
export class IsAuthorizedRes implements Action {
|
|
||||||
readonly type = IS_AUTHORIZED_RES;
|
|
||||||
constructor(public payload: any) {} // payload = token/error
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Signin implements Action {
|
|
||||||
readonly type = SIGNIN;
|
|
||||||
constructor(public payload: string) {} // payload = password
|
|
||||||
}
|
|
||||||
|
|
||||||
export class Signout implements Action {
|
|
||||||
readonly type = SIGNOUT;
|
|
||||||
constructor() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class InitAppData implements Action {
|
|
||||||
readonly type = INIT_APP_DATA;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type RTLActions =
|
|
||||||
ClearEffectError | EffectError | OpenSpinner | CloseSpinner |
|
|
||||||
FetchRTLConfig | SetRTLConfig | SaveSettings |
|
|
||||||
OpenAlert | CloseAlert | OpenConfirmation | CloseConfirmation |
|
|
||||||
ResetStore | SetSelelectedNode |
|
|
||||||
IsAuthorized | IsAuthorizedRes | Signin | Signout | InitAppData;
|
|
@ -1,261 +0,0 @@
|
|||||||
import { Injectable, OnDestroy } from '@angular/core';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { Actions, Effect, ofType } from '@ngrx/effects';
|
|
||||||
import { of, Subject } from 'rxjs';
|
|
||||||
import { map, mergeMap, catchError, take, withLatestFrom } from 'rxjs/operators';
|
|
||||||
|
|
||||||
import { MatDialog } from '@angular/material';
|
|
||||||
import { environment } from '../../environments/environment';
|
|
||||||
import { LoggerService } from '../shared/services/logger.service';
|
|
||||||
import { Settings } from '../shared/models/RTLconfig';
|
|
||||||
|
|
||||||
import { SpinnerDialogComponent } from '../shared/components/spinner-dialog/spinner-dialog.component';
|
|
||||||
import { AlertMessageComponent } from '../shared/components/alert-message/alert-message.component';
|
|
||||||
import { ConfirmationMessageComponent } from '../shared/components/confirmation-message/confirmation-message.component';
|
|
||||||
|
|
||||||
import * as CLActions from '../c-lightning/store/cl.actions';
|
|
||||||
import * as LNDActions from '../lnd/store/lnd.actions';
|
|
||||||
import * as RTLActions from './rtl.actions';
|
|
||||||
import * as fromApp from './rtl.reducers';
|
|
||||||
|
|
||||||
@Injectable()
|
|
||||||
export class RTLEffects implements OnDestroy {
|
|
||||||
dialogRef: any;
|
|
||||||
private unSubs: Array<Subject<void>> = [new Subject(), new Subject()];
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
private actions$: Actions,
|
|
||||||
private httpClient: HttpClient,
|
|
||||||
private store: Store<fromApp.AppState>,
|
|
||||||
private logger: LoggerService,
|
|
||||||
public dialog: MatDialog,
|
|
||||||
private router: Router,
|
|
||||||
private activatedRoute: ActivatedRoute) { }
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
openSpinner = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.OPEN_SPINNER),
|
|
||||||
map((action: RTLActions.OpenSpinner) => {
|
|
||||||
this.dialogRef = this.dialog.open(SpinnerDialogComponent, { data: { titleMessage: action.payload}});
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
closeSpinner = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.CLOSE_SPINNER),
|
|
||||||
map((action: RTLActions.CloseSpinner) => {
|
|
||||||
if (this.dialogRef) { this.dialogRef.close(); }
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
openAlert = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.OPEN_ALERT),
|
|
||||||
map((action: RTLActions.OpenAlert) => {
|
|
||||||
this.dialogRef = this.dialog.open(AlertMessageComponent, action.payload);
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
closeAlert = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.CLOSE_ALERT),
|
|
||||||
map((action: RTLActions.CloseAlert) => {
|
|
||||||
if (this.dialogRef) { this.dialogRef.close(); }
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
openConfirm = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.OPEN_CONFIRMATION),
|
|
||||||
map((action: RTLActions.OpenConfirmation) => {
|
|
||||||
this.dialogRef = this.dialog.open(ConfirmationMessageComponent, action.payload);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
closeConfirm = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.CLOSE_CONFIRMATION),
|
|
||||||
take(1),
|
|
||||||
map((action: RTLActions.CloseConfirmation) => {
|
|
||||||
this.dialogRef.close();
|
|
||||||
this.logger.info(action.payload);
|
|
||||||
return action.payload;
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
@Effect()
|
|
||||||
appConfigFetch = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.FETCH_RTL_CONFIG),
|
|
||||||
mergeMap((action: RTLActions.FetchRTLConfig) => {
|
|
||||||
this.store.dispatch(new RTLActions.ClearEffectError('FetchRTLConfig'));
|
|
||||||
return this.httpClient.get(environment.CONF_API + '/rtlconf');
|
|
||||||
}),
|
|
||||||
map((rtlConfig: any) => {
|
|
||||||
this.logger.info(rtlConfig);
|
|
||||||
if (+rtlConfig.sso.rtlSSO) { this.store.dispatch(new RTLActions.Signout()); }
|
|
||||||
return {
|
|
||||||
type: RTLActions.SET_RTL_CONFIG,
|
|
||||||
payload: rtlConfig
|
|
||||||
};
|
|
||||||
},
|
|
||||||
catchError((err) => {
|
|
||||||
this.logger.error(err);
|
|
||||||
this.store.dispatch(new RTLActions.EffectError({ action: 'FetchRTLConfig', code: err.status, message: err.error.error }));
|
|
||||||
return of();
|
|
||||||
})
|
|
||||||
));
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
settingSave = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.SAVE_SETTINGS),
|
|
||||||
mergeMap((action: RTLActions.SaveSettings) => {
|
|
||||||
return this.httpClient.post<Settings>(environment.CONF_API, { updatedSettings: action.payload });
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
@Effect()
|
|
||||||
isAuthorized = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.IS_AUTHORIZED),
|
|
||||||
withLatestFrom(this.store.select('rtlRoot')),
|
|
||||||
mergeMap(([action, store]: [RTLActions.IsAuthorized, fromApp.RootState]) => {
|
|
||||||
this.store.dispatch(new RTLActions.ClearEffectError('IsAuthorized'));
|
|
||||||
return this.httpClient.post(environment.AUTHENTICATE_API, { password: action.payload })
|
|
||||||
.pipe(
|
|
||||||
map((postRes: any) => {
|
|
||||||
this.logger.info(postRes);
|
|
||||||
this.logger.info('Successfully Authorized!');
|
|
||||||
return {
|
|
||||||
type: RTLActions.IS_AUTHORIZED_RES,
|
|
||||||
payload: postRes
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
catchError((err) => {
|
|
||||||
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', titleMessage: 'Authorization Failed',
|
|
||||||
message: JSON.stringify({Code: err.status, Message: err.error.error})}}));
|
|
||||||
this.store.dispatch(new RTLActions.EffectError({ action: 'IsAuthorized', code: err.status, message: err.error.message }));
|
|
||||||
this.logger.error(err.error);
|
|
||||||
return of({
|
|
||||||
type: RTLActions.IS_AUTHORIZED_RES,
|
|
||||||
payload: 'ERROR'
|
|
||||||
});
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}));
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
isAuthorizedRes = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.IS_AUTHORIZED_RES),
|
|
||||||
map((action: RTLActions.IsAuthorizedRes) => {
|
|
||||||
return action.payload;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
authSignin = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.SIGNIN),
|
|
||||||
withLatestFrom(this.store.select('rtlRoot')),
|
|
||||||
mergeMap(([action, store]: [RTLActions.Signin, fromApp.RootState]) => {
|
|
||||||
this.store.dispatch(new RTLActions.ClearEffectError('Signin'));
|
|
||||||
return this.httpClient.post(environment.AUTHENTICATE_API, { password: action.payload })
|
|
||||||
.pipe(
|
|
||||||
map((postRes: any) => {
|
|
||||||
this.logger.info(postRes);
|
|
||||||
this.logger.info('Successfully Authorized!');
|
|
||||||
this.SetToken(postRes.token);
|
|
||||||
this.router.navigate(['/'], { relativeTo: this.activatedRoute });
|
|
||||||
}),
|
|
||||||
catchError((err) => {
|
|
||||||
this.store.dispatch(new RTLActions.OpenAlert({ width: '70%', data: {type: 'ERROR', message: JSON.stringify(err.error)}}));
|
|
||||||
this.store.dispatch(new RTLActions.EffectError({ action: 'Signin', code: err.status, message: err.error.message }));
|
|
||||||
this.logger.error(err.error);
|
|
||||||
this.logger.info('Redirecting to Signin Error Page');
|
|
||||||
if (+store.appConfig.sso.rtlSSO) {
|
|
||||||
this.router.navigate(['/ssoerror'], { relativeTo: this.activatedRoute });
|
|
||||||
} else {
|
|
||||||
this.router.navigate([store.appConfig.sso.logoutRedirectLink], { relativeTo: this.activatedRoute });
|
|
||||||
}
|
|
||||||
return of();
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}));
|
|
||||||
|
|
||||||
@Effect({ dispatch: false })
|
|
||||||
signOut = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.SIGNOUT),
|
|
||||||
withLatestFrom(this.store.select('rtlRoot')),
|
|
||||||
mergeMap(([action, store]: [RTLActions.Signout, fromApp.RootState]) => {
|
|
||||||
if (+store.appConfig.sso.rtlSSO) {
|
|
||||||
window.location.href = store.appConfig.sso.logoutRedirectLink;
|
|
||||||
} else {
|
|
||||||
this.router.navigate([store.appConfig.sso.logoutRedirectLink], { relativeTo: this.activatedRoute });
|
|
||||||
}
|
|
||||||
sessionStorage.removeItem('lndUnlocked');
|
|
||||||
sessionStorage.removeItem('token');
|
|
||||||
this.logger.warn('LOGGED OUT');
|
|
||||||
return of();
|
|
||||||
}));
|
|
||||||
|
|
||||||
@Effect()
|
|
||||||
setSelectedNode = this.actions$.pipe(
|
|
||||||
ofType(RTLActions.SET_SELECTED_NODE),
|
|
||||||
mergeMap((action: RTLActions.SetSelelectedNode) => {
|
|
||||||
this.store.dispatch(new RTLActions.ClearEffectError('UpdateSelNode'));
|
|
||||||
return this.httpClient.post(environment.CONF_API + '/updateSelNode', { selNodeIndex: action.payload.index })
|
|
||||||
.pipe(
|
|
||||||
map((postRes: any) => {
|
|
||||||
this.logger.info(postRes);
|
|
||||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
|
||||||
if (sessionStorage.getItem('token')) {
|
|
||||||
this.store.dispatch(new RTLActions.ResetStore(action.payload));
|
|
||||||
if (action.payload.lnImplementation.toLowerCase() === 'clightning') {
|
|
||||||
this.router.navigate(['./cl'], { relativeTo: this.activatedRoute });
|
|
||||||
return { type: CLActions.FETCH_CL_INFO };
|
|
||||||
} else {
|
|
||||||
this.router.navigate(['./lnd'], { relativeTo: this.activatedRoute });
|
|
||||||
return { type: LNDActions.FETCH_INFO };
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return {
|
|
||||||
type: RTLActions.OPEN_ALERT,
|
|
||||||
payload: { width: '70%', data: {type: 'WARN', titleMessage: 'Authorization required to get the data from the node!' }}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
catchError((err: any) => {
|
|
||||||
this.store.dispatch(new RTLActions.CloseSpinner());
|
|
||||||
this.store.dispatch(new RTLActions.EffectError({ action: 'UpdateSelNode', code: err.status, message: err.error.message }));
|
|
||||||
this.logger.error(err);
|
|
||||||
return of(
|
|
||||||
{
|
|
||||||
type: RTLActions.OPEN_ALERT,
|
|
||||||
payload: { width: '70%', data: {type: 'ERROR', titleMessage: 'Update Selected Node Failed!',
|
|
||||||
message: JSON.stringify({code: err.status, Message: err.error.error})
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
));
|
|
||||||
|
|
||||||
SetToken(token: string) {
|
|
||||||
if (token) {
|
|
||||||
sessionStorage.setItem('lndUnlocked', 'true');
|
|
||||||
sessionStorage.setItem('token', token);
|
|
||||||
this.store.dispatch(new RTLActions.InitAppData());
|
|
||||||
} else {
|
|
||||||
sessionStorage.removeItem('lndUnlocked');
|
|
||||||
sessionStorage.removeItem('token');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.unSubs.forEach(completeSub => {
|
|
||||||
completeSub.next();
|
|
||||||
completeSub.complete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,82 +0,0 @@
|
|||||||
import * as RTLActions from './rtl.actions';
|
|
||||||
import { ErrorPayload } from '../shared/models/errorPayload';
|
|
||||||
import { RTLConfiguration, Node } from '../shared/models/RTLconfig';
|
|
||||||
|
|
||||||
import { ActionReducerMap } from '@ngrx/store';
|
|
||||||
|
|
||||||
import * as fromLND from '../lnd/store/lnd.reducers';
|
|
||||||
import * as fromCL from '../c-lightning/store/cl.reducers';
|
|
||||||
|
|
||||||
export interface AppState {
|
|
||||||
rtlRoot: RootState;
|
|
||||||
lnd: fromLND.LNDState;
|
|
||||||
cl: fromCL.CLState;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface RootState {
|
|
||||||
effectErrors: ErrorPayload[];
|
|
||||||
selNode: Node;
|
|
||||||
appConfig: RTLConfiguration;
|
|
||||||
}
|
|
||||||
|
|
||||||
const initNodeSettings = { flgSidenavOpened: true, flgSidenavPinned: true, menu: 'Vertical', menuType: 'Regular', theme: 'dark-blue', satsToBTC: false };
|
|
||||||
const initNodeAuthentication = { nodeAuthType: 'CUSTOM', lndConfigPath: '', bitcoindConfigPath: '' };
|
|
||||||
|
|
||||||
const initialState: RootState = {
|
|
||||||
effectErrors: [],
|
|
||||||
selNode: {settings: initNodeSettings, authentication: initNodeAuthentication},
|
|
||||||
appConfig: {
|
|
||||||
selectedNodeIndex: -1,
|
|
||||||
sso: { rtlSSO: 0, logoutRedirectLink: '/login' },
|
|
||||||
nodes: [{ settings: initNodeSettings, authentication: initNodeAuthentication}]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export function RTLRootReducer(state = initialState, action: RTLActions.RTLActions) {
|
|
||||||
switch (action.type) {
|
|
||||||
case RTLActions.CLEAR_EFFECT_ERROR:
|
|
||||||
const clearedEffectErrors = [...state.effectErrors];
|
|
||||||
const removeEffectIdx = state.effectErrors.findIndex(err => {
|
|
||||||
return err.action === action.payload;
|
|
||||||
});
|
|
||||||
if (removeEffectIdx > -1) {
|
|
||||||
clearedEffectErrors.splice(removeEffectIdx, 1);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
effectErrors: clearedEffectErrors
|
|
||||||
};
|
|
||||||
case RTLActions.EFFECT_ERROR:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
effectErrors: [...state.effectErrors, action.payload]
|
|
||||||
};
|
|
||||||
case RTLActions.RESET_STORE:
|
|
||||||
return {
|
|
||||||
...initialState,
|
|
||||||
appConfig: state.appConfig,
|
|
||||||
selNode: action.payload
|
|
||||||
};
|
|
||||||
case RTLActions.SET_SELECTED_NODE:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
selNode: action.payload
|
|
||||||
};
|
|
||||||
case RTLActions.SET_RTL_CONFIG:
|
|
||||||
return {
|
|
||||||
...state,
|
|
||||||
selNode: action.payload.nodes.find(node => +node.index === action.payload.selectedNodeIndex),
|
|
||||||
appConfig: action.payload
|
|
||||||
};
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
export const appReducer: ActionReducerMap<AppState> = {
|
|
||||||
rtlRoot: RTLRootReducer,
|
|
||||||
lnd: fromLND.LNDReducer,
|
|
||||||
cl: fromCL.CLReducer
|
|
||||||
};
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
|||||||
<router-outlet></router-outlet>
|
|
||||||
|
|
@ -1,25 +0,0 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
|
||||||
|
|
||||||
import { SuperUserDashboardComponent } from './super-user-dashboard.component';
|
|
||||||
|
|
||||||
describe('SuperUserDashboardComponent', () => {
|
|
||||||
let component: SuperUserDashboardComponent;
|
|
||||||
let fixture: ComponentFixture<SuperUserDashboardComponent>;
|
|
||||||
|
|
||||||
beforeEach(async(() => {
|
|
||||||
TestBed.configureTestingModule({
|
|
||||||
declarations: [ SuperUserDashboardComponent ]
|
|
||||||
})
|
|
||||||
.compileComponents();
|
|
||||||
}));
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
fixture = TestBed.createComponent(SuperUserDashboardComponent);
|
|
||||||
component = fixture.componentInstance;
|
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create', () => {
|
|
||||||
expect(component).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,70 +0,0 @@
|
|||||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
|
||||||
import { Router, ActivatedRoute } from '@angular/router';
|
|
||||||
import { Subject } from 'rxjs';
|
|
||||||
import { takeUntil, filter } from 'rxjs/operators';
|
|
||||||
import { Store } from '@ngrx/store';
|
|
||||||
import { Actions } from '@ngrx/effects';
|
|
||||||
import { UserIdleService } from 'angular-user-idle';
|
|
||||||
|
|
||||||
import { LoggerService } from '../shared/services/logger.service';
|
|
||||||
import { RTLConfiguration, Settings, Node } from '../shared/models/RTLconfig';
|
|
||||||
import { GetInfo } from '../shared/models/lndModels';
|
|
||||||
|
|
||||||
import * as LNDActions from '../lnd/store/lnd.actions';
|
|
||||||
import * as CLActions from '../c-lightning/store/cl.actions';
|
|
||||||
import * as RTLActions from '../store/rtl.actions';
|
|
||||||
import * as fromApp from '../store/rtl.reducers';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'rtl-super-user-dashboard',
|
|
||||||
templateUrl: './super-user-dashboard.component.html',
|
|
||||||
styleUrls: ['./super-user-dashboard.component.scss']
|
|
||||||
})
|
|
||||||
export class SuperUserDashboardComponent implements OnInit, OnDestroy {
|
|
||||||
public selNode: Node;
|
|
||||||
public settings: Settings;
|
|
||||||
public information: GetInfo = {};
|
|
||||||
public flgLoading: Array<Boolean | 'error'> = [true];
|
|
||||||
public flgCopied = false;
|
|
||||||
public appConfig: RTLConfiguration;
|
|
||||||
public accessKey = '';
|
|
||||||
public smallScreen = false;
|
|
||||||
unSubs: Array<Subject<void>> = [new Subject(), new Subject(), new Subject(), new Subject(), new Subject()];
|
|
||||||
|
|
||||||
constructor(private logger: LoggerService, private store: Store<fromApp.AppState>, private actions$: Actions, private userIdle: UserIdleService, private router: Router, private activatedRoute: ActivatedRoute) {}
|
|
||||||
|
|
||||||
ngOnInit() {
|
|
||||||
this.actions$.pipe(takeUntil(this.unSubs[3]), filter(action => action.type === RTLActions.SET_RTL_CONFIG))
|
|
||||||
.subscribe((setConfigAction: RTLActions.SetRTLConfig) => {
|
|
||||||
console.warn(setConfigAction);
|
|
||||||
this.selNode = setConfigAction.payload.nodes.find(node => +node.index === setConfigAction.payload.selectedNodeIndex)
|
|
||||||
if (this.selNode.lnImplementation.toLowerCase() === 'clightning') {
|
|
||||||
this.store.dispatch(new CLActions.FetchCLInfo());
|
|
||||||
this.router.navigate(['../cl'], { relativeTo: this.activatedRoute });
|
|
||||||
} else {
|
|
||||||
this.store.dispatch(new LNDActions.FetchInfo());
|
|
||||||
this.router.navigate(['../lnd'], { relativeTo: this.activatedRoute });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// this.store.select('rtlRoot')
|
|
||||||
// .pipe(takeUntil(this.unSubs[0]))
|
|
||||||
// .subscribe(rtlStore => {
|
|
||||||
// this.selNode = rtlStore.selNode;
|
|
||||||
// if (this.selNode.lnImplementation.toLowerCase() === 'clightning') {
|
|
||||||
// this.store.dispatch(new CLActions.FetchCLInfo());
|
|
||||||
// this.router.navigate(['./cl'], { relativeTo: this.activatedRoute });
|
|
||||||
// } else {
|
|
||||||
// this.store.dispatch(new LNDActions.FetchInfo());
|
|
||||||
// this.router.navigate(['./lnd'], { relativeTo: this.activatedRoute });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
|
|
||||||
ngOnDestroy() {
|
|
||||||
this.unSubs.forEach(unsub => {
|
|
||||||
unsub.next();
|
|
||||||
unsub.complete();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1 +1 @@
|
|||||||
export const VERSION = '0.4.7-beta';
|
export const VERSION = '0.4.8-beta';
|
Loading…
Reference in New Issue