diff --git a/src/ServicePulse.Host/ServicePulse.Host.csproj b/src/ServicePulse.Host/ServicePulse.Host.csproj index 3b9fe88988..3b61a69655 100644 --- a/src/ServicePulse.Host/ServicePulse.Host.csproj +++ b/src/ServicePulse.Host/ServicePulse.Host.csproj @@ -105,6 +105,8 @@ + + diff --git a/src/ServicePulse.Host/app/css/particular.css b/src/ServicePulse.Host/app/css/particular.css index 36fef08841..797a69d62e 100644 --- a/src/ServicePulse.Host/app/css/particular.css +++ b/src/ServicePulse.Host/app/css/particular.css @@ -95,24 +95,13 @@ body { color: #181919; overflow-y: scroll; padding-top: 100px; + padding-bottom: 100px; } pre { white-space: pre-wrap; } -footer { - color: #bcc6c2; - font-size: 14px; - font-weight: normal; - height: 60px; - margin-top: 100px; - padding: 5px 0; - text-align: left; - text-align: center; - width: 100%; -} - footer span { color: #777f7f; display: inline-block !important; @@ -872,6 +861,10 @@ p.endpoint-metadata { font-size: 24px; } +.events { + margin-top: 30px; +} + .events .box { padding-bottom: 0; } @@ -899,6 +892,7 @@ p.endpoint-metadata { .version-info-container { width: 100% !important; + margin-top: -4px; } .version-info { @@ -2155,7 +2149,7 @@ i.fa-exclamation-triangle { background-repeat: no-repeat; } -.pa-monitoring-lost.endpoint-details { +.pa-monitoring-lost.endpoint-details, .pa-connection-failed { background-image: url('../../../img/monitoring-lost.svg'); background-position: center; background-repeat: no-repeat; @@ -2234,6 +2228,69 @@ i.fa.pa-endpoint-lost.endpoints-overview, i.fa.pa-monitoring-lost.endpoints-over padding: 10px 6px; } +footer { + color: #bcc6c2; + font-size: 14px; + font-weight: normal; + height: 35px; + margin-top: 100px; + padding: 5px 0; + text-align: left; + text-align: center; + width: 100%; + background-color: #fff; + position: fixed; + bottom: 0; + border: 1px solid #ddd; + box-shadow: 0px -10px 16px #f2f6f7; + padding-top: 7px; +} + +footer .row { + display: flex; + justify-content: space-between; +} + +footer span { + padding-left: 0; + padding-right: 32px; +} + + footer span[ng-if="isSCConnected"], footer span[ng-if="isSCMonitoringConnected"] { + color: #000; + } + + footer span[class="ng-isolate-scope"], footer span[ng-if="isSCMonitoringConnected"] { + padding-right: 0; + } + +.connectivity-status div, .connectivity-status span { + display: inline-block; + color: #777f7f; +} + +.connectivity-status i, .connectivity-status div.pa-connection-success { + width: 10px; + height: 10px; +} + +.pa-connection-establishing { + background-image: url('../img/loader_spinner.gif'); + background-position: center; + background-repeat: no-repeat; + background-size: cover; +} + + +.connectivity-status .connection-failed { + color: #CE4844; +} + +.connectivity-status .pa-connection-success { + border-radius: 50%; + background: #00C468; +} + @media (min-width: 0px) { .container { width: 92%; diff --git a/src/ServicePulse.Host/app/js/app.controller.js b/src/ServicePulse.Host/app/js/app.controller.js index c5ebe09956..3d9c77664e 100644 --- a/src/ServicePulse.Host/app/js/app.controller.js +++ b/src/ServicePulse.Host/app/js/app.controller.js @@ -28,6 +28,7 @@ $scope.SCVersion = ''; $scope.is_compatible_with_sc = true; $scope.Version = version; + $scope.isSCConnecting = true; $scope.isActive = function(viewLocation) { var active = $location.path().startsWith(viewLocation); @@ -118,10 +119,12 @@ switch(data) { case 'SignalR started': - toastService.showInfo('Connected to ServiceControl'); + $scope.isSCConnected = true; + $scope.isSCConnecting = false; break; case 'Reconnected': - toastService.showInfo('Reconnected to ServiceControl'); + $scope.isSCConnected = true; + $scope.isSCConnecting = false; break; default: toastService.showWarning(data); @@ -132,7 +135,11 @@ notifier.subscribe($scope, function(event, data) { logit(event, data); - toastService.showError(data); + if ($scope.isSCConnected) { + toastService.showError(data); + } + $scope.isSCConnected = false; + $scope.isSCConnecting = false; }, 'SignalRError'); notifier.subscribe($scope, function(event, data) { diff --git a/src/ServicePulse.Host/app/js/directives/ui.particular.js b/src/ServicePulse.Host/app/js/directives/ui.particular.js index 305a1d21b4..c488870572 100644 --- a/src/ServicePulse.Host/app/js/directives/ui.particular.js +++ b/src/ServicePulse.Host/app/js/directives/ui.particular.js @@ -22,6 +22,7 @@ 'ui.particular.graphdecimal', 'ui.particular.multicheckboxList', 'ui.particular.reindexingstatus', + 'ui.particular.monitoringConnectivityStatus' ]); } (window, window.angular)); \ No newline at end of file diff --git a/src/ServicePulse.Host/app/js/directives/ui.particular.productVersion.tpl.html b/src/ServicePulse.Host/app/js/directives/ui.particular.productVersion.tpl.html index cd0b61b85d..e716794205 100644 --- a/src/ServicePulse.Host/app/js/directives/ui.particular.productVersion.tpl.html +++ b/src/ServicePulse.Host/app/js/directives/ui.particular.productVersion.tpl.html @@ -16,12 +16,6 @@ -
- - • - -
-
diff --git a/src/ServicePulse.Host/app/js/views/dashboard/dashboard.html b/src/ServicePulse.Host/app/js/views/dashboard/dashboard.html index c9ff243f8e..e170b4f18c 100644 --- a/src/ServicePulse.Host/app/js/views/dashboard/dashboard.html +++ b/src/ServicePulse.Host/app/js/views/dashboard/dashboard.html @@ -51,14 +51,6 @@

-
-
- - - -
-
- diff --git a/src/ServicePulse.Host/app/layout/footer.html b/src/ServicePulse.Host/app/layout/footer.html index 81b663efd7..e35047d6ec 100644 --- a/src/ServicePulse.Host/app/layout/footer.html +++ b/src/ServicePulse.Host/app/layout/footer.html @@ -1,29 +1,29 @@  diff --git a/src/ServicePulse.Host/app/modules/monitoring/js/directives/ui.particular.monitoringConnectivityStatus.js b/src/ServicePulse.Host/app/modules/monitoring/js/directives/ui.particular.monitoringConnectivityStatus.js new file mode 100644 index 0000000000..3346142cf6 --- /dev/null +++ b/src/ServicePulse.Host/app/modules/monitoring/js/directives/ui.particular.monitoringConnectivityStatus.js @@ -0,0 +1,56 @@ + +; (function (window, angular, $, undefined) { + 'use strict'; + + + function controller($scope, connectivityNotifier, monitoringService, $interval) { + $scope.isSCMonitoringConnecting = true; + connectivityNotifier.getConnectionStatusSource().subscribe(value => { + $scope.isSCMonitoringConnected = value; + $scope.isSCMonitoringConnecting = false; + }); + + var scMonitoringConnectionPing = $interval(function () { + var promises = monitoringService.getMonitoredEndpoints().map((request, index) => { + request.then(r => { + connectivityNotifier.reportSuccessfulConnection(index); + }, e => { + connectivityNotifier.reportFailedConnection(index); + }); + }); + }, 10000); + + // Cancel interval on page changes + $scope.$on('$destroy', function () { + if (angular.isDefined(scMonitoringConnectionPing)) { + $interval.cancel(scMonitoringConnectionPing); + scMonitoringConnectionPing = undefined; + } + }); + } + + + + + + controller.$inject = ['$scope', 'connectivityNotifier', 'monitoringService', '$interval']; + + function directive() { + return { + scope: {}, + restrict: 'E', + replace: true, + templateUrl: 'modules/monitoring/js/directives/ui.particular.monitoringConnectivityStatus.tpl.html', + controller: controller, + link: function (scope, element) { } + }; + } + + directive.$inject = []; + + angular + .module('ui.particular.monitoringConnectivityStatus', []) + .directive('monitoringConnectivityStatus', directive); + +}(window, window.angular, window.jQuery)); + diff --git a/src/ServicePulse.Host/app/modules/monitoring/js/directives/ui.particular.monitoringConnectivityStatus.tpl.html b/src/ServicePulse.Host/app/modules/monitoring/js/directives/ui.particular.monitoringConnectivityStatus.tpl.html new file mode 100644 index 0000000000..1a880faee7 --- /dev/null +++ b/src/ServicePulse.Host/app/modules/monitoring/js/directives/ui.particular.monitoringConnectivityStatus.tpl.html @@ -0,0 +1,12 @@ + + SC Monitoring: + +
Connected +
+ + Not connected + + + Connecting + +
\ No newline at end of file diff --git a/src/ServicePulse.Host/app/modules/monitoring/js/endpoint_details.module.js b/src/ServicePulse.Host/app/modules/monitoring/js/endpoint_details.module.js index 5fe8dd02fb..fbdf651623 100644 --- a/src/ServicePulse.Host/app/modules/monitoring/js/endpoint_details.module.js +++ b/src/ServicePulse.Host/app/modules/monitoring/js/endpoint_details.module.js @@ -9,6 +9,7 @@ require('./endpoint_details.route.js'); require('./constant.diagrams.js'); + require('./directives/ui.particular.monitoringConnectivityStatus.js'); require('./directives/ui.particular.graph.js'); require('./directives/ui.particular.graphdecimal.js'); require('./directives/ui.particular.duration.js'); diff --git a/src/ServicePulse.Host/app/modules/monitoring/js/monitored_endpoints.module.js b/src/ServicePulse.Host/app/modules/monitoring/js/monitored_endpoints.module.js index 7d9158e47d..8265c484e7 100644 --- a/src/ServicePulse.Host/app/modules/monitoring/js/monitored_endpoints.module.js +++ b/src/ServicePulse.Host/app/modules/monitoring/js/monitored_endpoints.module.js @@ -8,6 +8,7 @@ require('./monitored_endpoints.route.js'); require('./constant.diagrams.js'); + require('./directives/ui.particular.monitoringConnectivityStatus.js'); require('./directives/ui.particular.graph.js'); require('./directives/ui.particular.graphdecimal.js'); require('./directives/ui.particular.graphduration.js'); diff --git a/src/ServicePulse.Host/app/modules/monitoring/js/services/services.connectivityNotifier.js b/src/ServicePulse.Host/app/modules/monitoring/js/services/services.connectivityNotifier.js index 25355fb7a8..6d35c1a256 100644 --- a/src/ServicePulse.Host/app/modules/monitoring/js/services/services.connectivityNotifier.js +++ b/src/ServicePulse.Host/app/modules/monitoring/js/services/services.connectivityNotifier.js @@ -5,7 +5,9 @@ function Service(toastService, scConfig) { var isConnectedToSourceIndex = Array(scConfig.monitoring_urls.length).fill(true); - + var connectivitySource = new Rx.Subject(); + var shouldShowFailedMessage = true; + function reportFailedConnection(sourceIndex) { if (isConnectedToSourceIndex[sourceIndex]) { @@ -13,9 +15,14 @@ if (scConfig.monitoring_urls.length > 1) { message = 'Could not connect to the ServiceControl Monitoring service at' + scConfig.monitoring_urls[sourceIndex] + '.'; } - toastService.showError(message); + console.log(message); + if (shouldShowFailedMessage) { + toastService.showError(message); + shouldShowFailedMessage = false; + } } isConnectedToSourceIndex[sourceIndex] = false; + emitChange(isConnectedToSourceIndex); } function reportSuccessfulConnection(sourceIndex) { @@ -24,15 +31,28 @@ if (scConfig.monitoring_urls.length > 1) { message = 'Connection to ServiceControl Monitoring service was successful ' + scConfig.monitoring_urls[sourceIndex] +'.'; } - toastService.showInfo(message, 'Info', true); + console.log(message); + shouldShowFailedMessage = true; } isConnectedToSourceIndex[sourceIndex] = true; + emitChange(isConnectedToSourceIndex); + } + + function emitChange(connectedToSourceIndex) { + var result = connectedToSourceIndex.every(item => item); + connectivitySource.onNext(result); + }; + + function getConnectionStatusSource() { + return connectivitySource; } var service = { reportFailedConnection: reportFailedConnection, - reportSuccessfulConnection: reportSuccessfulConnection + reportSuccessfulConnection: reportSuccessfulConnection, + getConnectionStatusSource: getConnectionStatusSource, }; + return service; } diff --git a/src/ServicePulse.Host/app/modules/monitoring/js/services/services.monitoring.js b/src/ServicePulse.Host/app/modules/monitoring/js/services/services.monitoring.js index 866213a3c2..fcd597245c 100644 --- a/src/ServicePulse.Host/app/modules/monitoring/js/services/services.monitoring.js +++ b/src/ServicePulse.Host/app/modules/monitoring/js/services/services.monitoring.js @@ -62,9 +62,16 @@ }); } + function getMonitoredEndpoints() { + return scConfig.monitoring_urls.map(function (url) { + return $http.get(uri.join(url, 'monitored-endpoints') + '?history=1'); + }); + } + var service = { createEndpointsSource: createEndpointsSource, - createEndpointDetailsSource: createEndpointDetailsSource + createEndpointDetailsSource: createEndpointDetailsSource, + getMonitoredEndpoints: getMonitoredEndpoints, }; return service;