Improve data load process to occur on app load.
This commit is contained in:
parent
0ee8c7e6c8
commit
6ce332a9aa
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,6 +4,7 @@
|
|||||||
/dist
|
/dist
|
||||||
/tmp
|
/tmp
|
||||||
/out-tsc
|
/out-tsc
|
||||||
|
/tests
|
||||||
# Only exists if Bazel was run
|
# Only exists if Bazel was run
|
||||||
/bazel-out
|
/bazel-out
|
||||||
|
|
||||||
|
371
docs/compodoc/interceptors/ConnectionInterceptor.html
Normal file
371
docs/compodoc/interceptors/ConnectionInterceptor.html
Normal file
@ -0,0 +1,371 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html class="no-js" lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
|
<title>CICADA</title>
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
|
||||||
|
<link rel="icon" type="image/x-icon" href="../images/favicon.ico">
|
||||||
|
<link rel="stylesheet" href="../styles/style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="navbar navbar-default navbar-fixed-top visible-xs">
|
||||||
|
<a href="../" class="navbar-brand">CICADA</a>
|
||||||
|
<button type="button" class="btn btn-default btn-menu ion-ios-menu" id="btn-menu"></button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="xs-menu menu" id="mobile-menu">
|
||||||
|
<div id="book-search-input" role="search"><input type="text" placeholder="Type to search"></div> <compodoc-menu></compodoc-menu>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="container-fluid main">
|
||||||
|
<div class="row main">
|
||||||
|
<div class="hidden-xs menu">
|
||||||
|
<compodoc-menu mode="normal"></compodoc-menu>
|
||||||
|
</div>
|
||||||
|
<!-- START CONTENT -->
|
||||||
|
<div class="content interceptor">
|
||||||
|
<div class="content-data">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
<li>Interceptors</li>
|
||||||
|
<li>ConnectionInterceptor</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<ul class="nav nav-tabs" role="tablist">
|
||||||
|
<li class="active">
|
||||||
|
<a href="#info" role="tab" id="info-tab" data-toggle="tab" data-link="info">Info</a>
|
||||||
|
</li>
|
||||||
|
<li >
|
||||||
|
<a href="#source" role="tab" id="source-tab" data-toggle="tab" data-link="source">Source</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane fade active in" id="c-info">
|
||||||
|
<p class="comment">
|
||||||
|
<h3>File</h3>
|
||||||
|
</p>
|
||||||
|
<p class="comment">
|
||||||
|
<code>src/app/_interceptors/connection.interceptor.ts</code>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="comment">
|
||||||
|
<h3>Description</h3>
|
||||||
|
</p>
|
||||||
|
<p class="comment">
|
||||||
|
<p>Intercepts and handles of events from outgoing HTTP request. </p>
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3 id="index">Index</h3>
|
||||||
|
<table class="table table-sm table-bordered index-table">
|
||||||
|
<tbody>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<h6><b>Methods</b></h6>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<ul class="index-list">
|
||||||
|
<li>
|
||||||
|
<a href="#intercept">intercept</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3 id="constructor">Constructor</h3>
|
||||||
|
<table class="table table-sm table-bordered">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<code>constructor(loggingService: <a href="../injectables/LoggingService.html">LoggingService</a>)</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<div class="io-line">Defined in <a href="" data-line="14" class="link-to-prism">src/app/_interceptors/connection.interceptor.ts:14</a></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<div class="io-description"><p>Initialization of the connection interceptor.</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<b>Parameters :</b>
|
||||||
|
<table class="params">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>Optional</td>
|
||||||
|
<td>Description</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>loggingService</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<code><a href="../injectables/LoggingService.html" target="_self" >LoggingService</a></code>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
No
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<code><ul>
|
||||||
|
<li>A service that provides logging capabilities.</li>
|
||||||
|
</ul>
|
||||||
|
</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
|
||||||
|
<h3 id="methods">
|
||||||
|
Methods
|
||||||
|
</h3>
|
||||||
|
<table class="table table-sm table-bordered">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<a name="intercept"></a>
|
||||||
|
<span class="name">
|
||||||
|
<b>
|
||||||
|
intercept
|
||||||
|
</b>
|
||||||
|
<a href="#intercept"><span class="icon ion-ios-link"></span></a>
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<code>intercept(request: HttpRequest<unknown>, next: <a href="https://angular.io/api/common/http/HttpHandler" target="_blank">HttpHandler</a>)</code>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<div class="io-line">Defined in <a href="" data-line="29"
|
||||||
|
class="link-to-prism">src/app/_interceptors/connection.interceptor.ts:29</a></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="col-md-4">
|
||||||
|
<div class="io-description"><p>Intercepts HTTP requests.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="io-description">
|
||||||
|
<b>Parameters :</b>
|
||||||
|
<table class="params">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<td>Name</td>
|
||||||
|
<td>Type</td>
|
||||||
|
<td>Optional</td>
|
||||||
|
<td>Description</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>request</td>
|
||||||
|
<td>
|
||||||
|
<code>HttpRequest<unknown></code>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
No
|
||||||
|
</td>
|
||||||
|
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<ul>
|
||||||
|
<li>An outgoing HTTP request with an optional typed body.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>next</td>
|
||||||
|
<td>
|
||||||
|
<code><a href="https://angular.io/api/common/http/HttpHandler" target="_blank" >HttpHandler</a></code>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
No
|
||||||
|
</td>
|
||||||
|
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<ul>
|
||||||
|
<li>The next HTTP handler or the outgoing request dispatcher.</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
</div>
|
||||||
|
<div class="io-description">
|
||||||
|
<b>Returns : </b> <code>Observable<HttpEvent<unknown>></code>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="io-description">
|
||||||
|
<p>The forwarded request.</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="tab-pane fade tab-source-code" id="c-source">
|
||||||
|
<pre class="line-numbers compodoc-sourcecode"><code class="language-typescript">import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
// Third party imports
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
// Application imports
|
||||||
|
import { LoggingService } from '@app/_services/logging.service';
|
||||||
|
import { checkOnlineStatus } from '@app/_helpers';
|
||||||
|
|
||||||
|
/** Intercepts and handles of events from outgoing HTTP request. */
|
||||||
|
@Injectable()
|
||||||
|
export class ConnectionInterceptor implements HttpInterceptor {
|
||||||
|
/**
|
||||||
|
* Initialization of the connection interceptor.
|
||||||
|
*
|
||||||
|
* @param loggingService - A service that provides logging capabilities.
|
||||||
|
*/
|
||||||
|
constructor(private loggingService: LoggingService) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intercepts HTTP requests.
|
||||||
|
*
|
||||||
|
* @param request - An outgoing HTTP request with an optional typed body.
|
||||||
|
* @param next - The next HTTP handler or the outgoing request dispatcher.
|
||||||
|
* @returns The forwarded request.
|
||||||
|
*/
|
||||||
|
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||||
|
checkOnlineStatus().then((online) => {
|
||||||
|
if (!online) {
|
||||||
|
this.loggingService.sendErrorLevelMessage('No internet connection on device!', this, {
|
||||||
|
error: `NetworkError when attempting to fetch resource ${request.url}.`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
return next.handle(request);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return next.handle(request);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div><div class="search-results">
|
||||||
|
<div class="has-results">
|
||||||
|
<h1 class="search-results-title"><span class='search-results-count'></span> result-matching "<span class='search-query'></span>"</h1>
|
||||||
|
<ul class="search-results-list"></ul>
|
||||||
|
</div>
|
||||||
|
<div class="no-results">
|
||||||
|
<h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- END CONTENT -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var COMPODOC_CURRENT_PAGE_DEPTH = 1;
|
||||||
|
var COMPODOC_CURRENT_PAGE_CONTEXT = 'interceptor';
|
||||||
|
var COMPODOC_CURRENT_PAGE_URL = 'ConnectionInterceptor.html';
|
||||||
|
var MAX_SEARCH_RESULTS = 15;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script src="../js/libs/custom-elements.min.js"></script>
|
||||||
|
<script src="../js/libs/lit-html.js"></script>
|
||||||
|
<!-- Required to polyfill modern browsers as code is ES5 for IE... -->
|
||||||
|
<script src="../js/libs/custom-elements-es5-adapter.js" charset="utf-8" defer></script>
|
||||||
|
<script src="../js/menu-wc.js" defer></script>
|
||||||
|
|
||||||
|
<script src="../js/libs/bootstrap-native.js"></script>
|
||||||
|
|
||||||
|
<script src="../js/libs/es6-shim.min.js"></script>
|
||||||
|
<script src="../js/libs/EventDispatcher.js"></script>
|
||||||
|
<script src="../js/libs/promise.min.js"></script>
|
||||||
|
<script src="../js/libs/zepto.min.js"></script>
|
||||||
|
|
||||||
|
<script src="../js/compodoc.js"></script>
|
||||||
|
|
||||||
|
<script src="../js/tabs.js"></script>
|
||||||
|
<script src="../js/menu.js"></script>
|
||||||
|
<script src="../js/libs/clipboard.min.js"></script>
|
||||||
|
<script src="../js/libs/prism.js"></script>
|
||||||
|
<script src="../js/sourceCode.js"></script>
|
||||||
|
<script src="../js/search/search.js"></script>
|
||||||
|
<script src="../js/search/lunr.min.js"></script>
|
||||||
|
<script src="../js/search/search-lunr.js"></script>
|
||||||
|
<script src="../js/search/search_index.js"></script>
|
||||||
|
<script src="../js/lazy-load-graphs.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,246 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html class="default no-js">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<title>ConnectionInterceptor | CICADA</title>
|
||||||
|
<meta name="description" content="Documentation for CICADA">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="../assets/css/main.css">
|
||||||
|
<script async src="../assets/js/search.js" id="search-script"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="tsd-page-toolbar">
|
||||||
|
<div class="container">
|
||||||
|
<div class="table-wrap">
|
||||||
|
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.json" data-base="..">
|
||||||
|
<div class="field">
|
||||||
|
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||||
|
<input id="tsd-search-field" type="text" />
|
||||||
|
</div>
|
||||||
|
<ul class="results">
|
||||||
|
<li class="state loading">Preparing search index...</li>
|
||||||
|
<li class="state failure">The search index is not available</li>
|
||||||
|
</ul>
|
||||||
|
<a href="../index.html" class="title">CICADA</a>
|
||||||
|
</div>
|
||||||
|
<div class="table-cell" id="tsd-widgets">
|
||||||
|
<div id="tsd-filter">
|
||||||
|
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||||
|
<div class="tsd-filter-group">
|
||||||
|
<div class="tsd-select" id="tsd-filter-visibility">
|
||||||
|
<span class="tsd-select-label">All</span>
|
||||||
|
<ul class="tsd-select-list">
|
||||||
|
<li data-value="public">Public</li>
|
||||||
|
<li data-value="protected">Public/Protected</li>
|
||||||
|
<li data-value="private" class="selected">All</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||||
|
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||||
|
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||||
|
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tsd-page-title">
|
||||||
|
<div class="container">
|
||||||
|
<ul class="tsd-breadcrumb">
|
||||||
|
<li>
|
||||||
|
<a href="../modules.html">CICADA</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="../modules/app__interceptors_connection_interceptor.html">app/_interceptors/connection.interceptor</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="app__interceptors_connection_interceptor.connectioninterceptor.html">ConnectionInterceptor</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h1>Class ConnectionInterceptor</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="container container-main">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-8 col-content">
|
||||||
|
<section class="tsd-panel tsd-comment">
|
||||||
|
<div class="tsd-comment tsd-typography">
|
||||||
|
<div class="lead">
|
||||||
|
<p>Intercepts and handles of events from outgoing HTTP request.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="tsd-panel tsd-hierarchy">
|
||||||
|
<h3>Hierarchy</h3>
|
||||||
|
<ul class="tsd-hierarchy">
|
||||||
|
<li>
|
||||||
|
<span class="target">ConnectionInterceptor</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
<section class="tsd-panel">
|
||||||
|
<h3>Implements</h3>
|
||||||
|
<ul class="tsd-hierarchy">
|
||||||
|
<li><span class="tsd-signature-type">HttpInterceptor</span></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
<section class="tsd-panel-group tsd-index-group">
|
||||||
|
<h2>Index</h2>
|
||||||
|
<section class="tsd-panel tsd-index-panel">
|
||||||
|
<div class="tsd-index-content">
|
||||||
|
<section class="tsd-index-section ">
|
||||||
|
<h3>Constructors</h3>
|
||||||
|
<ul class="tsd-index-list">
|
||||||
|
<li class="tsd-kind-constructor tsd-parent-kind-class"><a href="app__interceptors_connection_interceptor.connectioninterceptor.html#constructor" class="tsd-kind-icon">constructor</a></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
<section class="tsd-index-section ">
|
||||||
|
<h3>Methods</h3>
|
||||||
|
<ul class="tsd-index-list">
|
||||||
|
<li class="tsd-kind-method tsd-parent-kind-class"><a href="app__interceptors_connection_interceptor.connectioninterceptor.html#intercept" class="tsd-kind-icon">intercept</a></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section class="tsd-panel-group tsd-member-group ">
|
||||||
|
<h2>Constructors</h2>
|
||||||
|
<section class="tsd-panel tsd-member tsd-kind-constructor tsd-parent-kind-class">
|
||||||
|
<a name="constructor" class="tsd-anchor"></a>
|
||||||
|
<h3>constructor</h3>
|
||||||
|
<ul class="tsd-signatures tsd-kind-constructor tsd-parent-kind-class">
|
||||||
|
<li class="tsd-signature tsd-kind-icon">new <wbr>Connection<wbr>Interceptor<span class="tsd-signature-symbol">(</span>loggingService<span class="tsd-signature-symbol">: </span><a href="app__services_logging_service.loggingservice.html" class="tsd-signature-type" data-tsd-kind="Class">LoggingService</a><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><a href="app__interceptors_connection_interceptor.connectioninterceptor.html" class="tsd-signature-type" data-tsd-kind="Class">ConnectionInterceptor</a></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-descriptions">
|
||||||
|
<li class="tsd-description">
|
||||||
|
<aside class="tsd-sources">
|
||||||
|
<ul>
|
||||||
|
<li>Defined in src/app/_interceptors/connection.interceptor.ts:14</li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
<div class="tsd-comment tsd-typography">
|
||||||
|
<div class="lead">
|
||||||
|
<p>Initialization of the connection interceptor.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4 class="tsd-parameters-title">Parameters</h4>
|
||||||
|
<ul class="tsd-parameters">
|
||||||
|
<li>
|
||||||
|
<h5>loggingService: <a href="app__services_logging_service.loggingservice.html" class="tsd-signature-type" data-tsd-kind="Class">LoggingService</a></h5>
|
||||||
|
<div class="tsd-comment tsd-typography">
|
||||||
|
<p>A service that provides logging capabilities.</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h4 class="tsd-returns-title">Returns <a href="app__interceptors_connection_interceptor.connectioninterceptor.html" class="tsd-signature-type" data-tsd-kind="Class">ConnectionInterceptor</a></h4>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section class="tsd-panel-group tsd-member-group ">
|
||||||
|
<h2>Methods</h2>
|
||||||
|
<section class="tsd-panel tsd-member tsd-kind-method tsd-parent-kind-class">
|
||||||
|
<a name="intercept" class="tsd-anchor"></a>
|
||||||
|
<h3>intercept</h3>
|
||||||
|
<ul class="tsd-signatures tsd-kind-method tsd-parent-kind-class">
|
||||||
|
<li class="tsd-signature tsd-kind-icon">intercept<span class="tsd-signature-symbol">(</span>request<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">HttpRequest</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">></span>, next<span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">HttpHandler</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Observable</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">HttpEvent</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">></span><span class="tsd-signature-symbol">></span></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-descriptions">
|
||||||
|
<li class="tsd-description">
|
||||||
|
<aside class="tsd-sources">
|
||||||
|
<p>Implementation of HttpInterceptor.intercept</p>
|
||||||
|
<ul>
|
||||||
|
<li>Defined in src/app/_interceptors/connection.interceptor.ts:29</li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
<div class="tsd-comment tsd-typography">
|
||||||
|
<div class="lead">
|
||||||
|
<p>Intercepts HTTP requests.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h4 class="tsd-parameters-title">Parameters</h4>
|
||||||
|
<ul class="tsd-parameters">
|
||||||
|
<li>
|
||||||
|
<h5>request: <span class="tsd-signature-type">HttpRequest</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">></span></h5>
|
||||||
|
<div class="tsd-comment tsd-typography">
|
||||||
|
<p>An outgoing HTTP request with an optional typed body.</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<h5>next: <span class="tsd-signature-type">HttpHandler</span></h5>
|
||||||
|
<div class="tsd-comment tsd-typography">
|
||||||
|
<p>The next HTTP handler or the outgoing request dispatcher.</p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Observable</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">HttpEvent</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">unknown</span><span class="tsd-signature-symbol">></span><span class="tsd-signature-symbol">></span></h4>
|
||||||
|
<p>The forwarded request.</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||||
|
<nav class="tsd-navigation primary">
|
||||||
|
<ul>
|
||||||
|
<li class=" ">
|
||||||
|
<a href="../modules.html">Exports</a>
|
||||||
|
</li>
|
||||||
|
<li class="current tsd-kind-module">
|
||||||
|
<a href="../modules/app__interceptors_connection_interceptor.html">app/_<wbr>interceptors/connection.interceptor</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<nav class="tsd-navigation secondary menu-sticky">
|
||||||
|
<ul class="before-current">
|
||||||
|
</ul>
|
||||||
|
<ul class="current">
|
||||||
|
<li class="current tsd-kind-class tsd-parent-kind-module">
|
||||||
|
<a href="app__interceptors_connection_interceptor.connectioninterceptor.html" class="tsd-kind-icon">Connection<wbr>Interceptor</a>
|
||||||
|
<ul>
|
||||||
|
<li class=" tsd-kind-constructor tsd-parent-kind-class">
|
||||||
|
<a href="app__interceptors_connection_interceptor.connectioninterceptor.html#constructor" class="tsd-kind-icon">constructor</a>
|
||||||
|
</li>
|
||||||
|
<li class=" tsd-kind-method tsd-parent-kind-class">
|
||||||
|
<a href="app__interceptors_connection_interceptor.connectioninterceptor.html#intercept" class="tsd-kind-icon">intercept</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<ul class="after-current">
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="with-border-bottom">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Legend</h2>
|
||||||
|
<div class="tsd-legend-group">
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||||
|
<li class="tsd-kind-constructor tsd-parent-kind-class"><span class="tsd-kind-icon">Constructor</span></li>
|
||||||
|
<li class="tsd-kind-method tsd-parent-kind-class"><span class="tsd-kind-icon">Method</span></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||||
|
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<div class="container tsd-generator">
|
||||||
|
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="overlay"></div>
|
||||||
|
<script src="../assets/js/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
146
docs/typedoc/modules/app__helpers_online_status.html
Normal file
146
docs/typedoc/modules/app__helpers_online_status.html
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html class="default no-js">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<title>app/_helpers/online-status | CICADA</title>
|
||||||
|
<meta name="description" content="Documentation for CICADA">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="../assets/css/main.css">
|
||||||
|
<script async src="../assets/js/search.js" id="search-script"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="tsd-page-toolbar">
|
||||||
|
<div class="container">
|
||||||
|
<div class="table-wrap">
|
||||||
|
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.json" data-base="..">
|
||||||
|
<div class="field">
|
||||||
|
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||||
|
<input id="tsd-search-field" type="text" />
|
||||||
|
</div>
|
||||||
|
<ul class="results">
|
||||||
|
<li class="state loading">Preparing search index...</li>
|
||||||
|
<li class="state failure">The search index is not available</li>
|
||||||
|
</ul>
|
||||||
|
<a href="../index.html" class="title">CICADA</a>
|
||||||
|
</div>
|
||||||
|
<div class="table-cell" id="tsd-widgets">
|
||||||
|
<div id="tsd-filter">
|
||||||
|
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||||
|
<div class="tsd-filter-group">
|
||||||
|
<div class="tsd-select" id="tsd-filter-visibility">
|
||||||
|
<span class="tsd-select-label">All</span>
|
||||||
|
<ul class="tsd-select-list">
|
||||||
|
<li data-value="public">Public</li>
|
||||||
|
<li data-value="protected">Public/Protected</li>
|
||||||
|
<li data-value="private" class="selected">All</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||||
|
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||||
|
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||||
|
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tsd-page-title">
|
||||||
|
<div class="container">
|
||||||
|
<ul class="tsd-breadcrumb">
|
||||||
|
<li>
|
||||||
|
<a href="../modules.html">CICADA</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="app__helpers_online_status.html">app/_helpers/online-status</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h1>Module app/_helpers/online-status</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="container container-main">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-8 col-content">
|
||||||
|
<section class="tsd-panel-group tsd-index-group">
|
||||||
|
<h2>Index</h2>
|
||||||
|
<section class="tsd-panel tsd-index-panel">
|
||||||
|
<div class="tsd-index-content">
|
||||||
|
<section class="tsd-index-section ">
|
||||||
|
<h3>Functions</h3>
|
||||||
|
<ul class="tsd-index-list">
|
||||||
|
<li class="tsd-kind-function tsd-parent-kind-module"><a href="app__helpers_online_status.html#checkonlinestatus" class="tsd-kind-icon">check<wbr>Online<wbr>Status</a></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
<section class="tsd-panel-group tsd-member-group ">
|
||||||
|
<h2>Functions</h2>
|
||||||
|
<section class="tsd-panel tsd-member tsd-kind-function tsd-parent-kind-module">
|
||||||
|
<a name="checkonlinestatus" class="tsd-anchor"></a>
|
||||||
|
<h3>check<wbr>Online<wbr>Status</h3>
|
||||||
|
<ul class="tsd-signatures tsd-kind-function tsd-parent-kind-module">
|
||||||
|
<li class="tsd-signature tsd-kind-icon">check<wbr>Online<wbr>Status<span class="tsd-signature-symbol">(</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">: </span><span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">boolean</span><span class="tsd-signature-symbol">></span></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-descriptions">
|
||||||
|
<li class="tsd-description">
|
||||||
|
<aside class="tsd-sources">
|
||||||
|
<ul>
|
||||||
|
<li>Defined in src/app/_helpers/online-status.ts:6</li>
|
||||||
|
</ul>
|
||||||
|
</aside>
|
||||||
|
<h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol"><</span><span class="tsd-signature-type">boolean</span><span class="tsd-signature-symbol">></span></h4>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||||
|
<nav class="tsd-navigation primary">
|
||||||
|
<ul>
|
||||||
|
<li class=" ">
|
||||||
|
<a href="../modules.html">Exports</a>
|
||||||
|
</li>
|
||||||
|
<li class="current tsd-kind-module">
|
||||||
|
<a href="app__helpers_online_status.html">app/_<wbr>helpers/online-<wbr>status</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<nav class="tsd-navigation secondary menu-sticky">
|
||||||
|
<ul class="before-current">
|
||||||
|
<li class=" tsd-kind-function tsd-parent-kind-module">
|
||||||
|
<a href="app__helpers_online_status.html#checkonlinestatus" class="tsd-kind-icon">check<wbr>Online<wbr>Status</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="with-border-bottom">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Legend</h2>
|
||||||
|
<div class="tsd-legend-group">
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||||
|
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<div class="container tsd-generator">
|
||||||
|
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="overlay"></div>
|
||||||
|
<script src="../assets/js/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -0,0 +1,126 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html class="default no-js">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<title>app/_interceptors/connection.interceptor | CICADA</title>
|
||||||
|
<meta name="description" content="Documentation for CICADA">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="../assets/css/main.css">
|
||||||
|
<script async src="../assets/js/search.js" id="search-script"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<div class="tsd-page-toolbar">
|
||||||
|
<div class="container">
|
||||||
|
<div class="table-wrap">
|
||||||
|
<div class="table-cell" id="tsd-search" data-index="../assets/js/search.json" data-base="..">
|
||||||
|
<div class="field">
|
||||||
|
<label for="tsd-search-field" class="tsd-widget search no-caption">Search</label>
|
||||||
|
<input id="tsd-search-field" type="text" />
|
||||||
|
</div>
|
||||||
|
<ul class="results">
|
||||||
|
<li class="state loading">Preparing search index...</li>
|
||||||
|
<li class="state failure">The search index is not available</li>
|
||||||
|
</ul>
|
||||||
|
<a href="../index.html" class="title">CICADA</a>
|
||||||
|
</div>
|
||||||
|
<div class="table-cell" id="tsd-widgets">
|
||||||
|
<div id="tsd-filter">
|
||||||
|
<a href="#" class="tsd-widget options no-caption" data-toggle="options">Options</a>
|
||||||
|
<div class="tsd-filter-group">
|
||||||
|
<div class="tsd-select" id="tsd-filter-visibility">
|
||||||
|
<span class="tsd-select-label">All</span>
|
||||||
|
<ul class="tsd-select-list">
|
||||||
|
<li data-value="public">Public</li>
|
||||||
|
<li data-value="protected">Public/Protected</li>
|
||||||
|
<li data-value="private" class="selected">All</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<input type="checkbox" id="tsd-filter-inherited" checked />
|
||||||
|
<label class="tsd-widget" for="tsd-filter-inherited">Inherited</label>
|
||||||
|
<input type="checkbox" id="tsd-filter-externals" checked />
|
||||||
|
<label class="tsd-widget" for="tsd-filter-externals">Externals</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="#" class="tsd-widget menu no-caption" data-toggle="menu">Menu</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="tsd-page-title">
|
||||||
|
<div class="container">
|
||||||
|
<ul class="tsd-breadcrumb">
|
||||||
|
<li>
|
||||||
|
<a href="../modules.html">CICADA</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="app__interceptors_connection_interceptor.html">app/_interceptors/connection.interceptor</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<h1>Module app/_interceptors/connection.interceptor</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="container container-main">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-8 col-content">
|
||||||
|
<section class="tsd-panel-group tsd-index-group">
|
||||||
|
<h2>Index</h2>
|
||||||
|
<section class="tsd-panel tsd-index-panel">
|
||||||
|
<div class="tsd-index-content">
|
||||||
|
<section class="tsd-index-section ">
|
||||||
|
<h3>Classes</h3>
|
||||||
|
<ul class="tsd-index-list">
|
||||||
|
<li class="tsd-kind-class tsd-parent-kind-module"><a href="../classes/app__interceptors_connection_interceptor.connectioninterceptor.html" class="tsd-kind-icon">Connection<wbr>Interceptor</a></li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
|
||||||
|
<nav class="tsd-navigation primary">
|
||||||
|
<ul>
|
||||||
|
<li class=" ">
|
||||||
|
<a href="../modules.html">Exports</a>
|
||||||
|
</li>
|
||||||
|
<li class="current tsd-kind-module">
|
||||||
|
<a href="app__interceptors_connection_interceptor.html">app/_<wbr>interceptors/connection.interceptor</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<nav class="tsd-navigation secondary menu-sticky">
|
||||||
|
<ul class="before-current">
|
||||||
|
<li class=" tsd-kind-class tsd-parent-kind-module">
|
||||||
|
<a href="../classes/app__interceptors_connection_interceptor.connectioninterceptor.html" class="tsd-kind-icon">Connection<wbr>Interceptor</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<footer class="with-border-bottom">
|
||||||
|
<div class="container">
|
||||||
|
<h2>Legend</h2>
|
||||||
|
<div class="tsd-legend-group">
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-variable"><span class="tsd-kind-icon">Variable</span></li>
|
||||||
|
<li class="tsd-kind-function"><span class="tsd-kind-icon">Function</span></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-interface"><span class="tsd-kind-icon">Interface</span></li>
|
||||||
|
</ul>
|
||||||
|
<ul class="tsd-legend">
|
||||||
|
<li class="tsd-kind-class"><span class="tsd-kind-icon">Class</span></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
<div class="container tsd-generator">
|
||||||
|
<p>Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p>
|
||||||
|
</div>
|
||||||
|
<div class="overlay"></div>
|
||||||
|
<script src="../assets/js/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -9,3 +9,4 @@ export * from '@app/_helpers/mock-backend';
|
|||||||
export * from '@app/_helpers/read-csv';
|
export * from '@app/_helpers/read-csv';
|
||||||
export * from '@app/_helpers/schema-validation';
|
export * from '@app/_helpers/schema-validation';
|
||||||
export * from '@app/_helpers/sync';
|
export * from '@app/_helpers/sync';
|
||||||
|
export * from '@app/_helpers/online-status';
|
||||||
|
15
src/app/_helpers/online-status.ts
Normal file
15
src/app/_helpers/online-status.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const apiUrls = [
|
||||||
|
'https://api.coindesk.com/v1/bpi/currentprice.json',
|
||||||
|
'https://dog.ceo/api/breeds/image/random',
|
||||||
|
];
|
||||||
|
|
||||||
|
async function checkOnlineStatus(): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
const online = await fetch(apiUrls[Math.floor(Math.random() * apiUrls.length)]);
|
||||||
|
return online.status >= 200 && online.status < 300;
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { checkOnlineStatus };
|
16
src/app/_interceptors/connection.interceptor.spec.ts
Normal file
16
src/app/_interceptors/connection.interceptor.spec.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { ConnectionInterceptor } from './connection.interceptor';
|
||||||
|
|
||||||
|
describe('ConnectionInterceptor', () => {
|
||||||
|
beforeEach(() =>
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
providers: [ConnectionInterceptor],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
it('should be created', () => {
|
||||||
|
const interceptor: ConnectionInterceptor = TestBed.inject(ConnectionInterceptor);
|
||||||
|
expect(interceptor).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
42
src/app/_interceptors/connection.interceptor.ts
Normal file
42
src/app/_interceptors/connection.interceptor.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Core imports
|
||||||
|
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
// Third party imports
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
|
// Application imports
|
||||||
|
import { LoggingService } from '@app/_services/logging.service';
|
||||||
|
import { checkOnlineStatus } from '@app/_helpers';
|
||||||
|
|
||||||
|
/** Intercepts and handles of events from outgoing HTTP request. */
|
||||||
|
@Injectable()
|
||||||
|
export class ConnectionInterceptor implements HttpInterceptor {
|
||||||
|
/**
|
||||||
|
* Initialization of the connection interceptor.
|
||||||
|
*
|
||||||
|
* @param loggingService - A service that provides logging capabilities.
|
||||||
|
*/
|
||||||
|
constructor(private loggingService: LoggingService) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Intercepts HTTP requests.
|
||||||
|
*
|
||||||
|
* @param request - An outgoing HTTP request with an optional typed body.
|
||||||
|
* @param next - The next HTTP handler or the outgoing request dispatcher.
|
||||||
|
* @returns The forwarded request.
|
||||||
|
*/
|
||||||
|
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
|
||||||
|
checkOnlineStatus().then((online) => {
|
||||||
|
if (!online) {
|
||||||
|
this.loggingService.sendErrorLevelMessage('No internet connection on device!', this, {
|
||||||
|
error: `NetworkError when attempting to fetch resource ${request.url}.`,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
return next.handle(request);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return next.handle(request);
|
||||||
|
}
|
||||||
|
}
|
@ -59,9 +59,10 @@ export class ErrorInterceptor implements HttpInterceptor {
|
|||||||
this.router.navigateByUrl('/auth').then();
|
this.router.navigateByUrl('/auth').then();
|
||||||
break;
|
break;
|
||||||
case 403: // forbidden
|
case 403: // forbidden
|
||||||
this.errorDialogService.openDialog(
|
this.errorDialogService.openDialog({
|
||||||
{ message: 'Access to resource is not allowed (Error 403)'})
|
message: 'Access to resource is not allowed (Error 403)',
|
||||||
//alert('Access to resource is not allowed!');
|
});
|
||||||
|
// alert('Access to resource is not allowed!');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Return an observable with a user-facing error message.
|
// Return an observable with a user-facing error message.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
export * from '@app/_interceptors/connection.interceptor';
|
||||||
export * from '@app/_interceptors/error.interceptor';
|
export * from '@app/_interceptors/error.interceptor';
|
||||||
export * from '@app/_interceptors/http-config.interceptor';
|
export * from '@app/_interceptors/http-config.interceptor';
|
||||||
export * from '@app/_interceptors/logging.interceptor';
|
export * from '@app/_interceptors/logging.interceptor';
|
||||||
|
@ -5,7 +5,6 @@ import { environment } from '@src/environments/environment';
|
|||||||
import { LoggingService } from '@app/_services/logging.service';
|
import { LoggingService } from '@app/_services/logging.service';
|
||||||
import { MutableKeyStore } from '@app/_pgp';
|
import { MutableKeyStore } from '@app/_pgp';
|
||||||
import { ErrorDialogService } from '@app/_services/error-dialog.service';
|
import { ErrorDialogService } from '@app/_services/error-dialog.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
|
||||||
import { HttpError, rejectBody } from '@app/_helpers/global-error-handler';
|
import { HttpError, rejectBody } from '@app/_helpers/global-error-handler';
|
||||||
import { Staff } from '@app/_models';
|
import { Staff } from '@app/_models';
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, Observable } from 'rxjs';
|
||||||
@ -23,7 +22,6 @@ export class AuthService {
|
|||||||
trustedUsersSubject: Observable<Array<Staff>> = this.trustedUsersList.asObservable();
|
trustedUsersSubject: Observable<Array<Staff>> = this.trustedUsersList.asObservable();
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private httpClient: HttpClient,
|
|
||||||
private loggingService: LoggingService,
|
private loggingService: LoggingService,
|
||||||
private errorDialogService: ErrorDialogService
|
private errorDialogService: ErrorDialogService
|
||||||
) {}
|
) {}
|
||||||
@ -48,7 +46,7 @@ export class AuthService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getWithToken(): Promise<boolean> {
|
getWithToken(): Promise<boolean> {
|
||||||
const sessionToken = this.getSessionToken()
|
const sessionToken = this.getSessionToken();
|
||||||
const headers = {
|
const headers = {
|
||||||
Authorization: 'Bearer ' + sessionToken,
|
Authorization: 'Bearer ' + sessionToken,
|
||||||
'Content-Type': 'application/json;charset=utf-8',
|
'Content-Type': 'application/json;charset=utf-8',
|
||||||
@ -98,29 +96,28 @@ export class AuthService {
|
|||||||
const o = await this.getChallenge();
|
const o = await this.getChallenge();
|
||||||
|
|
||||||
const r = await signChallenge(
|
const r = await signChallenge(
|
||||||
o.challenge,
|
o.challenge,
|
||||||
o.realm,
|
o.realm,
|
||||||
environment.cicMetaUrl,
|
environment.cicMetaUrl,
|
||||||
this.mutableKeyStore
|
this.mutableKeyStore
|
||||||
);
|
);
|
||||||
|
|
||||||
const tokenResponse = await this.sendSignedChallenge(r)
|
const tokenResponse = await this.sendSignedChallenge(r).then((response) => {
|
||||||
.then((response) => {
|
const token = response.headers.get('Token');
|
||||||
const token = response.headers.get('Token');
|
if (token) {
|
||||||
if (token) {
|
return token;
|
||||||
return token;
|
}
|
||||||
}
|
if (response.status === 401) {
|
||||||
if (response.status === 401) {
|
throw new HttpError('You are not authorized to use this system', response.status);
|
||||||
throw new HttpError('You are not authorized to use this system', response.status);
|
}
|
||||||
}
|
if (!response.ok) {
|
||||||
if (!response.ok) {
|
throw new HttpError('Unknown error from authentication server', response.status);
|
||||||
throw new HttpError('Unknown error from authentication server', response.status);
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
if (tokenResponse) {
|
if (tokenResponse) {
|
||||||
this.setSessionToken(tokenResponse);
|
this.setSessionToken(tokenResponse);
|
||||||
//this.setState('Click button to log in');
|
// this.setState('Click button to log in');
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -4,7 +4,6 @@ import { TransactionHelper } from '@cicnet/cic-client';
|
|||||||
import { first } from 'rxjs/operators';
|
import { first } from 'rxjs/operators';
|
||||||
import { TransactionService } from '@app/_services/transaction.service';
|
import { TransactionService } from '@app/_services/transaction.service';
|
||||||
import { environment } from '@src/environments/environment';
|
import { environment } from '@src/environments/environment';
|
||||||
import { LoggingService } from '@app/_services/logging.service';
|
|
||||||
import { RegistryService } from '@app/_services/registry.service';
|
import { RegistryService } from '@app/_services/registry.service';
|
||||||
import { Web3Service } from '@app/_services/web3.service';
|
import { Web3Service } from '@app/_services/web3.service';
|
||||||
|
|
||||||
@ -15,17 +14,9 @@ export class BlockSyncService {
|
|||||||
readyStateTarget: number = 2;
|
readyStateTarget: number = 2;
|
||||||
readyState: number = 0;
|
readyState: number = 0;
|
||||||
|
|
||||||
constructor(
|
constructor(private transactionService: TransactionService) {}
|
||||||
private transactionService: TransactionService,
|
|
||||||
private loggingService: LoggingService
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async init(): Promise<void> {
|
|
||||||
await this.transactionService.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
async blockSync(address: string = null, offset: number = 0, limit: number = 100): Promise<void> {
|
async blockSync(address: string = null, offset: number = 0, limit: number = 100): Promise<void> {
|
||||||
this.transactionService.resetTransactionsList();
|
|
||||||
const settings: Settings = new Settings(this.scan);
|
const settings: Settings = new Settings(this.scan);
|
||||||
const readyStateElements: { network: number } = { network: 2 };
|
const readyStateElements: { network: number } = { network: 2 };
|
||||||
settings.w3.provider = environment.web3Provider;
|
settings.w3.provider = environment.web3Provider;
|
||||||
|
@ -35,6 +35,7 @@ export class LocationService {
|
|||||||
return queriedAreaName;
|
return queriedAreaName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 'other';
|
||||||
}
|
}
|
||||||
|
|
||||||
getAreaTypes(): void {
|
getAreaTypes(): void {
|
||||||
@ -54,5 +55,6 @@ export class LocationService {
|
|||||||
return queriedAreaType;
|
return queriedAreaType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 'other';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,6 @@ import { NGXLogger } from 'ngx-logger';
|
|||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
})
|
})
|
||||||
export class LoggingService {
|
export class LoggingService {
|
||||||
env: string;
|
|
||||||
canDebug: boolean;
|
|
||||||
|
|
||||||
constructor(private logger: NGXLogger) {
|
constructor(private logger: NGXLogger) {
|
||||||
// TRACE|DEBUG|INFO|LOG|WARN|ERROR|FATAL|OFF
|
// TRACE|DEBUG|INFO|LOG|WARN|ERROR|FATAL|OFF
|
||||||
if (isDevMode()) {
|
if (isDevMode()) {
|
||||||
|
@ -22,9 +22,7 @@ export class TokenService {
|
|||||||
|
|
||||||
async init(): Promise<void> {
|
async init(): Promise<void> {
|
||||||
this.registry = await RegistryService.getRegistry();
|
this.registry = await RegistryService.getRegistry();
|
||||||
this.tokenRegistry = new TokenRegistry(
|
this.tokenRegistry = await RegistryService.getTokenRegistry();
|
||||||
await this.registry.getContractAddressByName('TokenRegistry')
|
|
||||||
);
|
|
||||||
this.load.next(true);
|
this.load.next(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ import { add0x, fromHex, strip0x, toHex } from '@src/assets/js/ethtx/dist/hex';
|
|||||||
import { Tx } from '@src/assets/js/ethtx/dist';
|
import { Tx } from '@src/assets/js/ethtx/dist';
|
||||||
import { toValue } from '@src/assets/js/ethtx/dist/tx';
|
import { toValue } from '@src/assets/js/ethtx/dist/tx';
|
||||||
import * as secp256k1 from 'secp256k1';
|
import * as secp256k1 from 'secp256k1';
|
||||||
import { AuthService } from '@app/_services/auth.service';
|
|
||||||
import { defaultAccount } from '@app/_models';
|
import { defaultAccount } from '@app/_models';
|
||||||
import { LoggingService } from '@app/_services/logging.service';
|
import { LoggingService } from '@app/_services/logging.service';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
@ -28,13 +27,11 @@ export class TransactionService {
|
|||||||
transactions: any[] = [];
|
transactions: any[] = [];
|
||||||
private transactionList = new BehaviorSubject<any[]>(this.transactions);
|
private transactionList = new BehaviorSubject<any[]>(this.transactions);
|
||||||
transactionsSubject = this.transactionList.asObservable();
|
transactionsSubject = this.transactionList.asObservable();
|
||||||
userInfo: any;
|
|
||||||
web3: Web3;
|
web3: Web3;
|
||||||
registry: CICRegistry;
|
registry: CICRegistry;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private httpClient: HttpClient,
|
private httpClient: HttpClient,
|
||||||
private authService: AuthService,
|
|
||||||
private userService: UserService,
|
private userService: UserService,
|
||||||
private loggingService: LoggingService
|
private loggingService: LoggingService
|
||||||
) {
|
) {
|
||||||
@ -42,8 +39,6 @@ export class TransactionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async init(): Promise<void> {
|
async init(): Promise<void> {
|
||||||
await this.authService.init();
|
|
||||||
await this.userService.init();
|
|
||||||
this.registry = await RegistryService.getRegistry();
|
this.registry = await RegistryService.getRegistry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,11 +7,9 @@ import { ArgPair, Envelope, Phone, Syncable, User } from 'cic-client-meta';
|
|||||||
import { AccountDetails } from '@app/_models';
|
import { AccountDetails } from '@app/_models';
|
||||||
import { LoggingService } from '@app/_services/logging.service';
|
import { LoggingService } from '@app/_services/logging.service';
|
||||||
import { TokenService } from '@app/_services/token.service';
|
import { TokenService } from '@app/_services/token.service';
|
||||||
import { AccountIndex } from '@app/_eth';
|
|
||||||
import { MutableKeyStore, PGPSigner, Signer } from '@app/_pgp';
|
import { MutableKeyStore, PGPSigner, Signer } from '@app/_pgp';
|
||||||
import { RegistryService } from '@app/_services/registry.service';
|
import { RegistryService } from '@app/_services/registry.service';
|
||||||
import { CICRegistry } from '@cicnet/cic-client';
|
import { CICRegistry } from '@cicnet/cic-client';
|
||||||
import { AuthService } from '@app/_services/auth.service';
|
|
||||||
import { personValidation, updateSyncable, vcardValidation } from '@app/_helpers';
|
import { personValidation, updateSyncable, vcardValidation } from '@app/_helpers';
|
||||||
import { add0x } from '@src/assets/js/ethtx/dist/hex';
|
import { add0x } from '@src/assets/js/ethtx/dist/hex';
|
||||||
import { KeystoreService } from '@app/_services/keystore.service';
|
import { KeystoreService } from '@app/_services/keystore.service';
|
||||||
@ -43,13 +41,10 @@ export class UserService {
|
|||||||
constructor(
|
constructor(
|
||||||
private httpClient: HttpClient,
|
private httpClient: HttpClient,
|
||||||
private loggingService: LoggingService,
|
private loggingService: LoggingService,
|
||||||
private tokenService: TokenService,
|
private tokenService: TokenService
|
||||||
private authService: AuthService
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async init(): Promise<void> {
|
async init(): Promise<void> {
|
||||||
await this.authService.init();
|
|
||||||
await this.tokenService.init();
|
|
||||||
this.keystore = await KeystoreService.getKeystore();
|
this.keystore = await KeystoreService.getKeystore();
|
||||||
this.signer = new PGPSigner(this.keystore);
|
this.signer = new PGPSigner(this.keystore);
|
||||||
this.registry = await RegistryService.getRegistry();
|
this.registry = await RegistryService.getRegistry();
|
||||||
@ -203,12 +198,6 @@ export class UserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async loadAccounts(limit: number = 100, offset: number = 0): Promise<void> {
|
async loadAccounts(limit: number = 100, offset: number = 0): Promise<void> {
|
||||||
this.resetAccountsList();
|
|
||||||
// const accountIndexAddress: string = await this.registry.getContractAddressByName(
|
|
||||||
// 'AccountRegistry'
|
|
||||||
// );
|
|
||||||
// const accountIndexQuery = new AccountIndex(accountIndexAddress);
|
|
||||||
// const accountAddresses: Array<string> = await accountIndexQuery.last(limit);
|
|
||||||
try {
|
try {
|
||||||
const accountRegistry = await RegistryService.getAccountRegistry();
|
const accountRegistry = await RegistryService.getAccountRegistry();
|
||||||
const accountAddresses: Array<string> = await accountRegistry.last(limit);
|
const accountAddresses: Array<string> = await accountRegistry.last(limit);
|
||||||
@ -271,10 +260,6 @@ export class UserService {
|
|||||||
this.accountsList.next(this.accounts);
|
this.accountsList.next(this.accounts);
|
||||||
}
|
}
|
||||||
|
|
||||||
searchAccountByName(name: string): any {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
getCategories(): void {
|
getCategories(): void {
|
||||||
this.httpClient
|
this.httpClient
|
||||||
.get(`${environment.cicMetaUrl}/categories`)
|
.get(`${environment.cicMetaUrl}/categories`)
|
||||||
@ -292,6 +277,7 @@ export class UserService {
|
|||||||
return queriedCategory;
|
return queriedCategory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 'other';
|
||||||
}
|
}
|
||||||
|
|
||||||
getAccountTypes(): Observable<any> {
|
getAccountTypes(): Observable<any> {
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
import { ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core';
|
import { ChangeDetectionStrategy, Component, HostListener, OnInit } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
AuthService,
|
AuthService,
|
||||||
|
BlockSyncService,
|
||||||
ErrorDialogService,
|
ErrorDialogService,
|
||||||
LoggingService,
|
LoggingService,
|
||||||
|
TokenService,
|
||||||
TransactionService,
|
TransactionService,
|
||||||
|
UserService,
|
||||||
} from '@app/_services';
|
} from '@app/_services';
|
||||||
import { catchError } from 'rxjs/operators';
|
|
||||||
import { SwUpdate } from '@angular/service-worker';
|
import { SwUpdate } from '@angular/service-worker';
|
||||||
|
import { NavigationEnd, Router } from '@angular/router';
|
||||||
|
import { filter } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@ -16,16 +20,20 @@ import { SwUpdate } from '@angular/service-worker';
|
|||||||
})
|
})
|
||||||
export class AppComponent implements OnInit {
|
export class AppComponent implements OnInit {
|
||||||
title = 'CICADA';
|
title = 'CICADA';
|
||||||
readyStateTarget: number = 3;
|
|
||||||
readyState: number = 0;
|
|
||||||
mediaQuery: MediaQueryList = window.matchMedia('(max-width: 768px)');
|
mediaQuery: MediaQueryList = window.matchMedia('(max-width: 768px)');
|
||||||
|
url: string;
|
||||||
|
accountDetailsRegex = '/accounts/[a-z,A-Z,0-9]{40}';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private authService: AuthService,
|
private authService: AuthService,
|
||||||
private transactionService: TransactionService,
|
private blockSyncService: BlockSyncService,
|
||||||
private loggingService: LoggingService,
|
|
||||||
private errorDialogService: ErrorDialogService,
|
private errorDialogService: ErrorDialogService,
|
||||||
private swUpdate: SwUpdate
|
private loggingService: LoggingService,
|
||||||
|
private tokenService: TokenService,
|
||||||
|
private transactionService: TransactionService,
|
||||||
|
private userService: UserService,
|
||||||
|
private swUpdate: SwUpdate,
|
||||||
|
private router: Router
|
||||||
) {
|
) {
|
||||||
this.mediaQuery.addEventListener('change', this.onResize);
|
this.mediaQuery.addEventListener('change', this.onResize);
|
||||||
this.onResize(this.mediaQuery);
|
this.onResize(this.mediaQuery);
|
||||||
@ -33,7 +41,34 @@ export class AppComponent implements OnInit {
|
|||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
await this.authService.init();
|
await this.authService.init();
|
||||||
|
await this.tokenService.init();
|
||||||
|
await this.userService.init();
|
||||||
await this.transactionService.init();
|
await this.transactionService.init();
|
||||||
|
await this.router.events
|
||||||
|
.pipe(filter((e) => e instanceof NavigationEnd))
|
||||||
|
.forEach(async (routeInfo) => {
|
||||||
|
if (routeInfo instanceof NavigationEnd) {
|
||||||
|
this.url = routeInfo.url;
|
||||||
|
if (!this.url.match(this.accountDetailsRegex) || !this.url.includes('tx')) {
|
||||||
|
await this.blockSyncService.blockSync();
|
||||||
|
}
|
||||||
|
if (!this.url.includes('accounts')) {
|
||||||
|
try {
|
||||||
|
// TODO it feels like this should be in the onInit handler
|
||||||
|
await this.userService.loadAccounts(100);
|
||||||
|
} catch (error) {
|
||||||
|
this.loggingService.sendErrorLevelMessage('Failed to load accounts', this, { error });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.url.includes('tokens')) {
|
||||||
|
this.tokenService.load.subscribe(async (status: boolean) => {
|
||||||
|
if (status) {
|
||||||
|
await this.tokenService.getTokens();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
const publicKeys = await this.authService.getPublicKeys();
|
const publicKeys = await this.authService.getPublicKeys();
|
||||||
await this.authService.mutableKeyStore.importPublicKey(publicKeys);
|
await this.authService.mutableKeyStore.importPublicKey(publicKeys);
|
||||||
|
@ -11,7 +11,12 @@ import { MatTableModule } from '@angular/material/table';
|
|||||||
import { AuthGuard } from '@app/_guards';
|
import { AuthGuard } from '@app/_guards';
|
||||||
import { LoggerModule } from 'ngx-logger';
|
import { LoggerModule } from 'ngx-logger';
|
||||||
import { environment } from '@src/environments/environment';
|
import { environment } from '@src/environments/environment';
|
||||||
import { ErrorInterceptor, HttpConfigInterceptor, LoggingInterceptor } from '@app/_interceptors';
|
import {
|
||||||
|
ConnectionInterceptor,
|
||||||
|
ErrorInterceptor,
|
||||||
|
HttpConfigInterceptor,
|
||||||
|
LoggingInterceptor,
|
||||||
|
} from '@app/_interceptors';
|
||||||
import { MutablePgpKeyStore } from '@app/_pgp';
|
import { MutablePgpKeyStore } from '@app/_pgp';
|
||||||
import { ServiceWorkerModule } from '@angular/service-worker';
|
import { ServiceWorkerModule } from '@angular/service-worker';
|
||||||
|
|
||||||
@ -38,6 +43,7 @@ import { ServiceWorkerModule } from '@angular/service-worker';
|
|||||||
MockBackendProvider,
|
MockBackendProvider,
|
||||||
GlobalErrorHandler,
|
GlobalErrorHandler,
|
||||||
{ provide: ErrorHandler, useClass: GlobalErrorHandler },
|
{ provide: ErrorHandler, useClass: GlobalErrorHandler },
|
||||||
|
{ provide: HTTP_INTERCEPTORS, useClass: ConnectionInterceptor, multi: true },
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true },
|
{ provide: HTTP_INTERCEPTORS, useClass: HttpConfigInterceptor, multi: true },
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
|
{ provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true },
|
||||||
{ provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true },
|
{ provide: HTTP_INTERCEPTORS, useClass: LoggingInterceptor, multi: true },
|
||||||
|
@ -3,7 +3,6 @@ import { FormBuilder, FormGroup, Validators } from '@angular/forms';
|
|||||||
import { CustomErrorStateMatcher } from '@app/_helpers';
|
import { CustomErrorStateMatcher } from '@app/_helpers';
|
||||||
import { AuthService } from '@app/_services';
|
import { AuthService } from '@app/_services';
|
||||||
import { ErrorDialogService } from '@app/_services/error-dialog.service';
|
import { ErrorDialogService } from '@app/_services/error-dialog.service';
|
||||||
import { LoggingService } from '@app/_services/logging.service';
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -25,7 +24,7 @@ export class AuthComponent implements OnInit {
|
|||||||
private errorDialogService: ErrorDialogService
|
private errorDialogService: ErrorDialogService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
ngOnInit(): void {
|
||||||
this.keyForm = this.formBuilder.group({
|
this.keyForm = this.formBuilder.group({
|
||||||
key: ['', Validators.required],
|
key: ['', Validators.required],
|
||||||
});
|
});
|
||||||
@ -58,7 +57,7 @@ export class AuthComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
} catch (HttpError) {
|
} catch (HttpError) {
|
||||||
this.errorDialogService.openDialog({
|
this.errorDialogService.openDialog({
|
||||||
message: "Failed to login please try again.",
|
message: 'Failed to login please try again.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,6 +382,11 @@
|
|||||||
<mat-icon matSuffix>search</mat-icon>
|
<mat-icon matSuffix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div *ngIf="transactionsLoading">
|
||||||
|
<h2 class="text-center"><strong>Loading Transactions!</strong></h2>
|
||||||
|
<mat-progress-bar [mode]="'query'"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table
|
<table
|
||||||
mat-table
|
mat-table
|
||||||
class="mat-elevation-z10"
|
class="mat-elevation-z10"
|
||||||
@ -491,6 +496,11 @@
|
|||||||
<mat-icon matSuffix>search</mat-icon>
|
<mat-icon matSuffix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div *ngIf="accountsLoading">
|
||||||
|
<h2 class="text-center"><strong>Loading Accounts!</strong></h2>
|
||||||
|
<mat-progress-bar [mode]="'query'"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mat-table
|
<mat-table
|
||||||
class="mat-elevation-z10"
|
class="mat-elevation-z10"
|
||||||
[dataSource]="userDataSource"
|
[dataSource]="userDataSource"
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import {
|
import {
|
||||||
|
AfterViewInit,
|
||||||
ChangeDetectionStrategy,
|
ChangeDetectionStrategy,
|
||||||
ChangeDetectorRef,
|
ChangeDetectorRef,
|
||||||
Component,
|
Component,
|
||||||
@ -31,7 +32,7 @@ import { AccountDetails, Transaction } from '@app/_models';
|
|||||||
styleUrls: ['./account-details.component.scss'],
|
styleUrls: ['./account-details.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AccountDetailsComponent implements OnInit {
|
export class AccountDetailsComponent implements OnInit, AfterViewInit {
|
||||||
transactionsDataSource: MatTableDataSource<any>;
|
transactionsDataSource: MatTableDataSource<any>;
|
||||||
transactionsDisplayedColumns: Array<string> = ['sender', 'recipient', 'value', 'created', 'type'];
|
transactionsDisplayedColumns: Array<string> = ['sender', 'recipient', 'value', 'created', 'type'];
|
||||||
transactionsDefaultPageSize: number = 10;
|
transactionsDefaultPageSize: number = 10;
|
||||||
@ -68,6 +69,8 @@ export class AccountDetailsComponent implements OnInit {
|
|||||||
category: string;
|
category: string;
|
||||||
area: string;
|
area: string;
|
||||||
areaType: string;
|
areaType: string;
|
||||||
|
accountsLoading: boolean = true;
|
||||||
|
transactionsLoading: boolean = true;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private formBuilder: FormBuilder,
|
private formBuilder: FormBuilder,
|
||||||
@ -103,10 +106,7 @@ export class AccountDetailsComponent implements OnInit {
|
|||||||
location: ['', Validators.required],
|
location: ['', Validators.required],
|
||||||
locationType: ['', Validators.required],
|
locationType: ['', Validators.required],
|
||||||
});
|
});
|
||||||
await this.blockSyncService.init();
|
this.transactionService.resetTransactionsList();
|
||||||
await this.tokenService.init();
|
|
||||||
await this.transactionService.init();
|
|
||||||
await this.userService.init();
|
|
||||||
await this.blockSyncService.blockSync(this.accountAddress);
|
await this.blockSyncService.blockSync(this.accountAddress);
|
||||||
this.userService.resetAccountsList();
|
this.userService.resetAccountsList();
|
||||||
(await this.userService.getAccountByAddress(this.accountAddress, 100)).subscribe(
|
(await this.userService.getAccountByAddress(this.accountAddress, 100)).subscribe(
|
||||||
@ -114,7 +114,6 @@ export class AccountDetailsComponent implements OnInit {
|
|||||||
if (res !== undefined) {
|
if (res !== undefined) {
|
||||||
this.account = res;
|
this.account = res;
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
this.loggingService.sendInfoLevelMessage(this.account);
|
|
||||||
this.locationService.areaNamesSubject.subscribe((response) => {
|
this.locationService.areaNamesSubject.subscribe((response) => {
|
||||||
this.area = this.locationService.getAreaNameByLocation(
|
this.area = this.locationService.getAreaNameByLocation(
|
||||||
this.account.location.area_name,
|
this.account.location.area_name,
|
||||||
@ -158,6 +157,9 @@ export class AccountDetailsComponent implements OnInit {
|
|||||||
this.userDataSource.paginator = this.userTablePaginator;
|
this.userDataSource.paginator = this.userTablePaginator;
|
||||||
this.userDataSource.sort = this.userTableSort;
|
this.userDataSource.sort = this.userTableSort;
|
||||||
this.accounts = accounts;
|
this.accounts = accounts;
|
||||||
|
if (accounts.length > 0) {
|
||||||
|
this.accountsLoading = false;
|
||||||
|
}
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -166,6 +168,9 @@ export class AccountDetailsComponent implements OnInit {
|
|||||||
this.transactionsDataSource.paginator = this.transactionTablePaginator;
|
this.transactionsDataSource.paginator = this.transactionTablePaginator;
|
||||||
this.transactionsDataSource.sort = this.transactionTableSort;
|
this.transactionsDataSource.sort = this.transactionTableSort;
|
||||||
this.transactions = transactions;
|
this.transactions = transactions;
|
||||||
|
if (transactions.length > 0) {
|
||||||
|
this.transactionsLoading = false;
|
||||||
|
}
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
});
|
});
|
||||||
this.userService.getCategories();
|
this.userService.getCategories();
|
||||||
@ -199,6 +204,17 @@ export class AccountDetailsComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
if (this.userDataSource) {
|
||||||
|
this.userDataSource.paginator = this.userTablePaginator;
|
||||||
|
this.userDataSource.sort = this.userTableSort;
|
||||||
|
}
|
||||||
|
if (this.transactionsDataSource) {
|
||||||
|
this.transactionsDataSource.paginator = this.transactionTablePaginator;
|
||||||
|
this.transactionsDataSource.sort = this.transactionTableSort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
doTransactionFilter(value: string): void {
|
doTransactionFilter(value: string): void {
|
||||||
this.transactionsDataSource.filter = value.trim().toLocaleLowerCase();
|
this.transactionsDataSource.filter = value.trim().toLocaleLowerCase();
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,6 @@ import { environment } from '@src/environments/environment';
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AccountSearchComponent implements OnInit {
|
export class AccountSearchComponent implements OnInit {
|
||||||
nameSearchForm: FormGroup;
|
|
||||||
nameSearchSubmitted: boolean = false;
|
|
||||||
nameSearchLoading: boolean = false;
|
|
||||||
phoneSearchForm: FormGroup;
|
phoneSearchForm: FormGroup;
|
||||||
phoneSearchSubmitted: boolean = false;
|
phoneSearchSubmitted: boolean = false;
|
||||||
phoneSearchLoading: boolean = false;
|
phoneSearchLoading: boolean = false;
|
||||||
@ -29,9 +26,6 @@ export class AccountSearchComponent implements OnInit {
|
|||||||
private userService: UserService,
|
private userService: UserService,
|
||||||
private router: Router
|
private router: Router
|
||||||
) {
|
) {
|
||||||
this.nameSearchForm = this.formBuilder.group({
|
|
||||||
name: ['', Validators.required],
|
|
||||||
});
|
|
||||||
this.phoneSearchForm = this.formBuilder.group({
|
this.phoneSearchForm = this.formBuilder.group({
|
||||||
phoneNumber: ['', Validators.required],
|
phoneNumber: ['', Validators.required],
|
||||||
});
|
});
|
||||||
@ -40,13 +34,8 @@ export class AccountSearchComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
ngOnInit(): void {}
|
||||||
await this.userService.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
get nameSearchFormStub(): any {
|
|
||||||
return this.nameSearchForm.controls;
|
|
||||||
}
|
|
||||||
get phoneSearchFormStub(): any {
|
get phoneSearchFormStub(): any {
|
||||||
return this.phoneSearchForm.controls;
|
return this.phoneSearchForm.controls;
|
||||||
}
|
}
|
||||||
@ -54,16 +43,6 @@ export class AccountSearchComponent implements OnInit {
|
|||||||
return this.addressSearchForm.controls;
|
return this.addressSearchForm.controls;
|
||||||
}
|
}
|
||||||
|
|
||||||
onNameSearch(): void {
|
|
||||||
this.nameSearchSubmitted = true;
|
|
||||||
if (this.nameSearchForm.invalid) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.nameSearchLoading = true;
|
|
||||||
this.userService.searchAccountByName(this.nameSearchFormStub.name.value);
|
|
||||||
this.nameSearchLoading = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
async onPhoneSearch(): Promise<void> {
|
async onPhoneSearch(): Promise<void> {
|
||||||
this.phoneSearchSubmitted = true;
|
this.phoneSearchSubmitted = true;
|
||||||
if (this.phoneSearchForm.invalid) {
|
if (this.phoneSearchForm.invalid) {
|
||||||
|
@ -64,6 +64,11 @@
|
|||||||
<mat-icon matSuffix>search</mat-icon>
|
<mat-icon matSuffix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div *ngIf="loading">
|
||||||
|
<h2 class="text-center"><strong>Loading Accounts!</strong></h2>
|
||||||
|
<mat-progress-bar [mode]="'query'"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mat-table
|
<mat-table
|
||||||
class="mat-elevation-z10"
|
class="mat-elevation-z10"
|
||||||
[dataSource]="dataSource"
|
[dataSource]="dataSource"
|
||||||
|
@ -1,4 +1,10 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core';
|
import {
|
||||||
|
AfterViewInit,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
|
} from '@angular/core';
|
||||||
import { MatTableDataSource } from '@angular/material/table';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { MatPaginator } from '@angular/material/paginator';
|
import { MatPaginator } from '@angular/material/paginator';
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatSort } from '@angular/material/sort';
|
||||||
@ -16,7 +22,7 @@ import { AccountDetails } from '@app/_models';
|
|||||||
styleUrls: ['./accounts.component.scss'],
|
styleUrls: ['./accounts.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class AccountsComponent implements OnInit {
|
export class AccountsComponent implements OnInit, AfterViewInit {
|
||||||
dataSource: MatTableDataSource<any>;
|
dataSource: MatTableDataSource<any>;
|
||||||
accounts: Array<AccountDetails> = [];
|
accounts: Array<AccountDetails> = [];
|
||||||
displayedColumns: Array<string> = ['name', 'phone', 'created', 'balance', 'location'];
|
displayedColumns: Array<string> = ['name', 'phone', 'created', 'balance', 'location'];
|
||||||
@ -25,32 +31,34 @@ export class AccountsComponent implements OnInit {
|
|||||||
accountsType: string = 'all';
|
accountsType: string = 'all';
|
||||||
accountTypes: Array<string>;
|
accountTypes: Array<string>;
|
||||||
tokenSymbol: string;
|
tokenSymbol: string;
|
||||||
|
loading: boolean = true;
|
||||||
|
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private userService: UserService,
|
|
||||||
private loggingService: LoggingService,
|
private loggingService: LoggingService,
|
||||||
|
private userService: UserService,
|
||||||
private router: Router,
|
private router: Router,
|
||||||
private tokenService: TokenService
|
private tokenService: TokenService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
await this.userService.init();
|
this.userService.accountsSubject.subscribe((accounts) => {
|
||||||
await this.tokenService.init();
|
this.dataSource = new MatTableDataSource<any>(accounts);
|
||||||
|
this.dataSource.paginator = this.paginator;
|
||||||
|
this.dataSource.sort = this.sort;
|
||||||
|
this.accounts = accounts;
|
||||||
|
if (accounts.length > 0) {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
// TODO it feels like this should be in the onInit handler
|
// TODO it feels like this should be in the onInit handler
|
||||||
await this.userService.loadAccounts(100);
|
await this.userService.loadAccounts(100);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.loggingService.sendErrorLevelMessage('Failed to load accounts', this, { error });
|
this.loggingService.sendErrorLevelMessage('Failed to load accounts', this, { error });
|
||||||
}
|
}
|
||||||
this.userService.accountsSubject.subscribe((accounts) => {
|
|
||||||
this.dataSource = new MatTableDataSource<any>(accounts);
|
|
||||||
this.dataSource.paginator = this.paginator;
|
|
||||||
this.dataSource.sort = this.sort;
|
|
||||||
this.accounts = accounts;
|
|
||||||
});
|
|
||||||
this.userService
|
this.userService
|
||||||
.getAccountTypes()
|
.getAccountTypes()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
@ -62,6 +70,13 @@ export class AccountsComponent implements OnInit {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
if (this.dataSource) {
|
||||||
|
this.dataSource.paginator = this.paginator;
|
||||||
|
this.dataSource.sort = this.sort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
doFilter(value: string): void {
|
doFilter(value: string): void {
|
||||||
this.dataSource.filter = value.trim().toLocaleLowerCase();
|
this.dataSource.filter = value.trim().toLocaleLowerCase();
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
|||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
import { AccountSearchComponent } from './account-search/account-search.component';
|
import { AccountSearchComponent } from './account-search/account-search.component';
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -51,6 +52,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|||||||
MatProgressSpinnerModule,
|
MatProgressSpinnerModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
|
MatProgressBarModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AccountsModule {}
|
export class AccountsModule {}
|
||||||
|
@ -25,8 +25,7 @@ export class CreateAccountComponent implements OnInit {
|
|||||||
private userService: UserService
|
private userService: UserService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
ngOnInit(): void {
|
||||||
await this.userService.init();
|
|
||||||
this.createForm = this.formBuilder.group({
|
this.createForm = this.formBuilder.group({
|
||||||
accountType: ['', Validators.required],
|
accountType: ['', Validators.required],
|
||||||
idNumber: ['', Validators.required],
|
idNumber: ['', Validators.required],
|
||||||
|
@ -43,6 +43,11 @@
|
|||||||
<mat-icon matSuffix>search</mat-icon>
|
<mat-icon matSuffix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div *ngIf="loading">
|
||||||
|
<h2 class="text-center"><strong>Loading Actions!</strong></h2>
|
||||||
|
<mat-progress-bar [mode]="'query'"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mat-table class="mat-elevation-z10" [dataSource]="dataSource" multiTemplateDataRows>
|
<mat-table class="mat-elevation-z10" [dataSource]="dataSource" multiTemplateDataRows>
|
||||||
<!-- Expand Column -->
|
<!-- Expand Column -->
|
||||||
<ng-container matColumnDef="expand">
|
<ng-container matColumnDef="expand">
|
||||||
|
@ -6,7 +6,7 @@ import { LoggingService, UserService } from '@app/_services';
|
|||||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||||
import { first } from 'rxjs/operators';
|
import { first } from 'rxjs/operators';
|
||||||
import { exportCsv } from '@app/_helpers';
|
import { exportCsv } from '@app/_helpers';
|
||||||
import { Action } from '../../_models';
|
import { Action } from '@app/_models';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-admin',
|
selector: 'app-admin',
|
||||||
@ -26,20 +26,23 @@ export class AdminComponent implements OnInit {
|
|||||||
displayedColumns: Array<string> = ['expand', 'user', 'role', 'action', 'status', 'approve'];
|
displayedColumns: Array<string> = ['expand', 'user', 'role', 'action', 'status', 'approve'];
|
||||||
action: Action;
|
action: Action;
|
||||||
actions: Array<Action>;
|
actions: Array<Action>;
|
||||||
|
loading: boolean = true;
|
||||||
|
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
|
|
||||||
constructor(private userService: UserService, private loggingService: LoggingService) {}
|
constructor(private userService: UserService, private loggingService: LoggingService) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
ngOnInit(): void {
|
||||||
await this.userService.init();
|
|
||||||
this.userService.getActions();
|
this.userService.getActions();
|
||||||
this.userService.actionsSubject.subscribe((actions) => {
|
this.userService.actionsSubject.subscribe((actions) => {
|
||||||
this.dataSource = new MatTableDataSource<any>(actions);
|
this.dataSource = new MatTableDataSource<any>(actions);
|
||||||
this.dataSource.paginator = this.paginator;
|
this.dataSource.paginator = this.paginator;
|
||||||
this.dataSource.sort = this.sort;
|
this.dataSource.sort = this.sort;
|
||||||
this.actions = actions;
|
this.actions = actions;
|
||||||
|
if (actions.length > 0) {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import { MatSortModule } from '@angular/material/sort';
|
|||||||
import { MatPaginatorModule } from '@angular/material/paginator';
|
import { MatPaginatorModule } from '@angular/material/paginator';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatRippleModule } from '@angular/material/core';
|
import { MatRippleModule } from '@angular/material/core';
|
||||||
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [AdminComponent],
|
declarations: [AdminComponent],
|
||||||
@ -29,6 +30,7 @@ import { MatRippleModule } from '@angular/material/core';
|
|||||||
MatPaginatorModule,
|
MatPaginatorModule,
|
||||||
MatButtonModule,
|
MatButtonModule,
|
||||||
MatRippleModule,
|
MatRippleModule,
|
||||||
|
MatProgressBarModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AdminModule {}
|
export class AdminModule {}
|
||||||
|
@ -22,10 +22,10 @@ const routes: Routes = [
|
|||||||
path: 'tokens',
|
path: 'tokens',
|
||||||
loadChildren: () => import('@pages/tokens/tokens.module').then((m) => m.TokensModule),
|
loadChildren: () => import('@pages/tokens/tokens.module').then((m) => m.TokensModule),
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
path: 'admin',
|
// path: 'admin',
|
||||||
loadChildren: () => import('@pages/admin/admin.module').then((m) => m.AdminModule),
|
// loadChildren: () => import('@pages/admin/admin.module').then((m) => m.AdminModule),
|
||||||
},
|
// },
|
||||||
{ path: '**', redirectTo: 'home', pathMatch: 'full' },
|
{ path: '**', redirectTo: 'home', pathMatch: 'full' },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -40,6 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-12 mb-2">
|
<div class="col-12 mb-2">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<mat-card-title class="card-header">
|
<mat-card-title class="card-header">
|
||||||
@ -67,6 +68,12 @@
|
|||||||
/>
|
/>
|
||||||
<mat-icon matSuffix>search</mat-icon>
|
<mat-icon matSuffix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div *ngIf="loading">
|
||||||
|
<h2 class="text-center"><strong>Loading Trusted Users!</strong></h2>
|
||||||
|
<mat-progress-bar [mode]="'query'"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mat-table
|
<mat-table
|
||||||
class="mat-elevation-z10"
|
class="mat-elevation-z10"
|
||||||
[dataSource]="dataSource"
|
[dataSource]="dataSource"
|
||||||
|
@ -13,24 +13,26 @@ import { exportCsv } from '@app/_helpers';
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class SettingsComponent implements OnInit {
|
export class SettingsComponent implements OnInit {
|
||||||
date: string;
|
|
||||||
dataSource: MatTableDataSource<any>;
|
dataSource: MatTableDataSource<any>;
|
||||||
displayedColumns: Array<string> = ['name', 'email', 'userId'];
|
displayedColumns: Array<string> = ['name', 'email', 'userId'];
|
||||||
trustedUsers: Array<Staff>;
|
trustedUsers: Array<Staff>;
|
||||||
userInfo: Staff;
|
userInfo: Staff;
|
||||||
|
loading: boolean = true;
|
||||||
|
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
|
|
||||||
constructor(private authService: AuthService) {}
|
constructor(private authService: AuthService) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
ngOnInit(): void {
|
||||||
await this.authService.init();
|
|
||||||
this.authService.trustedUsersSubject.subscribe((users) => {
|
this.authService.trustedUsersSubject.subscribe((users) => {
|
||||||
this.dataSource = new MatTableDataSource<any>(users);
|
this.dataSource = new MatTableDataSource<any>(users);
|
||||||
this.dataSource.paginator = this.paginator;
|
this.dataSource.paginator = this.paginator;
|
||||||
this.dataSource.sort = this.sort;
|
this.dataSource.sort = this.sort;
|
||||||
this.trustedUsers = users;
|
this.trustedUsers = users;
|
||||||
|
if (users.length > 0) {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
this.userInfo = this.authService.getPrivateKeyInfo();
|
this.userInfo = this.authService.getPrivateKeyInfo();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ import { MatCheckboxModule } from '@angular/material/checkbox';
|
|||||||
import { MatSelectModule } from '@angular/material/select';
|
import { MatSelectModule } from '@angular/material/select';
|
||||||
import { MatMenuModule } from '@angular/material/menu';
|
import { MatMenuModule } from '@angular/material/menu';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [SettingsComponent, OrganizationComponent],
|
declarations: [SettingsComponent, OrganizationComponent],
|
||||||
@ -38,6 +39,7 @@ import { ReactiveFormsModule } from '@angular/forms';
|
|||||||
MatSelectModule,
|
MatSelectModule,
|
||||||
MatMenuModule,
|
MatMenuModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
MatProgressBarModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class SettingsModule {}
|
export class SettingsModule {}
|
||||||
|
@ -45,6 +45,11 @@
|
|||||||
<mat-icon matSuffix>search</mat-icon>
|
<mat-icon matSuffix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div *ngIf="loading">
|
||||||
|
<h2 class="text-center"><strong>Loading Tokens!</strong></h2>
|
||||||
|
<mat-progress-bar [mode]="'query'"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<mat-table
|
<mat-table
|
||||||
class="mat-elevation-z10 table-responsive"
|
class="mat-elevation-z10 table-responsive"
|
||||||
[dataSource]="dataSource"
|
[dataSource]="dataSource"
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
import { ChangeDetectionStrategy, Component, OnInit, ViewChild } from '@angular/core';
|
import {
|
||||||
|
AfterViewInit,
|
||||||
|
ChangeDetectionStrategy,
|
||||||
|
Component,
|
||||||
|
OnInit,
|
||||||
|
ViewChild,
|
||||||
|
} from '@angular/core';
|
||||||
import { MatPaginator } from '@angular/material/paginator';
|
import { MatPaginator } from '@angular/material/paginator';
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatSort } from '@angular/material/sort';
|
||||||
import { LoggingService, TokenService } from '@app/_services';
|
import { TokenService } from '@app/_services';
|
||||||
import { MatTableDataSource } from '@angular/material/table';
|
import { MatTableDataSource } from '@angular/material/table';
|
||||||
import { Router } from '@angular/router';
|
|
||||||
import { exportCsv } from '@app/_helpers';
|
import { exportCsv } from '@app/_helpers';
|
||||||
import { Token } from '@app/_models';
|
import { Token } from '@app/_models';
|
||||||
|
|
||||||
@ -13,36 +18,41 @@ import { Token } from '@app/_models';
|
|||||||
styleUrls: ['./tokens.component.scss'],
|
styleUrls: ['./tokens.component.scss'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class TokensComponent implements OnInit {
|
export class TokensComponent implements OnInit, AfterViewInit {
|
||||||
dataSource: MatTableDataSource<any>;
|
dataSource: MatTableDataSource<any>;
|
||||||
columnsToDisplay: Array<string> = ['name', 'symbol', 'address', 'supply'];
|
columnsToDisplay: Array<string> = ['name', 'symbol', 'address', 'supply'];
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
tokens: Array<Token>;
|
tokens: Array<Token>;
|
||||||
token: Token;
|
token: Token;
|
||||||
|
loading: boolean = true;
|
||||||
|
|
||||||
constructor(
|
constructor(private tokenService: TokenService) {}
|
||||||
private tokenService: TokenService,
|
|
||||||
private loggingService: LoggingService,
|
|
||||||
private router: Router
|
|
||||||
) {}
|
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
ngOnInit(): void {
|
||||||
await this.tokenService.init();
|
|
||||||
this.tokenService.load.subscribe(async (status: boolean) => {
|
this.tokenService.load.subscribe(async (status: boolean) => {
|
||||||
if (status) {
|
if (status) {
|
||||||
await this.tokenService.getTokens();
|
await this.tokenService.getTokens();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.tokenService.tokensSubject.subscribe((tokens) => {
|
this.tokenService.tokensSubject.subscribe((tokens) => {
|
||||||
this.loggingService.sendInfoLevelMessage(tokens);
|
|
||||||
this.dataSource = new MatTableDataSource(tokens);
|
this.dataSource = new MatTableDataSource(tokens);
|
||||||
this.dataSource.paginator = this.paginator;
|
this.dataSource.paginator = this.paginator;
|
||||||
this.dataSource.sort = this.sort;
|
this.dataSource.sort = this.sort;
|
||||||
this.tokens = tokens;
|
this.tokens = tokens;
|
||||||
|
if (tokens.length > 0) {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
if (this.dataSource) {
|
||||||
|
this.dataSource.paginator = this.paginator;
|
||||||
|
this.dataSource.sort = this.sort;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
doFilter(value: string): void {
|
doFilter(value: string): void {
|
||||||
this.dataSource.filter = value.trim().toLocaleLowerCase();
|
this.dataSource.filter = value.trim().toLocaleLowerCase();
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ import { MatSidenavModule } from '@angular/material/sidenav';
|
|||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import { MatToolbarModule } from '@angular/material/toolbar';
|
import { MatToolbarModule } from '@angular/material/toolbar';
|
||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [TokensComponent, TokenDetailsComponent],
|
declarations: [TokensComponent, TokenDetailsComponent],
|
||||||
@ -37,6 +38,7 @@ import { MatCardModule } from '@angular/material/card';
|
|||||||
MatToolbarModule,
|
MatToolbarModule,
|
||||||
MatCardModule,
|
MatCardModule,
|
||||||
MatRippleModule,
|
MatRippleModule,
|
||||||
|
MatProgressBarModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class TokensModule {}
|
export class TokensModule {}
|
||||||
|
@ -36,9 +36,7 @@ export class TransactionDetailsComponent implements OnInit {
|
|||||||
private tokenService: TokenService
|
private tokenService: TokenService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
ngOnInit(): void {
|
||||||
await this.transactionService.init();
|
|
||||||
await this.tokenService.init();
|
|
||||||
if (this.transaction?.type === 'conversion') {
|
if (this.transaction?.type === 'conversion') {
|
||||||
this.traderBloxbergLink =
|
this.traderBloxbergLink =
|
||||||
'https://blockexplorer.bloxberg.org/address/' + this.transaction?.trader + '/transactions';
|
'https://blockexplorer.bloxberg.org/address/' + this.transaction?.trader + '/transactions';
|
||||||
|
@ -63,6 +63,11 @@
|
|||||||
<mat-icon matSuffix>search</mat-icon>
|
<mat-icon matSuffix>search</mat-icon>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
<div *ngIf="loading">
|
||||||
|
<h2 class="text-center"><strong>Loading Transactions!</strong></h2>
|
||||||
|
<mat-progress-bar [mode]="'query'"></mat-progress-bar>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table
|
<table
|
||||||
mat-table
|
mat-table
|
||||||
class="mat-elevation-z10"
|
class="mat-elevation-z10"
|
||||||
|
@ -29,6 +29,7 @@ export class TransactionsComponent implements OnInit, AfterViewInit {
|
|||||||
transactionsType: string = 'all';
|
transactionsType: string = 'all';
|
||||||
transactionsTypes: Array<string>;
|
transactionsTypes: Array<string>;
|
||||||
tokenSymbol: string;
|
tokenSymbol: string;
|
||||||
|
loading: boolean = true;
|
||||||
|
|
||||||
@ViewChild(MatPaginator) paginator: MatPaginator;
|
@ViewChild(MatPaginator) paginator: MatPaginator;
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
@ -41,17 +42,16 @@ export class TransactionsComponent implements OnInit, AfterViewInit {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async ngOnInit(): Promise<void> {
|
async ngOnInit(): Promise<void> {
|
||||||
|
await this.blockSyncService.blockSync();
|
||||||
this.transactionService.transactionsSubject.subscribe((transactions) => {
|
this.transactionService.transactionsSubject.subscribe((transactions) => {
|
||||||
this.transactionDataSource = new MatTableDataSource<any>(transactions);
|
this.transactionDataSource = new MatTableDataSource<any>(transactions);
|
||||||
this.transactionDataSource.paginator = this.paginator;
|
this.transactionDataSource.paginator = this.paginator;
|
||||||
this.transactionDataSource.sort = this.sort;
|
this.transactionDataSource.sort = this.sort;
|
||||||
this.transactions = transactions;
|
this.transactions = transactions;
|
||||||
|
if (transactions.length > 0) {
|
||||||
|
this.loading = false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
await this.blockSyncService.init();
|
|
||||||
await this.tokenService.init();
|
|
||||||
await this.transactionService.init();
|
|
||||||
await this.userService.init();
|
|
||||||
await this.blockSyncService.blockSync();
|
|
||||||
this.userService
|
this.userService
|
||||||
.getTransactionTypes()
|
.getTransactionTypes()
|
||||||
.pipe(first())
|
.pipe(first())
|
||||||
@ -85,8 +85,10 @@ export class TransactionsComponent implements OnInit, AfterViewInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
this.transactionDataSource.paginator = this.paginator;
|
if (this.transactionDataSource) {
|
||||||
this.transactionDataSource.sort = this.sort;
|
this.transactionDataSource.paginator = this.paginator;
|
||||||
|
this.transactionDataSource.sort = this.sort;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
downloadCsv(): void {
|
downloadCsv(): void {
|
||||||
|
@ -17,6 +17,7 @@ import { MatSelectModule } from '@angular/material/select';
|
|||||||
import { MatCardModule } from '@angular/material/card';
|
import { MatCardModule } from '@angular/material/card';
|
||||||
import { MatRippleModule } from '@angular/material/core';
|
import { MatRippleModule } from '@angular/material/core';
|
||||||
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
import { MatSnackBarModule } from '@angular/material/snack-bar';
|
||||||
|
import { MatProgressBarModule } from '@angular/material/progress-bar';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [TransactionsComponent, TransactionDetailsComponent],
|
declarations: [TransactionsComponent, TransactionDetailsComponent],
|
||||||
@ -37,6 +38,7 @@ import { MatSnackBarModule } from '@angular/material/snack-bar';
|
|||||||
MatCardModule,
|
MatCardModule,
|
||||||
MatRippleModule,
|
MatRippleModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
|
MatProgressBarModule,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class TransactionsModule {}
|
export class TransactionsModule {}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<nav class="navbar navbar-dark background-dark">
|
<nav class="navbar navbar-dark background-dark">
|
||||||
<h1 class="navbar-brand">
|
<h1 class="navbar-brand">
|
||||||
<div *ngIf="noInternetConnection; then offlineBlock; else onlineBlock"></div>
|
<div *ngIf="online; then onlineBlock; else offlineBlock"></div>
|
||||||
<ng-template #offlineBlock>
|
<ng-template #offlineBlock>
|
||||||
<strong style="color: red">OFFLINE </strong>
|
<strong style="color: red">OFFLINE </strong>
|
||||||
<img width="20rem" src="assets/images/no-wifi.svg" alt="Internet Disconnected" />
|
<img width="20rem" src="assets/images/no-wifi.svg" alt="Internet Disconnected" />
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@angular/core';
|
||||||
|
import { checkOnlineStatus } from '@src/app/_helpers';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-network-status',
|
selector: 'app-network-status',
|
||||||
@ -7,21 +8,30 @@ import { Component, OnInit, ChangeDetectionStrategy, ChangeDetectorRef } from '@
|
|||||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||||
})
|
})
|
||||||
export class NetworkStatusComponent implements OnInit {
|
export class NetworkStatusComponent implements OnInit {
|
||||||
noInternetConnection: boolean = !navigator.onLine;
|
online: boolean = navigator.onLine;
|
||||||
|
|
||||||
constructor(private cdr: ChangeDetectorRef) {
|
constructor(private cdr: ChangeDetectorRef) {
|
||||||
this.handleNetworkChange();
|
this.handleNetworkChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {}
|
ngOnInit(): void {
|
||||||
|
window.addEventListener('online', (event: any) => {
|
||||||
|
this.online = true;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
});
|
||||||
|
window.addEventListener('offline', (event: any) => {
|
||||||
|
this.online = false;
|
||||||
|
this.cdr.detectChanges();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
handleNetworkChange(): void {
|
handleNetworkChange(): void {
|
||||||
setTimeout(() => {
|
setTimeout(async () => {
|
||||||
if (!navigator.onLine !== this.noInternetConnection) {
|
if (this.online !== (await checkOnlineStatus())) {
|
||||||
this.noInternetConnection = !navigator.onLine;
|
this.online = await checkOnlineStatus();
|
||||||
this.cdr.detectChanges();
|
this.cdr.detectChanges();
|
||||||
}
|
}
|
||||||
this.handleNetworkChange();
|
this.handleNetworkChange();
|
||||||
}, 5000);
|
}, 3000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user