diff --git a/src/ServicePulse.Host.Tests/ServicePulse.Host.Tests.csproj b/src/ServicePulse.Host.Tests/ServicePulse.Host.Tests.csproj index c4fa66c0a2..e558aad206 100644 --- a/src/ServicePulse.Host.Tests/ServicePulse.Host.Tests.csproj +++ b/src/ServicePulse.Host.Tests/ServicePulse.Host.Tests.csproj @@ -83,6 +83,7 @@ + diff --git a/src/ServicePulse.Host.Tests/SpecsRunner.html b/src/ServicePulse.Host.Tests/SpecsRunner.html index b20e0ce8ae..4bb4b3236e 100644 --- a/src/ServicePulse.Host.Tests/SpecsRunner.html +++ b/src/ServicePulse.Host.Tests/SpecsRunner.html @@ -130,6 +130,7 @@ + diff --git a/src/ServicePulse.Host.Tests/tests/js/services/services.messageTypeParser.spec.js b/src/ServicePulse.Host.Tests/tests/js/services/services.messageTypeParser.spec.js new file mode 100644 index 0000000000..f829fc67b2 --- /dev/null +++ b/src/ServicePulse.Host.Tests/tests/js/services/services.messageTypeParser.spec.js @@ -0,0 +1,68 @@ +describe('messageTypeParser', function () { + beforeEach(module('services.messageTypeParser')); + + var oneTypeMessageType = { + "id": "IMyEvent, Shared, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", + "typeName": "IMyEvent", + "assemblyName": "Shared", + "assemblyVersion": "0.0.0.0", + "culture": "Neutral", + "publicKeyToken": "123123123" + }; + var twoTypeMessageType = { + "id": + "Some.Very.Long.Shared.Namespace.Is.Found.Here.EventMessage, Shared, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null;IMyEvent, Shared, Version=0.0.0.0, Culture=neutral, PublicKeyToken=123123123", + "typeName": + "Some.Very.Long.Shared.Namespace.Is.Found.Here.EventMessage, Shared, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null;IMyEvent, Shared, Version=0.0.0.0, Culture=neutral, PublicKeyToken=123123123", + "assemblyName": null, + "assemblyVersion": null, + "culture": null, + "publicKeyToken": null + }; + + + var messageTypeParser; + + beforeEach(inject(function (_messageTypeParser_) { + messageTypeParser = _messageTypeParser_; + })); + + it('should not parse message type if there is only one class in', function () { + var sut = {}; + Object.assign(sut, oneTypeMessageType); + messageTypeParser.parseTheMessageTypeData(sut); + + expect(sut.typeName).toEqual('IMyEvent'); + expect(sut.assemblyName).toEqual('Shared'); + }); + + it('should parse message type if there is more than one class in', function () { + var sut = {}; + Object.assign(sut, twoTypeMessageType); + messageTypeParser.parseTheMessageTypeData(sut); + + expect(sut.typeName).toEqual('Some.Very.Long.Shared.Namespace.Is.Found.Here.EventMessage, IMyEvent'); + expect(sut.assemblyName).toEqual(null); + expect(sut.messageTypeHierarchy[0].typeName).toEqual('Some.Very.Long.Shared.Namespace.Is.Found.Here.EventMessage'); + expect(sut.messageTypeHierarchy[1].typeName).toEqual('IMyEvent'); + expect(sut.messageTypeHierarchy[0].assemblyName).toEqual(' Shared'); + expect(sut.messageTypeHierarchy[1].assemblyName).toEqual(' Shared'); + }); + + it('should fill tooltip text with all parameters when present', function () { + var sut = {}; + Object.assign(sut, oneTypeMessageType); + messageTypeParser.parseTheMessageTypeData(sut); + + expect(sut.tooltipText).toEqual('IMyEvent | Shared-0.0.0.0 | Culture=Neutral | PublicKeyToken=123123123'); + }); + + it('should fill tooltip text with all parameters from both types when present', function () { + var sut = {}; + Object.assign(sut, twoTypeMessageType); + messageTypeParser.parseTheMessageTypeData(sut); + + expect(sut.tooltipText).toEqual('Some.Very.Long.Shared.Namespace.Is.Found.Here.EventMessage | Shared-0.0.0.0
IMyEvent | Shared-0.0.0.0 | Culture=neutral | PublicKeyToken=123123123'); + }); + +}); \ No newline at end of file diff --git a/src/ServicePulse.Host/ServicePulse.Host.csproj b/src/ServicePulse.Host/ServicePulse.Host.csproj index a37270ae83..3b9fe88988 100644 --- a/src/ServicePulse.Host/ServicePulse.Host.csproj +++ b/src/ServicePulse.Host/ServicePulse.Host.csproj @@ -84,6 +84,7 @@ + @@ -116,6 +117,7 @@ + diff --git a/src/ServicePulse.Host/app/css/particular.css b/src/ServicePulse.Host/app/css/particular.css index 4b8a580cf4..206e82ad2a 100644 --- a/src/ServicePulse.Host/app/css/particular.css +++ b/src/ServicePulse.Host/app/css/particular.css @@ -422,7 +422,26 @@ body { font-size: 14px !important; font-weight: bold; margin-bottom: 3px; - word-wrap: break-word; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.righ-side-ellipsis { + direction: rtl; + text-align: left; +} + +@supports (-ms-ime-align:auto) { + .righ-side-ellipsis { + direction: ltr; + } +} + +@media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { + .righ-side-ellipsis { + direction: ltr; + } } .break { @@ -1827,6 +1846,11 @@ p.col-sort-active { width: 200px; } +.endpoint-row .tooltip-inner { + width: auto; + max-width: 600px; +} + .endpoint-status { display: inline-block; position: absolute; @@ -2000,7 +2024,7 @@ h1 .endpoint-status i.fa-envelope, .endpoint-status i.fa-exclamation-triangle { color: #8C8C8C; font-weight: normal; font-size: 12px; - float: left; + display: inline-block; } i.fa-exclamation-triangle { @@ -2106,6 +2130,9 @@ i.fa-exclamation-triangle { .row.message-type-properties { position: relative; top: -5px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } i.fa.pa-endpoint-lost.endpoints-overview, i.fa.pa-monitoring-lost.endpoints-overview { @@ -2187,4 +2214,9 @@ div.alert.alert-warning strong { .alert.alert-warning { font-size: 16px; margin-bottom: 32px; -} \ No newline at end of file +} + +.lead.righ-side-ellipsis { + color: #00729C !important; +} + diff --git a/src/ServicePulse.Host/app/css/particular.ie.css b/src/ServicePulse.Host/app/css/particular.ie.css new file mode 100644 index 0000000000..00fc9cea43 --- /dev/null +++ b/src/ServicePulse.Host/app/css/particular.ie.css @@ -0,0 +1,4 @@ +/*Hack to keep the default ellipsis on monitoring details screen for message types.*/ +.righ-side-ellipsis { + direction: ltr; +} \ No newline at end of file diff --git a/src/ServicePulse.Host/app/index.html b/src/ServicePulse.Host/app/index.html index 218f7c2303..0144cac6b6 100644 --- a/src/ServicePulse.Host/app/index.html +++ b/src/ServicePulse.Host/app/index.html @@ -5,7 +5,9 @@ @@ -16,10 +18,10 @@ - + - + + diff --git a/src/ServicePulse.Host/app/js/services/services.module.js b/src/ServicePulse.Host/app/js/services/services.module.js index 3740b8e924..b8b8612e09 100644 --- a/src/ServicePulse.Host/app/js/services/services.module.js +++ b/src/ServicePulse.Host/app/js/services/services.module.js @@ -11,7 +11,8 @@ 'services.notifications', 'services.exceptionHandler', 'services.uri', - 'services.endpoints' + 'services.endpoints', + 'services.messageTypeParser' ]); diff --git a/src/ServicePulse.Host/app/modules/monitoring/js/endpoint_details.controller.js b/src/ServicePulse.Host/app/modules/monitoring/js/endpoint_details.controller.js index 9498969823..ef585e7678 100644 --- a/src/ServicePulse.Host/app/modules/monitoring/js/endpoint_details.controller.js +++ b/src/ServicePulse.Host/app/modules/monitoring/js/endpoint_details.controller.js @@ -12,7 +12,8 @@ $filter, smallGraphsMinimumYAxis, largeGraphsMinimumYAxis, - connectivityNotifier + connectivityNotifier, + messageTypeParser ) { $scope.endpointName = $routeParams.endpointName; @@ -78,7 +79,10 @@ }); $scope.loading = false; - $scope.endpoint.messageTypes.forEach((messageType) => fillDisplayValues(messageType)); + $scope.endpoint.messageTypes.forEach((messageType) => { + fillDisplayValues(messageType); + messageTypeParser.parseTheMessageTypeData(messageType); + }); $scope.endpoint.isStale = true; $scope.endpoint.isScMonitoringDisconnected = false; @@ -131,7 +135,8 @@ '$filter', 'smallGraphsMinimumYAxis', 'largeGraphsMinimumYAxis', - 'connectivityNotifier' + 'connectivityNotifier', + 'messageTypeParser' ]; angular.module('endpoint_details') 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 0e96e9d5c6..5fe8dd02fb 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 @@ -3,6 +3,7 @@ angular.module('endpoint_details', []); + require('./services/services.messageTypeParser'); require('./services/services.connectivityNotifier'); require('./endpoint_details.controller'); require('./endpoint_details.route.js'); diff --git a/src/ServicePulse.Host/app/modules/monitoring/js/services/services.messageTypeParser.js b/src/ServicePulse.Host/app/modules/monitoring/js/services/services.messageTypeParser.js new file mode 100644 index 0000000000..13c7aea1b8 --- /dev/null +++ b/src/ServicePulse.Host/app/modules/monitoring/js/services/services.messageTypeParser.js @@ -0,0 +1,58 @@ +; +(function (window, angular, $, undefined) { + 'use strict'; + + function Service() { + + function parseTheMessageTypeData(messageType) { + if (!messageType.typeName) + return; + + if (messageType.typeName.indexOf(';') > 0) { + var messageTypeHierarchy = messageType.typeName.split(';'); + messageTypeHierarchy = messageTypeHierarchy.map((item) => { + var obj = {}; + var segments = item.split(','); + obj.typeName = segments[0]; + obj.assemblyName = segments[1]; + obj.assemblyVersion = segments[2].substring(segments[2].indexOf('=') + 1); + + if (!segments[4].endsWith('=null')) { //SC monitoring fills culture only if PublicKeyToken is filled + obj.culture = segments[3]; + obj.publicKeyToken = segments[4]; + } + return obj; + }); + messageType.messageTypeHierarchy = messageTypeHierarchy; + messageType.typeName = + messageTypeHierarchy.reduce((sum, item) => (sum ? `${sum}, ` : '') + item.typeName, ''); + messageType.containsTypeHierarchy = true; + messageType.tooltipText = messageTypeHierarchy.reduce((sum, item) => (sum ? `${sum}
` : '') + + `${item.typeName} |${item.assemblyName}-${item.assemblyVersion}` + (item.culture ? ` |${item.culture}` : '') + (item.publicKeyToken ? ` |${item.publicKeyToken}` : ''), + ''); + } else { + var tooltip = `${messageType.typeName} | ${messageType.assemblyName}-${messageType.assemblyVersion}`; + if (messageType.culture && messageType.culture != 'null') { + tooltip += ` | Culture=${messageType.culture}`; + } + + if (messageType.publicKeyToken && messageType.publicKeyToken != 'null') { + tooltip += ` | PublicKeyToken=${messageType.publicKeyToken}`; + } + + messageType.tooltipText = tooltip; + } + } + + var service = { + parseTheMessageTypeData: parseTheMessageTypeData + }; + + return service; + } + + Service.$inject = []; + + angular.module('services.messageTypeParser', ['sc']) + .service('messageTypeParser', Service); +}(window, window.angular, window.jQuery)); diff --git a/src/ServicePulse.Host/app/modules/monitoring/views/endpoint_details.html b/src/ServicePulse.Host/app/modules/monitoring/views/endpoint_details.html index 43e4ab4ae5..f684044b14 100644 --- a/src/ServicePulse.Host/app/modules/monitoring/views/endpoint_details.html +++ b/src/ServicePulse.Host/app/modules/monitoring/views/endpoint_details.html @@ -8,8 +8,8 @@ All endpoints
-

- {{endpointName}} +

+
{{endpointName}}
@@ -221,7 +221,7 @@
-
+
Instance Name @@ -263,9 +263,9 @@
-
+
-
+
{{instance.name}}
@@ -346,7 +346,7 @@
-
+
Message type name @@ -388,10 +388,10 @@
-
+
-
-
+
+
{{messageType.typeName ? messageType.typeName : 'Unknown'}}
@@ -405,7 +405,12 @@
-
{{messageType.assemblyName + '-' + messageType.assemblyVersion}}
+
+ {{messageType.assemblyName + '-' + messageType.assemblyVersion}} +
+
+ {{type.assemblyName + '-' + type.assemblyVersion}} +
{{'Culture=' + messageType.culture}}
{{'PublicKeyToken=' + messageType.publicKeyToken}}
diff --git a/src/ServicePulse.Host/app/modules/monitoring/views/monitored_endpoints.html b/src/ServicePulse.Host/app/modules/monitoring/views/monitored_endpoints.html index a3f175bb67..df1d8e033d 100644 --- a/src/ServicePulse.Host/app/modules/monitoring/views/monitored_endpoints.html +++ b/src/ServicePulse.Host/app/modules/monitoring/views/monitored_endpoints.html @@ -68,7 +68,7 @@

Endpoints overview

-
+
diff --git a/src/ServicePulse.Host/package.json b/src/ServicePulse.Host/package.json index 08daba7132..596c7d1733 100644 --- a/src/ServicePulse.Host/package.json +++ b/src/ServicePulse.Host/package.json @@ -6,8 +6,8 @@ "dependencies": { "angular": "^1.6.9", "angular-animate": "^1.6.9", - "angular-pretty-xml": "^0.1.1", "angular-cookies": "^1.6.9", + "angular-pretty-xml": "^0.1.1", "angular-route": "^1.6.9", "angular-sanitize": "^1.6.9", "angular-ui-bootstrap": "0.14.3", @@ -21,7 +21,7 @@ "ng-infinite-scroll": "^1.3.0", "ng-page-title": "^1.1.1", "ngstorage": "git://github.com/gsklee/ngStorage#0.3.10", - "npm": "^5.0.3", + "npm": "^6.1.0", "rx": "^4.1.0", "signalr": "^2.2.1", "ui-select": "^0.18.1",