From 0f2918efaf4c95dec6aba79339b88caf03a0376c Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Thu, 14 Mar 2019 13:49:37 -0700 Subject: [PATCH] Fix telemetry metadata issues (#2308) * Do not try to convert undefined to a string * Fixed metadata sorting. Iteratees that return arrays are treated as object paths. * Added test specs for telemetry API reordering change * Added telemetry filters to the API * Support multiple inspector views * Renamed InspectorView.vue to InspectorViews.vue * VISTA compatibility issues (#2291) * Build config changes necessary to work with VISTA * Fixes to TelemetryTableRow to address bug in VISTA * Fixed sass-fast-loader version to avoid https://github.com/yibn2008/fast-sass-loader/issues/47 * Reverted default theme --- .../generator/GeneratorMetadataProvider.js | 9 +- src/api/telemetry/TelemetryAPISpec.js | 236 ++++++++++++++++++ src/api/telemetry/TelemetryMetadataManager.js | 8 +- .../telemetryTable/TelemetryTableColumn.js | 2 +- 4 files changed, 242 insertions(+), 13 deletions(-) diff --git a/example/generator/GeneratorMetadataProvider.js b/example/generator/GeneratorMetadataProvider.js index fecf996ffe..1668d72d4c 100644 --- a/example/generator/GeneratorMetadataProvider.js +++ b/example/generator/GeneratorMetadataProvider.js @@ -33,19 +33,12 @@ define([ formatString: '%0.2f', hints: { range: 1 - }, - filters: [ - { - comparator: 'equals', - possibleValues: [1,2,3,4] - } - ] + } }, { key: "cos", name: "Cosine", formatString: '%0.2f', - filters: ['equals'], hints: { range: 2 } diff --git a/src/api/telemetry/TelemetryAPISpec.js b/src/api/telemetry/TelemetryAPISpec.js index fe28c5d58f..7b123253a3 100644 --- a/src/api/telemetry/TelemetryAPISpec.js +++ b/src/api/telemetry/TelemetryAPISpec.js @@ -28,14 +28,22 @@ define([ describe('Telemetry API', function () { var openmct; var telemetryAPI; + var mockTypeService; beforeEach(function () { openmct = { time: jasmine.createSpyObj('timeAPI', [ 'timeSystem', 'bounds' + ]), + $injector: jasmine.createSpyObj('injector', [ + 'get' ]) }; + mockTypeService = jasmine.createSpyObj('typeService', [ + 'getType' + ]); + openmct.$injector.get.and.returnValue(mockTypeService); openmct.time.timeSystem.and.returnValue({key: 'system'}); openmct.time.bounds.and.returnValue({start: 0, end: 1}); telemetryAPI = new TelemetryAPI(openmct); @@ -296,5 +304,233 @@ define([ ); }); }); + describe('metadata', function () { + let mockMetadata = {}; + let mockObjectType = { + typeDef: {} + }; + beforeEach(function () { + telemetryAPI.addProvider({ + key: 'mockMetadataProvider', + supportsMetadata() { + return true; + }, + getMetadata() { + return mockMetadata; + } + }); + mockTypeService.getType.and.returnValue(mockObjectType); + }) + it('respects explicit priority', function () { + mockMetadata.values = [ + { + key: "name", + name: "Name", + hints: { + priority: 2 + } + + }, + { + key: "timestamp", + name: "Timestamp", + hints: { + priority: 1 + } + }, + { + key: "sin", + name: "Sine", + hints: { + priority: 4 + } + }, + { + key: "cos", + name: "Cosine", + hints: { + priority: 3 + } + } + ]; + let metadata = telemetryAPI.getMetadata({}); + let values = metadata.values(); + + values.forEach((value, index) => { + expect(value.hints.priority).toBe(index + 1); + }); + }); + it('if no explicit priority, defaults to order defined', function () { + mockMetadata.values = [ + { + key: "name", + name: "Name" + + }, + { + key: "timestamp", + name: "Timestamp" + }, + { + key: "sin", + name: "Sine" + }, + { + key: "cos", + name: "Cosine" + } + ]; + let metadata = telemetryAPI.getMetadata({}); + let values = metadata.values(); + + values.forEach((value, index) => { + expect(value.key).toBe(mockMetadata.values[index].key); + }); + }); + it('respects domain priority', function () { + mockMetadata.values = [ + { + key: "name", + name: "Name" + + }, + { + key: "timestamp-utc", + name: "Timestamp UTC", + hints: { + domain: 2 + } + }, + { + key: "timestamp-local", + name: "Timestamp Local", + hints: { + domain: 1 + } + }, + { + key: "sin", + name: "Sine", + hints: { + range: 2 + } + }, + { + key: "cos", + name: "Cosine", + hints: { + range: 1 + } + } + ]; + let metadata = telemetryAPI.getMetadata({}); + let values = metadata.valuesForHints(['domain']); + + expect(values[0].key).toBe('timestamp-local'); + expect(values[1].key).toBe('timestamp-utc'); + }); + it('respects range priority', function () { + mockMetadata.values = [ + { + key: "name", + name: "Name" + + }, + { + key: "timestamp-utc", + name: "Timestamp UTC", + hints: { + domain: 2 + } + }, + { + key: "timestamp-local", + name: "Timestamp Local", + hints: { + domain: 1 + } + }, + { + key: "sin", + name: "Sine", + hints: { + range: 2 + } + }, + { + key: "cos", + name: "Cosine", + hints: { + range: 1 + } + } + ]; + let metadata = telemetryAPI.getMetadata({}); + let values = metadata.valuesForHints(['range']); + + expect(values[0].key).toBe('cos'); + expect(values[1].key).toBe('sin'); + }); + it('respects priority and domain ordering', function () { + mockMetadata.values = [ + { + key: "id", + name: "ID", + hints: { + priority: 2 + } + }, + { + key: "name", + name: "Name", + hints: { + priority: 1 + } + + }, + { + key: "timestamp-utc", + name: "Timestamp UTC", + hints: { + domain: 2, + priority: 1 + } + }, + { + key: "timestamp-local", + name: "Timestamp Local", + hints: { + domain: 1, + priority: 2 + } + }, + { + key: "timestamp-pst", + name: "Timestamp PST", + hints: { + domain: 3, + priority: 2 + } + }, + { + key: "sin", + name: "Sine" + }, + { + key: "cos", + name: "Cosine" + } + ]; + let metadata = telemetryAPI.getMetadata({}); + let values = metadata.valuesForHints(['priority', 'domain']); + [ + 'timestamp-utc', + 'timestamp-local', + 'timestamp-pst' + ].forEach((key, index) => { + expect(values[index].key).toBe(key); + }); + }); + }) }); }); diff --git a/src/api/telemetry/TelemetryMetadataManager.js b/src/api/telemetry/TelemetryMetadataManager.js index df3fbc6320..b3390c145d 100644 --- a/src/api/telemetry/TelemetryMetadataManager.js +++ b/src/api/telemetry/TelemetryMetadataManager.js @@ -116,12 +116,12 @@ define([ return hints.every(hasHint, metadata); } var matchingMetadata = this.valueMetadatas.filter(hasHints); - var sortedMetadata = _.sortBy(matchingMetadata, function (metadata) { - return hints.map(function (hint) { + let iteratees = hints.map(hint => { + return (metadata) => { return metadata.hints[hint]; - }); + } }); - return sortedMetadata; + return _.sortByAll(matchingMetadata, ...iteratees); }; TelemetryMetadataManager.prototype.getFilterableValues = function () { diff --git a/src/plugins/telemetryTable/TelemetryTableColumn.js b/src/plugins/telemetryTable/TelemetryTableColumn.js index efb50cb286..15185f159a 100644 --- a/src/plugins/telemetryTable/TelemetryTableColumn.js +++ b/src/plugins/telemetryTable/TelemetryTableColumn.js @@ -49,7 +49,7 @@ define(function () { getFormattedValue(telemetryDatum) { let formattedValue = this.formatter.format(telemetryDatum); - if (typeof formattedValue !== 'string') { + if (formattedValue !== undefined && typeof formattedValue !== 'string') { return formattedValue.toString(); } else { return formattedValue;