diff --git a/static/skywire-manager-src/src/app/app.component.html b/static/skywire-manager-src/src/app/app.component.html index 7c8353e9aa..af0e10c7ea 100644 --- a/static/skywire-manager-src/src/app/app.component.html +++ b/static/skywire-manager-src/src/app/app.component.html @@ -10,3 +10,9 @@ + +
+ + error_outline {{ 'common.data-update-problems' | translate }} + +
diff --git a/static/skywire-manager-src/src/app/app.component.scss b/static/skywire-manager-src/src/app/app.component.scss index d46021feb8..1d5b80fa6d 100644 --- a/static/skywire-manager-src/src/app/app.component.scss +++ b/static/skywire-manager-src/src/app/app.component.scss @@ -41,3 +41,18 @@ left: 0; position: fixed; } + +.connection-problem-container { + position: fixed; + bottom: 0; + right: 0; + background-color: red; + padding: 0px 10px 5px; + font-size: 10px; + opacity: 0.75; + + mat-icon { + position: relative; + top: 4px; + } +} diff --git a/static/skywire-manager-src/src/app/app.component.ts b/static/skywire-manager-src/src/app/app.component.ts index 4749b68337..50d070ad7e 100644 --- a/static/skywire-manager-src/src/app/app.component.ts +++ b/static/skywire-manager-src/src/app/app.component.ts @@ -32,6 +32,8 @@ export class AppComponent { pkErrorShown = false; pkErrorsFound = 0; + showingDataProblemMsg = false; + obtainPkSubscription: Subscription; constructor( @@ -108,6 +110,20 @@ export class AppComponent { } } + /** + * Shows a box at the bottom-right corner indicating that there is a problem getting the data. + */ + showDataProblemMsg() { + this.showingDataProblemMsg = true; + } + + /** + * Hides the box at the bottom-right corner indicating that there is a problem getting the data. + */ + hideDataProblemMsg() { + this.showingDataProblemMsg = false; + } + /** * Gets the pk of the hypervisor. After that, it initializes services and allows the app to start working. */ diff --git a/static/skywire-manager-src/src/app/components/layout/top-bar/top-bar.component.scss b/static/skywire-manager-src/src/app/components/layout/top-bar/top-bar.component.scss index ce3e8c6d56..2862192061 100644 --- a/static/skywire-manager-src/src/app/components/layout/top-bar/top-bar.component.scss +++ b/static/skywire-manager-src/src/app/components/layout/top-bar/top-bar.component.scss @@ -281,6 +281,11 @@ $top-bar-height: 56px; flex-direction: row-reverse; font-size: $font-size-mini-plus; + mat-icon { + position: relative; + top: 3px; + } + .connection-error-msg-vpn { margin: -5px 5px 5px 10px; color: $yellow-clear; diff --git a/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts b/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts index b6aac69c24..f53cce715e 100644 --- a/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node-list/node-list.component.ts @@ -24,6 +24,7 @@ import { NodeData, UpdateAllComponent } from '../../layout/update-all/update-all import { BulkRewardAddressChangerComponent, BulkRewardAddressParams, NodeToEditData } from '../../layout/bulk-reward-address-changer/bulk-reward-address-changer.component'; import { MultipleNodeDataService, MultipleNodesBackendData } from 'src/app/services/multiple-node-data.service'; import { PageBaseComponent } from 'src/app/utils/page-base'; +import { AppComponent } from 'src/app/app.component'; /** * Page for showing the node list. @@ -409,6 +410,7 @@ export class NodeListComponent extends PageBaseComponent implements OnInit, OnDe this.lastUpdate = result.momentOfLastCorrectUpdate; this.secondsSinceLastUpdate = Math.floor((Date.now() - result.momentOfLastCorrectUpdate) / 1000); this.errorsUpdating = false; + AppComponent.currentInstance.hideDataProblemMsg(); if (this.lastUpdateRequestedManually) { // Show a confirmation msg. @@ -429,6 +431,7 @@ export class NodeListComponent extends PageBaseComponent implements OnInit, OnDe // Stop the loading indicator and show a warning icon. this.errorsUpdating = true; + AppComponent.currentInstance.showDataProblemMsg(); } } diff --git a/static/skywire-manager-src/src/app/components/pages/node/node.component.ts b/static/skywire-manager-src/src/app/components/pages/node/node.component.ts index 89544706a0..064513514b 100644 --- a/static/skywire-manager-src/src/app/components/pages/node/node.component.ts +++ b/static/skywire-manager-src/src/app/components/pages/node/node.component.ts @@ -12,6 +12,7 @@ import { SnackbarService } from '../../../services/snackbar.service'; import { NodeActionsHelper } from './actions/node-actions-helper'; import { SingleNodeBackendData, SingleNodeDataService, TrafficData } from 'src/app/services/single-node-data.service'; import { PageBaseComponent } from 'src/app/utils/page-base'; +import { AppComponent } from 'src/app/app.component'; /** * Main page used for showing the details of a node. It is in charge of loading @@ -320,6 +321,7 @@ export class NodeComponent extends PageBaseComponent implements OnInit, OnDestro this.lastUpdate = result.momentOfLastCorrectUpdate; this.secondsSinceLastUpdate = Math.floor((Date.now() - result.momentOfLastCorrectUpdate) / 1000); this.errorsUpdating = false; + AppComponent.currentInstance.hideDataProblemMsg(); if (this.lastUpdateRequestedManually) { // Show a confirmation msg. @@ -347,6 +349,7 @@ export class NodeComponent extends PageBaseComponent implements OnInit, OnDestro // Stop the loading indicator and show a warning icon. this.errorsUpdating = true; + AppComponent.currentInstance.showDataProblemMsg(); } } diff --git a/static/skywire-manager-src/src/app/services/vpn-client.service.ts b/static/skywire-manager-src/src/app/services/vpn-client.service.ts index 14338ddb35..d3c2050787 100644 --- a/static/skywire-manager-src/src/app/services/vpn-client.service.ts +++ b/static/skywire-manager-src/src/app/services/vpn-client.service.ts @@ -15,6 +15,7 @@ import { environment } from 'src/environments/environment'; import { SnackbarService } from './snackbar.service'; import { processServiceError } from '../utils/errors'; import { OperationError } from '../utils/operation-error'; +import { AppComponent } from '../app.component'; /** * States in which the VPN client app of the local visor can be. @@ -576,6 +577,7 @@ export class VpnClientService { mergeMap(() => this.getVpnClientState()), retryWhen(err => err.pipe(mergeMap((error: OperationError) => { this.errorSubject.next(true); + AppComponent.currentInstance.showDataProblemMsg(); error = processServiceError(error); // If the problem was because the user is not authorized, don't retry. @@ -599,6 +601,7 @@ export class VpnClientService { ).subscribe(appData => { if (appData) { this.errorSubject.next(false); + AppComponent.currentInstance.hideDataProblemMsg(); // Remove the busy state of the initial check. if (this.lastServiceState === VpnServiceStates.PerformingInitialCheck) { diff --git a/static/skywire-manager-src/src/assets/i18n/en.json b/static/skywire-manager-src/src/assets/i18n/en.json index 79aa6c8329..0ddebb2701 100644 --- a/static/skywire-manager-src/src/assets/i18n/en.json +++ b/static/skywire-manager-src/src/assets/i18n/en.json @@ -20,7 +20,8 @@ "no": "No", "unknown": "Unknown", "close": "Close", - "window-size-error": "The window is too narrow for the content." + "window-size-error": "The window is too narrow for the content.", + "data-update-problems": "Problem updating the data." }, "labeled-element": { diff --git a/static/skywire-manager-src/src/assets/i18n/es.json b/static/skywire-manager-src/src/assets/i18n/es.json index 27dd44541f..4fd0f77a05 100644 --- a/static/skywire-manager-src/src/assets/i18n/es.json +++ b/static/skywire-manager-src/src/assets/i18n/es.json @@ -20,7 +20,8 @@ "no": "No", "unknown": "Desconocido", "close": "Cerrar", - "window-size-error": "La ventana es demasiado estrecha para el contenido." + "window-size-error": "La ventana es demasiado estrecha para el contenido.", + "data-update-problems": "Problema actualizando los datos." }, "labeled-element": { diff --git a/static/skywire-manager-src/src/assets/i18n/es_base.json b/static/skywire-manager-src/src/assets/i18n/es_base.json index 8c853eda94..47ab2b5cb4 100644 --- a/static/skywire-manager-src/src/assets/i18n/es_base.json +++ b/static/skywire-manager-src/src/assets/i18n/es_base.json @@ -20,7 +20,8 @@ "no": "No", "unknown": "Unknown", "close": "Close", - "window-size-error": "The window is too narrow for the content." + "window-size-error": "The window is too narrow for the content.", + "data-update-problems": "Problem updating the data." }, "labeled-element": { diff --git a/static/skywire-manager-src/src/assets/scss/_responsive_tables.scss b/static/skywire-manager-src/src/assets/scss/_responsive_tables.scss index 16a527d3b2..24fd7cb490 100644 --- a/static/skywire-manager-src/src/assets/scss/_responsive_tables.scss +++ b/static/skywire-manager-src/src/assets/scss/_responsive_tables.scss @@ -306,7 +306,5 @@ $responsive-table-colors: ( // Allows to remove the margin at the right of the last mat-icon element inside // generic-title-container, to make it be shown correctly when there is a paginator. .paginator-icons-fixer { - mat-icon:last-of-type { - margin-right: 0 !important; - } + margin-right: 0 !important; }