Compare commits
	
		
			1 Commits
		
	
	
		
			telemetry-
			...
			slideshow
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | d75058d5bd | 
| @@ -17,7 +17,7 @@ | ||||
|     "screenfull": "^3.0.0", | ||||
|     "node-uuid": "^1.4.7", | ||||
|     "comma-separated-values": "^3.6.4", | ||||
|     "file-saver": "^1.3.3", | ||||
|     "FileSaver.js": "^0.0.2", | ||||
|     "zepto": "^1.1.6", | ||||
|     "eventemitter3": "^1.2.0", | ||||
|     "lodash": "3.10.1", | ||||
|   | ||||
| @@ -4,6 +4,12 @@ deployment: | ||||
|     commands: | ||||
|         - npm install canvas nomnoml | ||||
|         - ./build-docs.sh | ||||
|         - git fetch --unshallow | ||||
|         - git push git@heroku.com:openmctweb-demo.git $CIRCLE_SHA1:refs/heads/master | ||||
|   openmct-demo: | ||||
|     branch: live_demo | ||||
|     heroku: | ||||
|       appname: openmct-demo | ||||
|   openmctweb-staging-deux: | ||||
|     branch: mobile | ||||
|     heroku: | ||||
|   | ||||
| @@ -127,8 +127,7 @@ | ||||
| { 'meaning': 'Timer object', 'cssClass': 'icon-timer', 'cssContent': 'e1127', 'htmlEntity': '&#xe1127' }, | ||||
| { 'meaning': 'Data Topic', 'cssClass': 'icon-topic', 'cssContent': 'e1128', 'htmlEntity': '&#xe1128' }, | ||||
| { 'meaning': 'Fixed Position object', 'cssClass': 'icon-box-with-dashed-lines', 'cssContent': 'e1129', 'htmlEntity': '&#xe1129' }, | ||||
| { 'meaning': 'Summary Widget', 'cssClass': 'icon-summary-widget', 'cssContent': 'e1130', 'htmlEntity': '&#xe1130' }, | ||||
| { 'meaning': 'Notebook object', 'cssClass': 'icon-notebook', 'cssContent': 'e1131', 'htmlEntity': '&#xe1131' } | ||||
| { 'meaning': 'Summary Widget', 'cssClass': 'icon-summary-widget', 'cssContent': 'e1130', 'htmlEntity': '&#xe1130' } | ||||
| ]; | ||||
| "></div> | ||||
|  | ||||
|   | ||||
| @@ -33,7 +33,7 @@ requirejs.config({ | ||||
|         "moment": "bower_components/moment/moment", | ||||
|         "moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format", | ||||
|         "moment-timezone": "bower_components/moment-timezone/builds/moment-timezone-with-data", | ||||
|         "saveAs": "bower_components/file-saver/FileSaver.min", | ||||
|         "saveAs": "bower_components/FileSaver.js/FileSaver.min", | ||||
|         "screenfull": "bower_components/screenfull/dist/screenfull.min", | ||||
|         "text": "bower_components/text/text", | ||||
|         "uuid": "bower_components/node-uuid/uuid", | ||||
|   | ||||
| @@ -22,7 +22,7 @@ | ||||
| <span class='type-icon flex-elem {{type.getCssClass()}}'></span> | ||||
| <span class="l-elem-wrapper l-flex-row flex-elem grows" ng-controller="ObjectHeaderController as controller"> | ||||
|     <span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span> | ||||
|     <span ng-attr-contenteditable="{{ controller.editable ? true : undefined }}" | ||||
|     <span contenteditable="true"  | ||||
| 		class='title-label flex-elem holder flex-can-shrink s-input-inline' | ||||
| 		ng-click="controller.edit()" | ||||
| 		ng-blur="controller.updateName($event)" | ||||
|   | ||||
| @@ -32,8 +32,7 @@ define( | ||||
|          */ | ||||
|         function ObjectHeaderController($scope) { | ||||
|             this.$scope = $scope; | ||||
|             this.domainObject = $scope.domainObject; | ||||
|             this.editable = this.allowEdit(); | ||||
|             $scope.editing = false; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
| @@ -42,49 +41,33 @@ define( | ||||
|          * @param event the mouse event | ||||
|          */ | ||||
|         ObjectHeaderController.prototype.updateName = function (event) { | ||||
|             if (!event || !event.currentTarget) { | ||||
|                 return; | ||||
|             } | ||||
|             if (event && (event.type === 'blur' || event.which === 13)) { | ||||
|                 var name = event.currentTarget.innerHTML; | ||||
|  | ||||
|             if (event.type === 'blur') { | ||||
|                 this.updateModel(event); | ||||
|             } else if (event.which === 13) { | ||||
|                 this.updateModel(event); | ||||
|                 event.currentTarget.blur(); | ||||
|                 window.getSelection().removeAllRanges(); | ||||
|                 if (name.length === 0) { | ||||
|                     name = "Unnamed " + this.$scope.domainObject.getCapability("type").typeDef.name; | ||||
|                     event.currentTarget.innerHTML = name; | ||||
|                 } | ||||
|  | ||||
|                 if (name !== this.$scope.domainObject.model.name) { | ||||
|                     this.$scope.domainObject.getCapability('mutation').mutate(function (model) { | ||||
|                         model.name = name; | ||||
|                     }); | ||||
|                 } | ||||
|  | ||||
|                 this.$scope.editing = false; | ||||
|  | ||||
|                 if (event.which === 13) { | ||||
|                     event.currentTarget.blur(); | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Updates the model. | ||||
|          * | ||||
|          * @param event the mouse event | ||||
|          * @param private | ||||
|          * Marks the status of the field as editing. | ||||
|          */ | ||||
|         ObjectHeaderController.prototype.updateModel = function (event) { | ||||
|             var name = event.currentTarget.textContent.replace(/\n/g, ' '); | ||||
|  | ||||
|             if (name.length === 0) { | ||||
|                 name = "Unnamed " + this.domainObject.getCapability("type").typeDef.name; | ||||
|                 event.currentTarget.textContent = name; | ||||
|             } | ||||
|  | ||||
|             if (name !== this.domainObject.getModel().name) { | ||||
|                 this.domainObject.getCapability('mutation').mutate(function (model) { | ||||
|                     model.name = name; | ||||
|                 }); | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Checks if the domain object is editable. | ||||
|          * | ||||
|          * @private | ||||
|          * @return true if object is editable | ||||
|          */ | ||||
|         ObjectHeaderController.prototype.allowEdit = function () { | ||||
|             var type = this.domainObject && this.domainObject.getCapability('type'); | ||||
|             return !!(type && type.hasFeature('creation')); | ||||
|         ObjectHeaderController.prototype.edit = function () { | ||||
|             this.$scope.editing = true; | ||||
|         }; | ||||
|  | ||||
|         return ObjectHeaderController; | ||||
|   | ||||
| @@ -32,27 +32,22 @@ define( | ||||
|                 mockTypeCapability, | ||||
|                 mockEvent, | ||||
|                 mockCurrentTarget, | ||||
|                 model, | ||||
|                 controller; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockMutationCapability = jasmine.createSpyObj("mutation", ["mutate"]); | ||||
|                 mockTypeCapability = jasmine.createSpyObj("type", ["typeDef", "hasFeature"]); | ||||
|                 mockTypeCapability.typeDef = { name: ""}; | ||||
|                 mockTypeCapability.hasFeature.andCallFake(function (feature) { | ||||
|                     return feature === 'creation'; | ||||
|                 }); | ||||
|  | ||||
|                 mockTypeCapability = { | ||||
|                     typeDef: { | ||||
|                         name: "" | ||||
|                     } | ||||
|                 }; | ||||
|                 mockCapabilities = { | ||||
|                     mutation: mockMutationCapability, | ||||
|                     type: mockTypeCapability | ||||
|                 }; | ||||
|  | ||||
|                 model = { | ||||
|                     name: "Test name" | ||||
|                 }; | ||||
|                 mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "getModel"]); | ||||
|                 mockDomainObject.getModel.andReturn(model); | ||||
|                 mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "model"]); | ||||
|                 mockDomainObject.model = {name: "Test name"}; | ||||
|                 mockDomainObject.getCapability.andCallFake(function (key) { | ||||
|                     return mockCapabilities[key]; | ||||
|                 }); | ||||
| @@ -61,7 +56,7 @@ define( | ||||
|                     domainObject: mockDomainObject | ||||
|                 }; | ||||
|  | ||||
|                 mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "textContent"]); | ||||
|                 mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "innerHTML"]); | ||||
|                 mockCurrentTarget.blur.andReturn(mockCurrentTarget); | ||||
|  | ||||
|                 mockEvent = { | ||||
| @@ -75,7 +70,7 @@ define( | ||||
|  | ||||
|             it("updates the model with new name on blur", function () { | ||||
|                 mockEvent.type = "blur"; | ||||
|                 mockCurrentTarget.textContent = "New name"; | ||||
|                 mockCurrentTarget.innerHTML = "New name"; | ||||
|                 controller.updateName(mockEvent); | ||||
|  | ||||
|                 expect(mockMutationCapability.mutate).toHaveBeenCalled(); | ||||
| @@ -83,23 +78,23 @@ define( | ||||
|  | ||||
|             it("updates the model with a default for blank names", function () { | ||||
|                 mockEvent.type = "blur"; | ||||
|                 mockCurrentTarget.textContent = ""; | ||||
|                 mockCurrentTarget.innerHTML = ""; | ||||
|                 controller.updateName(mockEvent); | ||||
|  | ||||
|                 expect(mockCurrentTarget.textContent.length).not.toEqual(0); | ||||
|                 expect(mockCurrentTarget.innerHTML.length).not.toEqual(0); | ||||
|                 expect(mockMutationCapability.mutate).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("does not update the model if the same name", function () { | ||||
|                 mockEvent.type = "blur"; | ||||
|                 mockCurrentTarget.textContent = mockDomainObject.getModel().name; | ||||
|                 mockCurrentTarget.innerHTML = mockDomainObject.model.name; | ||||
|                 controller.updateName(mockEvent); | ||||
|  | ||||
|                 expect(mockMutationCapability.mutate).not.toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("updates the model on enter keypress event only", function () { | ||||
|                 mockCurrentTarget.textContent = "New name"; | ||||
|                 mockCurrentTarget.innerHTML = "New name"; | ||||
|                 controller.updateName(mockEvent); | ||||
|  | ||||
|                 expect(mockMutationCapability.mutate).not.toHaveBeenCalled(); | ||||
| @@ -109,29 +104,17 @@ define( | ||||
|  | ||||
|                 expect(mockMutationCapability.mutate).toHaveBeenCalledWith(jasmine.any(Function)); | ||||
|  | ||||
|                 mockMutationCapability.mutate.mostRecentCall.args[0](model); | ||||
|                 mockMutationCapability.mutate.mostRecentCall.args[0](mockDomainObject.model); | ||||
|  | ||||
|                 expect(mockDomainObject.getModel().name).toBe("New name"); | ||||
|                 expect(mockDomainObject.model.name).toBe("New name"); | ||||
|             }); | ||||
|  | ||||
|             it("blurs the field on enter key press", function () { | ||||
|                 mockCurrentTarget.textContent = "New name"; | ||||
|                 mockEvent.which = 13; | ||||
|                 controller.updateName(mockEvent); | ||||
|  | ||||
|                 expect(mockEvent.currentTarget.blur).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("allows editting name when object is creatable", function () { | ||||
|                 expect(controller.allowEdit()).toBe(true); | ||||
|             }); | ||||
|  | ||||
|             it("disallows editting name when object is non-creatable", function () { | ||||
|                 mockTypeCapability.hasFeature.andReturn(false); | ||||
|  | ||||
|                 expect(controller.allowEdit()).toBe(false); | ||||
|  | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
|   | ||||
| @@ -101,15 +101,10 @@ define( | ||||
|          */ | ||||
|         EditorCapability.prototype.finish = function () { | ||||
|             var domainObject = this.domainObject; | ||||
|  | ||||
|             if (this.transactionService.isActive()) { | ||||
|                 return this.transactionService.cancel().then(function () { | ||||
|                     domainObject.getCapability("status").set("editing", false); | ||||
|                     return domainObject; | ||||
|                 }); | ||||
|             } else { | ||||
|                 return Promise.resolve(domainObject); | ||||
|             } | ||||
|             return this.transactionService.cancel().then(function () { | ||||
|                 domainObject.getCapability("status").set("editing", false); | ||||
|                 return domainObject; | ||||
|             }); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|   | ||||
| @@ -62,7 +62,6 @@ define( | ||||
|                 ); | ||||
|                 mockTransactionService.commit.andReturn(fastPromise()); | ||||
|                 mockTransactionService.cancel.andReturn(fastPromise()); | ||||
|                 mockTransactionService.isActive = jasmine.createSpy('isActive'); | ||||
|  | ||||
|                 mockStatusCapability = jasmine.createSpyObj( | ||||
|                     "statusCapability", | ||||
| @@ -142,7 +141,6 @@ define( | ||||
|  | ||||
|             describe("finish", function () { | ||||
|                 beforeEach(function () { | ||||
|                     mockTransactionService.isActive.andReturn(true); | ||||
|                     capability.edit(); | ||||
|                     capability.finish(); | ||||
|                 }); | ||||
| @@ -154,23 +152,6 @@ define( | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("finish", function () { | ||||
|                 beforeEach(function () { | ||||
|                     mockTransactionService.isActive.andReturn(false); | ||||
|                     capability.edit(); | ||||
|                 }); | ||||
|  | ||||
|                 it("does not cancel transaction when transaction is not active", function () { | ||||
|                     capability.finish(); | ||||
|                     expect(mockTransactionService.cancel).not.toHaveBeenCalled(); | ||||
|                 }); | ||||
|  | ||||
|                 it("returns a promise", function () { | ||||
|                     expect(capability.finish() instanceof Promise).toBe(true); | ||||
|                 }); | ||||
|  | ||||
|             }); | ||||
|  | ||||
|             describe("dirty", function () { | ||||
|                 var model = {}; | ||||
|  | ||||
|   | ||||
| @@ -121,9 +121,6 @@ define([ | ||||
|     }; | ||||
|  | ||||
|     UTCTimeFormat.prototype.parse = function (text) { | ||||
|         if (typeof text === 'number') { | ||||
|             return text; | ||||
|         } | ||||
|         return moment.utc(text, DATE_FORMATS).valueOf(); | ||||
|     }; | ||||
|  | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   "metadata": { | ||||
|     "name": "openmct-symbols-16px", | ||||
|     "lastOpened": 0, | ||||
|     "created": 1506973656040 | ||||
|     "created": 1505151140023 | ||||
|   }, | ||||
|   "iconSets": [ | ||||
|     { | ||||
| @@ -899,14 +899,6 @@ | ||||
|           "prevSize": 24, | ||||
|           "code": 921904, | ||||
|           "tempChar": "" | ||||
|         }, | ||||
|         { | ||||
|           "order": 139, | ||||
|           "id": 117, | ||||
|           "name": "icon-notebook", | ||||
|           "prevSize": 24, | ||||
|           "code": 921905, | ||||
|           "tempChar": "" | ||||
|         } | ||||
|       ], | ||||
|       "metadata": { | ||||
| @@ -3532,29 +3524,6 @@ | ||||
|               {} | ||||
|             ] | ||||
|           } | ||||
|         }, | ||||
|         { | ||||
|           "id": 117, | ||||
|           "paths": [ | ||||
|             "M896 110.8c0-79.8-55.4-127.4-123-105.4l-773 250.6h896v-145.2z", | ||||
|             "M896 320h-896v576c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128v-448c0-70.4-57.6-128-128-128zM832 832h-384v-320h384v320z" | ||||
|           ], | ||||
|           "attrs": [ | ||||
|             {}, | ||||
|             {} | ||||
|           ], | ||||
|           "isMulticolor": false, | ||||
|           "isMulticolor2": false, | ||||
|           "grid": 16, | ||||
|           "tags": [ | ||||
|             "icon-notebook" | ||||
|           ], | ||||
|           "colorPermutations": { | ||||
|             "1161751207457516161751": [ | ||||
|               {}, | ||||
|               {} | ||||
|             ] | ||||
|           } | ||||
|         } | ||||
|       ], | ||||
|       "colorThemes": [ | ||||
|   | ||||
										
											Binary file not shown.
										
									
								
							| @@ -118,5 +118,4 @@ | ||||
| <glyph unicode="󡄨" glyph-name="icon-topic" d="M454.36 483.36l86.3 86.3c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c19.328-19.358 42.832-34.541 69.047-44.082l1.313 171.722-57.64 57.64c-34.407 34.33-81.9 55.558-134.35 55.558s-99.943-21.228-134.354-55.562l-86.296-86.297c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-28.674 28.654v-172.14c19.045-7.022 41.040-11.084 63.984-11.084 52.463 0 99.966 21.239 134.379 55.587zM505.64 412.64l-86.3-86.3c-9.088-8.965-21.577-14.502-35.36-14.502s-26.272 5.537-35.366 14.507l-86.294 86.294c-2 2-4.2 4-6.36 6v-197.36c33.664-30.72 78.65-49.537 128.031-49.537 52.44 0 99.923 21.22 134.333 55.541l86.296 86.296c9.088 8.965 21.577 14.502 35.36 14.502s26.272-5.537 35.366-14.507l86.294-86.294c2-2 4.2-4 6.36-6v197.36c-33.664 30.72-78.65 49.537-128.031 49.537-52.44 0-99.923-21.22-134.333-55.541zM832 960h-128v-192h127.66l0.34-0.34v-639.32l-0.34-0.34h-127.66v-192h128c105.6 0 192 86.4 192 192v640c0 105.6-86.4 192-192 192zM320 128h-127.66l-0.34 0.34v639.32l0.34 0.34h127.66v192h-128c-105.6 0-192-86.4-192-192v-640c0-105.6 86.4-192 192-192h128v192z" /> | ||||
| <glyph unicode="󡄩" glyph-name="icon-box-with-dashed-lines" d="M0 576h128v-256h-128v256zM128 831.78l0.22 0.22h191.78v128h-192c-70.606-0.215-127.785-57.394-128-127.979v-192.021h128v191.78zM128 64.22v191.78h-128v-192c0.215-70.606 57.394-127.785 127.979-128h192.021v128h-191.78zM384 960h256v-128h-256v128zM896 64.22l-0.22-0.22h-191.78v-128h192c70.606 0.215 127.785 57.394 128 127.979v192.021h-128v-191.78zM896 960h-192v-128h191.78l0.22-0.22v-191.78h128v192c-0.215 70.606-57.394 127.785-127.979 128zM896 576h128v-256h-128v256zM384 64h256v-128h-256v128zM256 704h512v-512h-512v512z" /> | ||||
| <glyph unicode="󡄰" glyph-name="icon-summary-widget" d="M896 960h-768c-70.4 0-128-57.6-128-128v-768c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v768c0 70.4-57.6 128-128 128zM847.8 349.6l-82.6-143.2-189.6 131.6 19.2-230h-165.4l19.2 230-189.6-131.6-82.6 143.2 208.6 98.4-208.8 98.4 82.6 143.2 189.6-131.6-19.2 230h165.4l-19.2-230 189.6 131.6 82.6-143.2-208.6-98.4 208.8-98.4z" /> | ||||
| <glyph unicode="󡄱" glyph-name="icon-notebook" d="M896 849.2c0 79.8-55.4 127.4-123 105.4l-773-250.6h896v145.2zM896 640h-896v-576c0-70.4 57.6-128 128-128h768c70.4 0 128 57.6 128 128v448c0 70.4-57.6 128-128 128zM832 128h-384v320h384v-320z" /> | ||||
| </font></defs></svg> | ||||
| Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB | 
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							| @@ -146,7 +146,6 @@ $glyph-icon-timer: '\e1127'; | ||||
| $glyph-icon-topic: '\e1128'; | ||||
| $glyph-icon-box-with-dashed-lines: '\e1129'; | ||||
| $glyph-icon-summary-widget: '\e1130'; | ||||
| $glyph-icon-notebook: '\e1131'; | ||||
|  | ||||
| /************************** 16 PX CLASSES */ | ||||
|  | ||||
| @@ -261,7 +260,6 @@ $glyph-icon-notebook: '\e1131'; | ||||
| .icon-topic {  @include glyphBefore($glyph-icon-topic); } | ||||
| .icon-box-with-dashed-lines {  @include glyphBefore($glyph-icon-box-with-dashed-lines); } | ||||
| .icon-summary-widget {  @include glyphBefore($glyph-icon-summary-widget); } | ||||
| .icon-notebook {  @include glyphBefore($glyph-icon-notebook); } | ||||
|  | ||||
| /************************** 12 PX CLASSES */ | ||||
| .icon-crosshair-12px {  @include glyphBefore($glyph-icon-crosshair,'symbolsfont-12px'); } | ||||
|   | ||||
| @@ -26,6 +26,5 @@ | ||||
|         display: block; | ||||
|         height: 100%; | ||||
|         width: 100%; | ||||
|         border: none; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -50,6 +50,7 @@ | ||||
|         content:''; | ||||
|         font-family: symbolsfont; | ||||
|         font-size: 0.8em; | ||||
|         display: inline; | ||||
|         margin-right: $interiorMarginSm; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -120,11 +120,7 @@ | ||||
| 	} | ||||
|  | ||||
| 	.status-indicator { | ||||
|         background: none !important; | ||||
| 		margin-right: $interiorMarginSm; | ||||
|         &[class*='s-status']:before { | ||||
|             font-size: 1em; | ||||
|         } | ||||
| 	} | ||||
|  | ||||
| 	.count { | ||||
|   | ||||
| @@ -108,11 +108,8 @@ define( | ||||
|  | ||||
|                 getMetadata(); | ||||
|             }); | ||||
|  | ||||
|             var mutation = $scope.ngModel.selectedObject.getCapability('mutation'); | ||||
|             var unlisten = mutation.listen(getMetadata); | ||||
|             $scope.$on('$destroy', unlisten); | ||||
|         } | ||||
|  | ||||
|         return ObjectInspectorController; | ||||
|     } | ||||
| ); | ||||
|   | ||||
| @@ -39,18 +39,10 @@ define( | ||||
|             beforeEach(function () { | ||||
|                 mockScope = jasmine.createSpyObj( | ||||
|                     "$scope", | ||||
|                     ["$watch", "$on"] | ||||
|                     ["$watch"] | ||||
|                 ); | ||||
|                 mockScope.ngModel = {}; | ||||
|                 mockScope.ngModel.selectedObject = { | ||||
|                     getCapability: function () { | ||||
|                         return { | ||||
|                             listen: function () { | ||||
|                                 return true; | ||||
|                             } | ||||
|                         }; | ||||
|                     } | ||||
|                 }; | ||||
|                 mockScope.ngModel.selectedObject = 'mock selected object'; | ||||
|  | ||||
|                 mockObjectService = jasmine.createSpyObj( | ||||
|                     "objectService", | ||||
|   | ||||
| @@ -23,13 +23,10 @@ | ||||
| define([ | ||||
|     "moment-timezone", | ||||
|     "./src/indicators/ClockIndicator", | ||||
|     "./src/indicators/FollowIndicator", | ||||
|     "./src/services/TickerService", | ||||
|     "./src/services/TimerService", | ||||
|     "./src/controllers/ClockController", | ||||
|     "./src/controllers/TimerController", | ||||
|     "./src/controllers/RefreshingController", | ||||
|     "./src/actions/FollowTimerAction", | ||||
|     "./src/actions/StartTimerAction", | ||||
|     "./src/actions/RestartTimerAction", | ||||
|     "./src/actions/StopTimerAction", | ||||
| @@ -40,13 +37,10 @@ define([ | ||||
| ], function ( | ||||
|     MomentTimezone, | ||||
|     ClockIndicator, | ||||
|     FollowIndicator, | ||||
|     TickerService, | ||||
|     TimerService, | ||||
|     ClockController, | ||||
|     TimerController, | ||||
|     RefreshingController, | ||||
|     FollowTimerAction, | ||||
|     StartTimerAction, | ||||
|     RestartTimerAction, | ||||
|     StopTimerAction, | ||||
| @@ -86,11 +80,6 @@ define([ | ||||
|                         "CLOCK_INDICATOR_FORMAT" | ||||
|                     ], | ||||
|                     "priority": "preferred" | ||||
|                 }, | ||||
|                 { | ||||
|                     "implementation": FollowIndicator, | ||||
|                     "depends": ["timerService"], | ||||
|                     "priority": "fallback" | ||||
|                 } | ||||
|             ], | ||||
|             "services": [ | ||||
| @@ -101,11 +90,6 @@ define([ | ||||
|                         "$timeout", | ||||
|                         "now" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "timerService", | ||||
|                     "implementation": TimerService, | ||||
|                     "depends": ["openmct"] | ||||
|                 } | ||||
|             ], | ||||
|             "controllers": [ | ||||
| @@ -150,15 +134,6 @@ define([ | ||||
|                 } | ||||
|             ], | ||||
|             "actions": [ | ||||
|                 { | ||||
|                     "key": "timer.follow", | ||||
|                     "implementation": FollowTimerAction, | ||||
|                     "depends": ["timerService"], | ||||
|                     "category": "contextual", | ||||
|                     "name": "Follow Timer", | ||||
|                     "cssClass": "icon-clock", | ||||
|                     "priority": "optional" | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "timer.start", | ||||
|                     "implementation": StartTimerAction, | ||||
|   | ||||
| @@ -1,113 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define(['EventEmitter'], function (EventEmitter) { | ||||
|  | ||||
|     /** | ||||
|      * Tracks the currently-followed Timer object. Used by | ||||
|      * timelines et al to synchronize to a particular timer. | ||||
|      * | ||||
|      * The TimerService emits `change` events when the active timer | ||||
|      * is changed. | ||||
|      */ | ||||
|     function TimerService(openmct) { | ||||
|         EventEmitter.apply(this); | ||||
|         this.time = openmct.time; | ||||
|         this.objects = openmct.objects; | ||||
|     } | ||||
|  | ||||
|     TimerService.prototype = Object.create(EventEmitter.prototype); | ||||
|  | ||||
|     /** | ||||
|      * Set (or clear, if `timer` is undefined) the currently active timer. | ||||
|      * @param {DomainObject} timer the new active timer | ||||
|      * @emits change | ||||
|      */ | ||||
|     TimerService.prototype.setTimer = function (timer) { | ||||
|         this.timer = timer; | ||||
|         this.emit('change'); | ||||
|  | ||||
|         if (this.stopObserving) { | ||||
|             this.stopObserving(); | ||||
|             delete this.stopObserving; | ||||
|         } | ||||
|  | ||||
|         if (timer) { | ||||
|             this.stopObserving = | ||||
|                 this.objects.observe(timer, '*', this.setTimer.bind(this)); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Get the currently active timer. | ||||
|      * @return {DomainObject} the active timer | ||||
|      * @emits change | ||||
|      */ | ||||
|     TimerService.prototype.getTimer = function () { | ||||
|         return this.timer; | ||||
|     }; | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Check if there is a currently active timer. | ||||
|      * @return {boolean} true if there is a timer | ||||
|      */ | ||||
|     TimerService.prototype.hasTimer = function () { | ||||
|         return !!this.timer; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Convert the provided timestamp to milliseconds relative to | ||||
|      * the active timer. | ||||
|      * @return {number} milliseconds since timer start | ||||
|      */ | ||||
|     TimerService.prototype.convert = function (timestamp) { | ||||
|         var clock = this.time.clock(); | ||||
|         var canConvert = this.hasTimer() && | ||||
|             !!clock && | ||||
|             this.timer.timerState !== 'stopped'; | ||||
|  | ||||
|         if (!canConvert) { | ||||
|             return undefined; | ||||
|         } | ||||
|  | ||||
|         var now = clock.currentValue(); | ||||
|         var delta = this.timer.timerState === 'paused' ? | ||||
|             now - this.timer.pausedTime : 0; | ||||
|         var epoch = this.timer.timestamp; | ||||
|  | ||||
|         return timestamp - epoch - delta; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Get the value of the active clock, adjusted to be relative to the active | ||||
|      * timer. If there is no clock or no active timer, this will return | ||||
|      * `undefined`. | ||||
|      * @return {number} milliseconds since the start of the active timer | ||||
|      */ | ||||
|     TimerService.prototype.now = function () { | ||||
|         var clock = this.time.clock(); | ||||
|         return clock && this.convert(clock.currentValue()); | ||||
|     }; | ||||
|  | ||||
|     return TimerService; | ||||
| }); | ||||
| @@ -1,87 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     "../../src/actions/FollowTimerAction" | ||||
| ], function (FollowTimerAction) { | ||||
|     var TIMER_SERVICE_METHODS = | ||||
|         ['setTimer', 'getTimer', 'clearTimer', 'on', 'off']; | ||||
|  | ||||
|     describe("The Follow Timer action", function () { | ||||
|         var testContext; | ||||
|         var testModel; | ||||
|         var testAdaptedObject; | ||||
|  | ||||
|         beforeEach(function () { | ||||
|             testModel = {}; | ||||
|             testContext = { domainObject: jasmine.createSpyObj('domainObject', [ | ||||
|                 'getModel', | ||||
|                 'useCapability' | ||||
|             ]) }; | ||||
|             testAdaptedObject = { foo: 'bar' }; | ||||
|             testContext.domainObject.getModel.andReturn(testModel); | ||||
|             testContext.domainObject.useCapability.andCallFake(function (c) { | ||||
|                 return c === 'adapter' && testAdaptedObject; | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         it("is applicable to timers", function () { | ||||
|             testModel.type = "timer"; | ||||
|             expect(FollowTimerAction.appliesTo(testContext)).toBe(true); | ||||
|         }); | ||||
|  | ||||
|         it("is inapplicable to non-timers", function () { | ||||
|             testModel.type = "folder"; | ||||
|             expect(FollowTimerAction.appliesTo(testContext)).toBe(false); | ||||
|         }); | ||||
|  | ||||
|         describe("when instantiated", function () { | ||||
|             var mockTimerService; | ||||
|             var action; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 mockTimerService = jasmine.createSpyObj( | ||||
|                     'timerService', | ||||
|                     TIMER_SERVICE_METHODS | ||||
|                 ); | ||||
|                 action = new FollowTimerAction(mockTimerService, testContext); | ||||
|             }); | ||||
|  | ||||
|             it("does not interact with the timer service", function () { | ||||
|                 TIMER_SERVICE_METHODS.forEach(function (method) { | ||||
|                     expect(mockTimerService[method]).not.toHaveBeenCalled(); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             describe("and performed", function () { | ||||
|                 beforeEach(function () { | ||||
|                     action.perform(); | ||||
|                 }); | ||||
|  | ||||
|                 it("sets the active timer", function () { | ||||
|                     expect(mockTimerService.setTimer) | ||||
|                         .toHaveBeenCalledWith(testAdaptedObject); | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -1,61 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define(["../../src/indicators/FollowIndicator"], function (FollowIndicator) { | ||||
|     var TIMER_SERVICE_METHODS = | ||||
|         ['setTimer', 'getTimer', 'clearTimer', 'on', 'off']; | ||||
|  | ||||
|     describe("The timer-following indicator", function () { | ||||
|         var mockTimerService; | ||||
|         var indicator; | ||||
|  | ||||
|         beforeEach(function () { | ||||
|             mockTimerService = | ||||
|                 jasmine.createSpyObj('timerService', TIMER_SERVICE_METHODS); | ||||
|             indicator = new FollowIndicator(mockTimerService); | ||||
|         }); | ||||
|  | ||||
|         it("implements the Indicator interface", function () { | ||||
|             expect(indicator.getGlyphClass()).toEqual(jasmine.any(String)); | ||||
|             expect(indicator.getCssClass()).toEqual(jasmine.any(String)); | ||||
|             expect(indicator.getText()).toEqual(jasmine.any(String)); | ||||
|             expect(indicator.getDescription()).toEqual(jasmine.any(String)); | ||||
|         }); | ||||
|  | ||||
|         describe("when a timer is set", function () { | ||||
|             var testModel; | ||||
|             var mockDomainObject; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testModel = { name: "some timer!" }; | ||||
|                 mockDomainObject = jasmine.createSpyObj('timer', ['getModel']); | ||||
|                 mockDomainObject.getModel.andReturn(testModel); | ||||
|                 mockTimerService.getTimer.andReturn(mockDomainObject); | ||||
|             }); | ||||
|  | ||||
|             it("displays the timer's name", function () { | ||||
|                 expect(indicator.getText().indexOf(testModel.name)) | ||||
|                     .not.toEqual(-1); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -1,77 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     '../../src/services/TimerService' | ||||
| ], function (TimerService) { | ||||
|     describe("TimerService", function () { | ||||
|         var callback; | ||||
|         var mockmct; | ||||
|         var timerService; | ||||
|  | ||||
|         beforeEach(function () { | ||||
|             callback = jasmine.createSpy('callback'); | ||||
|             mockmct = { | ||||
|                 time: { clock: jasmine.createSpy('clock') }, | ||||
|                 objects: { observe: jasmine.createSpy('observe') } | ||||
|             }; | ||||
|             timerService = new TimerService(mockmct); | ||||
|             timerService.on('change', callback); | ||||
|         }); | ||||
|  | ||||
|         it("initially emits no change events", function () { | ||||
|             expect(callback).not.toHaveBeenCalled(); | ||||
|         }); | ||||
|  | ||||
|         it("reports no current timer", function () { | ||||
|             expect(timerService.getTimer()).toBeUndefined(); | ||||
|         }); | ||||
|  | ||||
|         describe("setTimer", function () { | ||||
|             var testTimer; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testTimer = { name: "I am some timer; you are nobody." }; | ||||
|                 timerService.setTimer(testTimer); | ||||
|             }); | ||||
|  | ||||
|             it("emits a change event", function () { | ||||
|                 expect(callback).toHaveBeenCalled(); | ||||
|             }); | ||||
|  | ||||
|             it("reports the current timer", function () { | ||||
|                 expect(timerService.getTimer()).toBe(testTimer); | ||||
|             }); | ||||
|  | ||||
|             it("observes changes to an object", function () { | ||||
|                 var newTimer = { name: "I am another timer." }; | ||||
|                 expect(mockmct.objects.observe).toHaveBeenCalledWith( | ||||
|                     testTimer, | ||||
|                     '*', | ||||
|                     jasmine.any(Function) | ||||
|                 ); | ||||
|                 mockmct.objects.observe.mostRecentCall.args[2](newTimer); | ||||
|                 expect(timerService.getTimer()).toBe(newTimer); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -255,8 +255,6 @@ define( | ||||
|                 if (this.nextDatum) { | ||||
|                     this.updateValues(this.nextDatum); | ||||
|                     delete this.nextDatum; | ||||
|                 } else { | ||||
|                     this.updateValues(this.$scope.imageHistory[this.$scope.imageHistory.length - 1]); | ||||
|                 } | ||||
|                 this.autoScroll = true; | ||||
|             } | ||||
|   | ||||
| @@ -183,17 +183,6 @@ define( | ||||
|                     expect(controller.getImageUrl()).toEqual(newUrl); | ||||
|                 }); | ||||
|  | ||||
|                 it("forwards large image view to latest image in history on un-pause", function () { | ||||
|                     $scope.imageHistory = [ | ||||
|                         { utc: 1434600258122, url: 'some/url1', selected: false}, | ||||
|                         { utc: 1434600258123, url: 'some/url2', selected: false} | ||||
|                     ]; | ||||
|                     controller.paused(true); | ||||
|                     controller.paused(false); | ||||
|  | ||||
|                     expect(controller.getImageUrl()).toEqual(controller.getImageUrl($scope.imageHistory[1])); | ||||
|                 }); | ||||
|  | ||||
|                 it("subscribes to telemetry", function () { | ||||
|                     expect(openmct.telemetry.subscribe).toHaveBeenCalledWith( | ||||
|                         newDomainObject, | ||||
| @@ -238,7 +227,7 @@ define( | ||||
|                     expect(controller.updateHistory(mockDatum)).toBe(false); | ||||
|                 }); | ||||
|  | ||||
|                 describe("when user clicks on imagery thumbnail", function () { | ||||
|                 describe("user clicks on imagery thumbnail", function () { | ||||
|                     var mockDatum = { utc: 1434600258123, url: 'some/url', selected: false}; | ||||
|  | ||||
|                     it("pauses and adds selected class to imagery thumbnail", function () { | ||||
| @@ -259,7 +248,6 @@ define( | ||||
|                         expect(controller.getTime()).toEqual(controller.timeFormat.format(mockDatum.utc)); | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|             }); | ||||
|  | ||||
|             it("initially shows an empty string for date/time", function () { | ||||
|   | ||||
| @@ -360,47 +360,22 @@ define( | ||||
|          */ | ||||
|         FixedController.prototype.updateView = function (telemetryObject, datum) { | ||||
|             var metadata = this.openmct.telemetry.getMetadata(telemetryObject); | ||||
|             var telemetryKeyToDisplay = this.chooseTelemetryKeyToDisplay(metadata); | ||||
|             var formattedTelemetryValue = this.getFormattedTelemetryValueForKey(telemetryKeyToDisplay, datum, metadata); | ||||
|             var rangeMetadata = metadata.valuesForHints(['range'])[0]; | ||||
|             var rangeKey = rangeMetadata.source || rangeMetadata.key; | ||||
|             var valueMetadata = metadata.value(rangeKey); | ||||
|             var limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject); | ||||
|             var alarm = limitEvaluator && limitEvaluator.evaluate(datum, telemetryKeyToDisplay); | ||||
|             var formatter = this.openmct.telemetry.getValueFormatter(valueMetadata); | ||||
|             var value = datum[valueMetadata.key]; | ||||
|             var alarm = limitEvaluator && limitEvaluator.evaluate(datum, rangeKey); | ||||
|  | ||||
|             this.setDisplayedValue( | ||||
|                 telemetryObject, | ||||
|                 formattedTelemetryValue, | ||||
|                 formatter.format(value), | ||||
|                 alarm && alarm.cssClass | ||||
|             ); | ||||
|             this.digest(); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * @private | ||||
|          */ | ||||
|         FixedController.prototype.getFormattedTelemetryValueForKey = function (telemetryKeyToDisplay, datum, metadata) { | ||||
|             var valueMetadata = metadata.value(telemetryKeyToDisplay); | ||||
|             var formatter = this.openmct.telemetry.getValueFormatter(valueMetadata); | ||||
|  | ||||
|             return formatter.format(datum[valueMetadata.key]); | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * @private | ||||
|          */ | ||||
|         FixedController.prototype.chooseTelemetryKeyToDisplay = function (metadata) { | ||||
|             // If there is a range value, show that preferentially | ||||
|             var telemetryKeyToDisplay = metadata.valuesForHints(['range'])[0]; | ||||
|  | ||||
|             // If no range is defined, default to the highest priority non time-domain data. | ||||
|             if (telemetryKeyToDisplay === undefined) { | ||||
|                 var valuesOrderedByPriority = metadata.values(); | ||||
|                 telemetryKeyToDisplay = valuesOrderedByPriority.filter(function (valueMetadata) { | ||||
|                     return !(valueMetadata.hints.domain); | ||||
|                 })[0]; | ||||
|             } | ||||
|  | ||||
|             return telemetryKeyToDisplay.source; | ||||
|         }; | ||||
|  | ||||
|         /** | ||||
|          * Request the last historical data point for the given domain objects | ||||
|          * @param {object[]} objects | ||||
| @@ -413,9 +388,7 @@ define( | ||||
|             objects.forEach(function (object) { | ||||
|                 self.openmct.telemetry.request(object, {start: bounds.start, end: bounds.end, size: 1}) | ||||
|                     .then(function (data) { | ||||
|                         if (data.length > 0) { | ||||
|                             self.updateView(object, data[data.length - 1]); | ||||
|                         } | ||||
|                         self.updateView(object, data[data.length - 1]); | ||||
|                     }); | ||||
|             }); | ||||
|             return objects; | ||||
|   | ||||
| @@ -26,12 +26,8 @@ | ||||
|  * @namespace platform/features/layout | ||||
|  */ | ||||
| define( | ||||
|     [ | ||||
|         './LayoutDrag' | ||||
|     ], | ||||
|     function ( | ||||
|         LayoutDrag | ||||
|     ) { | ||||
|     ['./LayoutDrag'], | ||||
|     function (LayoutDrag) { | ||||
|  | ||||
|         var DEFAULT_DIMENSIONS = [12, 8], | ||||
|             DEFAULT_GRID_SIZE = [32, 32], | ||||
| @@ -127,8 +123,6 @@ define( | ||||
|                         if (self.droppedIdToSelectAfterRefresh) { | ||||
|                             self.select(null, self.droppedIdToSelectAfterRefresh); | ||||
|                             delete self.droppedIdToSelectAfterRefresh; | ||||
|                         } else if (composition.indexOf(self.selectedId) === -1) { | ||||
|                             self.clearSelection(); | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|   | ||||
| @@ -178,6 +178,7 @@ define( | ||||
|                     Promise.resolve(mockChildren) | ||||
|                 ); | ||||
|  | ||||
|  | ||||
|                 mockScope.model = testModel; | ||||
|                 mockScope.configuration = testConfiguration; | ||||
|                 mockScope.selection = jasmine.createSpyObj( | ||||
| @@ -193,8 +194,7 @@ define( | ||||
|  | ||||
|                 mockMetadata = jasmine.createSpyObj('mockMetadata', [ | ||||
|                     'valuesForHints', | ||||
|                     'value', | ||||
|                     'values' | ||||
|                     'value' | ||||
|                 ]); | ||||
|                 mockMetadata.value.andReturn({ | ||||
|                     key: 'value' | ||||
| @@ -653,39 +653,6 @@ define( | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("selects an range value to display, if available", function () { | ||||
|                     mockMetadata.valuesForHints.andReturn([ | ||||
|                         { | ||||
|                             key: 'range', | ||||
|                             source: 'range' | ||||
|                         } | ||||
|                     ]); | ||||
|                     var key = controller.chooseTelemetryKeyToDisplay(mockMetadata); | ||||
|                     expect(key).toEqual('range'); | ||||
|                 }); | ||||
|  | ||||
|                 it("selects the first non-domain value to display, if no range available", function () { | ||||
|                     mockMetadata.valuesForHints.andReturn([]); | ||||
|                     mockMetadata.values.andReturn([ | ||||
|                         { | ||||
|                             key: 'domain', | ||||
|                             source: 'domain', | ||||
|                             hints: { | ||||
|                                 domain: 1 | ||||
|                             } | ||||
|                         }, | ||||
|                         { | ||||
|                             key: 'image', | ||||
|                             source: 'image', | ||||
|                             hints: { | ||||
|                                 image: 1 | ||||
|                             } | ||||
|                         } | ||||
|                     ]); | ||||
|                     var key = controller.chooseTelemetryKeyToDisplay(mockMetadata); | ||||
|                     expect(key).toEqual('image'); | ||||
|                 }); | ||||
|  | ||||
|                 it("reflects limit status", function () { | ||||
|                     mockLimitEvaluator.evaluate.andReturn({cssClass: "alarm-a"}); | ||||
|                     controller.updateView(mockTelemetryObject, [{ | ||||
|   | ||||
| @@ -424,17 +424,6 @@ define( | ||||
|                 expect(selectedObj.showFrame).toEqual(jasmine.any(Function)); | ||||
|             }); | ||||
|  | ||||
|             it("deselects the object that is no longer in the composition", function () { | ||||
|                 mockScope.$watchCollection.mostRecentCall.args[1](); | ||||
|                 var childObj = mockCompositionObjects[0]; | ||||
|                 controller.select(mockEvent, childObj.getId()); | ||||
|  | ||||
|                 var composition = ["b", "c"]; | ||||
|                 mockScope.$watchCollection.mostRecentCall.args[1](composition); | ||||
|  | ||||
|                 expect(controller.selected(childObj)).toBe(false); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
|   | ||||
| @@ -49,7 +49,7 @@ | ||||
|                 { | ||||
|                     "key": "ListViewController", | ||||
|                     "implementation": ListViewController, | ||||
|                     "depends": ["$scope", "formatService"] | ||||
|                     "depends": ["$scope"] | ||||
|                 } | ||||
|             ], | ||||
|             "directives": [ | ||||
|   | ||||
| @@ -21,7 +21,7 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define(function () { | ||||
|     function ListViewController($scope, formatService) { | ||||
|     function ListViewController($scope) { | ||||
|         this.$scope = $scope; | ||||
|         $scope.orderByField = 'title'; | ||||
|         $scope.reverseSort = false; | ||||
| @@ -30,8 +30,6 @@ define(function () { | ||||
|         var unlisten = $scope.domainObject.getCapability('mutation') | ||||
|             .listen(this.updateView.bind(this)); | ||||
|  | ||||
|         this.utc = formatService.getFormat('utc'); | ||||
|  | ||||
|         $scope.$on('$destroy', function () { | ||||
|             unlisten(); | ||||
|         }); | ||||
| @@ -52,13 +50,17 @@ define(function () { | ||||
|                 icon: child.getCapability('type').getCssClass(), | ||||
|                 title: child.getModel().name, | ||||
|                 type: child.getCapability('type').getName(), | ||||
|                 persisted: this.utc.format(child.getModel().persisted), | ||||
|                 modified: this.utc.format(child.getModel().modified), | ||||
|                 persisted: new Date( | ||||
|                     child.getModel().persisted | ||||
|                 ).toUTCString(), | ||||
|                 modified: new Date( | ||||
|                     child.getModel().modified | ||||
|                 ).toUTCString(), | ||||
|                 asDomainObject: child, | ||||
|                 location: child.getCapability('location'), | ||||
|                 action: child.getCapability('action') | ||||
|             }; | ||||
|         }, this); | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     return ListViewController; | ||||
|   | ||||
| @@ -31,9 +31,7 @@ define( | ||||
|                 controller, | ||||
|                 childModel, | ||||
|                 typeCapability, | ||||
|                 mutationCapability, | ||||
|                 formatService; | ||||
|  | ||||
|                 mutationCapability; | ||||
|             beforeEach(function () { | ||||
|                 unlistenFunc = jasmine.createSpy("unlisten"); | ||||
|  | ||||
| @@ -43,18 +41,6 @@ define( | ||||
|                 ); | ||||
|                 mutationCapability.listen.andReturn(unlistenFunc); | ||||
|  | ||||
|                 formatService = jasmine.createSpyObj( | ||||
|                     "formatService", | ||||
|                     ["getFormat"] | ||||
|                 ); | ||||
|                 formatService.getFormat.andReturn(jasmine.createSpyObj( | ||||
|                     'utc', | ||||
|                     ["format"] | ||||
|                 )); | ||||
|                 formatService.getFormat().format.andCallFake(function (v) { | ||||
|                     return "formatted " + v; | ||||
|                 }); | ||||
|  | ||||
|                 typeCapability = jasmine.createSpyObj( | ||||
|                     "typeCapability", | ||||
|                     ["getCssClass", "getName"] | ||||
| @@ -108,27 +94,20 @@ define( | ||||
|                 ); | ||||
|                 scope.domainObject = domainObject; | ||||
|  | ||||
|                 controller  = new ListViewController(scope, formatService); | ||||
|                 controller  = new ListViewController(scope); | ||||
|  | ||||
|                 waitsFor(function () { | ||||
|                     return scope.children; | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("uses the UTC time format", function () { | ||||
|                 expect(formatService.getFormat).toHaveBeenCalledWith('utc'); | ||||
|             }); | ||||
|  | ||||
|             it("updates the view", function () { | ||||
|                 expect(scope.children[0]).toEqual( | ||||
|                     { | ||||
|                         icon: "icon-folder", | ||||
|                         title: "Battery Charge Status", | ||||
|                         type: "Folder", | ||||
|                         persisted: formatService.getFormat('utc') | ||||
|                             .format(childModel.persisted), | ||||
|                         modified: formatService.getFormat('utc') | ||||
|                             .format(childModel.modified), | ||||
|                         persisted: "Wed, 07 Jun 2017 20:34:57 GMT", | ||||
|                         modified: "Wed, 07 Jun 2017 20:34:57 GMT", | ||||
|                         asDomainObject: childObject, | ||||
|                         location: '' | ||||
|                     } | ||||
|   | ||||
| @@ -170,9 +170,6 @@ define( | ||||
|          * @param rows | ||||
|          */ | ||||
|         TelemetryTableController.prototype.addRowsToTable = function (rows) { | ||||
|             rows.forEach(function (row) { | ||||
|                 this.$scope.rows.push(row); | ||||
|             }, this); | ||||
|             this.$scope.$broadcast('add:rows', rows); | ||||
|         }; | ||||
|  | ||||
|   | ||||
| @@ -436,28 +436,5 @@ define( | ||||
|                 expect(mockScope.$broadcast).toHaveBeenCalledWith("remove:rows", discardedRows); | ||||
|             }); | ||||
|  | ||||
|             describe('when telemetry is added', function () { | ||||
|                 var testRows; | ||||
|                 var expectedRows; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     testRows = [{ a: 0 }, { a: 1 }, { a: 2 }]; | ||||
|                     mockScope.rows = [{ a: -1 }]; | ||||
|                     expectedRows = mockScope.rows.concat(testRows); | ||||
|  | ||||
|                     spyOn(controller.telemetry, "on").andCallThrough(); | ||||
|                     controller.registerChangeListeners(); | ||||
|  | ||||
|                     controller.telemetry.on.calls.forEach(function (call) { | ||||
|                         if (call.args[0] === 'added') { | ||||
|                             call.args[1](testRows); | ||||
|                         } | ||||
|                     }); | ||||
|                 }); | ||||
|  | ||||
|                 it("adds it to rows in scope", function () { | ||||
|                     expect(mockScope.rows).toEqual(expectedRows); | ||||
|                 }); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
|   | ||||
| @@ -29,7 +29,6 @@ define([ | ||||
|     "./src/controllers/TimelineTickController", | ||||
|     "./src/controllers/TimelineTableController", | ||||
|     "./src/controllers/TimelineGanttController", | ||||
|     "./src/controllers/TimelineTOIController", | ||||
|     "./src/controllers/ActivityModeValuesController", | ||||
|     "./src/capabilities/ActivityTimespanCapability", | ||||
|     "./src/capabilities/TimelineTimespanCapability", | ||||
| @@ -38,7 +37,6 @@ define([ | ||||
|     "./src/capabilities/CostCapability", | ||||
|     "./src/directives/MCTSwimlaneDrop", | ||||
|     "./src/directives/MCTSwimlaneDrag", | ||||
|     "./src/directives/MCTResourceGraphDrop", | ||||
|     "./src/services/ObjectLoader", | ||||
|     "./src/chart/MCTTimelineChart", | ||||
|     "text!./res/templates/values.html", | ||||
| @@ -61,7 +59,6 @@ define([ | ||||
|     TimelineTickController, | ||||
|     TimelineTableController, | ||||
|     TimelineGanttController, | ||||
|     TimelineTOIController, | ||||
|     ActivityModeValuesController, | ||||
|     ActivityTimespanCapability, | ||||
|     TimelineTimespanCapability, | ||||
| @@ -70,7 +67,6 @@ define([ | ||||
|     CostCapability, | ||||
|     MCTSwimlaneDrop, | ||||
|     MCTSwimlaneDrag, | ||||
|     MCTResourceGraphDrop, | ||||
|     ObjectLoader, | ||||
|     MCTTimelineChart, | ||||
|     valuesTemplate, | ||||
| @@ -506,15 +502,6 @@ define([ | ||||
|                         "TIMELINE_MAXIMUM_OFFSCREEN" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "TimelineTOIController", | ||||
|                     "implementation": TimelineTOIController, | ||||
|                     "depends": [ | ||||
|                         "openmct", | ||||
|                         "timerService", | ||||
|                         "$scope" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "ActivityModeValuesController", | ||||
|                     "implementation": ActivityModeValuesController, | ||||
| @@ -579,13 +566,6 @@ define([ | ||||
|                         "$interval", | ||||
|                         "$log" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|                     "key": "mctResourceGraphDrop", | ||||
|                     "implementation": MCTResourceGraphDrop, | ||||
|                     "depends": [ | ||||
|                         "dndService" | ||||
|                     ] | ||||
|                 } | ||||
|             ], | ||||
|             "services": [ | ||||
|   | ||||
| @@ -29,44 +29,6 @@ | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Follow Line | ||||
|     .l-follow-line { | ||||
|         // TODO: move before and after into l-timeline-gantt so those only render in that pane | ||||
|         pointer-events: none; | ||||
|         position: absolute; | ||||
|         top: 0; bottom: 0; | ||||
|         width: 1px; | ||||
|         z-index: 9; // Just below .l-hover-btns-holder | ||||
|     } | ||||
| } | ||||
|  | ||||
| .l-timeline-gantt { | ||||
|     .l-follow-line { | ||||
|         $d: 0.8rem; | ||||
|         top: $interiorMargin; | ||||
|         &:before, | ||||
|         &:after { | ||||
|             content: ''; | ||||
|             display: block; | ||||
|             height: $d; | ||||
|             width: $d; | ||||
|             position: absolute; | ||||
|             top: 0; | ||||
|             @include transform(translateX(-50%)); | ||||
|         } | ||||
|         &:before { | ||||
|             // Icon blocker | ||||
|             width: 2 * $d; | ||||
|         } | ||||
|         &:after { | ||||
|             // Icon | ||||
|             font-size: $d; | ||||
|             line-height: $d; | ||||
|             text-align: center; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| .s-timeline-gantt { | ||||
| @@ -146,9 +108,10 @@ | ||||
|     } | ||||
|     .s-hover-btns-holder { | ||||
|         $bg: $timelineHeaderColorBg; | ||||
|         $bga: 1; | ||||
|         $l: 5%; | ||||
|         @include user-select(none); | ||||
|         @include background-image(linear-gradient(-90deg, rgba($bg, 1), rgba($bg, 1) 70%, rgba($bg, 0) 100%)); | ||||
|         @include background-image(linear-gradient(-90deg, rgba($bg, $bga), rgba($bg, $bga) 70%, rgba($bg, 0) 100%)); | ||||
|         .s-button { | ||||
|             height: 16px; | ||||
|             line-height: 16px; | ||||
| @@ -166,27 +129,4 @@ | ||||
|             color: $timelineResourceGraphFg; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     .s-follow-line { | ||||
|         background: rgba($timeControllerToiLineColor, 0.5); | ||||
|     } | ||||
|  | ||||
|     .s-timeline-gantt { | ||||
|         .s-follow-line { | ||||
|             &:after { | ||||
|                 // Icon | ||||
|                 color: $timeControllerToiLineColor; | ||||
|                 content: $glyph-icon-timer; | ||||
|                 font-family: symbolsfont; | ||||
|                 text-shadow: $shdwItemText; | ||||
|             } | ||||
|             &:before { | ||||
|                 // Blocker | ||||
|                 $bg: $timelineHeaderColorBg; | ||||
|                 $l: 30%; | ||||
|                 @include background-image(linear-gradient(90deg, rgba($bg, 0), rgba($bg, 1) $l, rgba($bg, 1) 100% - $l, rgba($bg, 0))); | ||||
|  | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -38,10 +38,6 @@ | ||||
|     .l-timeline-pane { | ||||
|         @include absPosDefault(); | ||||
|  | ||||
| 		&.drop-over { | ||||
| 			background-color: lighten($colorEditAreaBg, 5%); | ||||
| 		} | ||||
|  | ||||
| 	    .l-width-control { | ||||
| 		    position: relative; | ||||
| 	    } | ||||
| @@ -79,10 +75,6 @@ | ||||
|                 } | ||||
|             } | ||||
|             &.l-timeline-gantt { | ||||
|                 .abs.l-timeline-gantt-header-w { | ||||
|                     overflow: hidden; | ||||
|                     height: $timelineTopPaneHeaderH; | ||||
|                 } | ||||
|                 .l-swimlanes-holder { | ||||
|                     @include scrollV(scroll); | ||||
|                     bottom: $scrollbarTrackSize; | ||||
|   | ||||
| @@ -24,7 +24,6 @@ $output-bourbon-deprecation-warnings: false; | ||||
|  | ||||
| @import "../../../../commonUI/general/res/sass/constants"; | ||||
| @import "../../../../commonUI/general/res/sass/mixins"; | ||||
| @import "../../../../commonUI/general/res/sass/glyphs"; | ||||
| @import "../../../../commonUI/themes/espresso/res/sass/constants"; | ||||
| @import "../../../../commonUI/themes/espresso/res/sass/mixins"; | ||||
| @import "constants"; | ||||
|   | ||||
| @@ -24,7 +24,6 @@ $output-bourbon-deprecation-warnings: false; | ||||
|  | ||||
| @import "../../../../commonUI/general/res/sass/constants"; | ||||
| @import "../../../../commonUI/general/res/sass/mixins"; | ||||
| @import "../../../../commonUI/general/res/sass/glyphs"; | ||||
| @import "../../../../commonUI/themes/snow/res/sass/constants"; | ||||
| @import "../../../../commonUI/themes/snow/res/sass/mixins"; | ||||
| @import "constants"; | ||||
|   | ||||
| @@ -24,7 +24,6 @@ $output-bourbon-deprecation-warnings: false; | ||||
|  | ||||
| @import "../../../../commonUI/general/res/sass/constants"; | ||||
| @import "../../../../commonUI/general/res/sass/mixins"; | ||||
| @import "../../../../commonUI/general/res/sass/glyphs"; | ||||
| @import "../../../../commonUI/themes/espresso/res/sass/constants"; | ||||
| @import "../../../../commonUI/themes/espresso/res/sass/mixins"; | ||||
| @import "constants"; | ||||
|   | ||||
| @@ -77,8 +77,7 @@ | ||||
|         <mct-splitter></mct-splitter> | ||||
|  | ||||
|         <!-- BOTTOM PANE RESOURCE LEGEND --> | ||||
|         <div mct-resource-graph-drop | ||||
|              class="split-pane-component abs l-timeline-pane t-pane-h l-pane-btm s-timeline-resource-legend l-timeline-resource-legend"> | ||||
|         <div class="split-pane-component abs l-timeline-pane t-pane-h l-pane-btm s-timeline-resource-legend l-timeline-resource-legend"> | ||||
|             <div class="l-title s-title">{{ngModel.title}}Resource Graph Legend</div> | ||||
|             <div class="l-legend-items legend"> | ||||
|                 <mct-include key="'timeline-legend-item'" | ||||
| @@ -97,124 +96,109 @@ | ||||
|  | ||||
|     <!-- RIGHT PANE: GANTT AND RESOURCE PLOTS --> | ||||
|     <span ng-controller="TimelineZoomController as zoomController" class="abs"> | ||||
|  | ||||
|         <span class="toi-control-holder temp" ng-controller="TimelineTOIController as toiController"> | ||||
|             <mct-split-pane anchor="bottom" | ||||
|     <mct-split-pane anchor="bottom" | ||||
|                     position="pane.y" | ||||
|                     class="abs split-pane-component l-timeline-pane l-pane-r t-pane-v"> | ||||
|  | ||||
|                 <!-- TOP PANE GANTT BARS --> | ||||
|                 <div class="split-pane-component l-timeline-pane t-pane-h l-pane-top t-timeline-gantt l-timeline-gantt s-timeline-gantt"> | ||||
|                     <div class="l-hover-btns-holder s-hover-btns-holder"> | ||||
|                         <a class="s-button icon-timer" | ||||
|                            ng-click="scroll.follow = true" | ||||
|                            ng-show="!toiController.isFollowing() && toiController.isActive()" | ||||
|                            title="Follow time bounds"> | ||||
|                         </a> | ||||
|         <!-- TOP PANE GANTT BARS --> | ||||
|         <div class="split-pane-component l-timeline-pane t-pane-h l-pane-top t-timeline-gantt l-timeline-gantt s-timeline-gantt"> | ||||
|             <div class="l-hover-btns-holder s-hover-btns-holder"> | ||||
|                 <a class="s-button icon-arrows-out" | ||||
|                    ng-click="zoomController.fit()" | ||||
|                    ng-show="true" | ||||
|                    title="Zoom to fit"> | ||||
|                 </a> | ||||
|  | ||||
|                         <a class="s-button icon-arrows-out" | ||||
|                            ng-click="scroll.follow = false; zoomController.fit()" | ||||
|                            ng-show="true" | ||||
|                            title="Zoom to fit"> | ||||
|                         </a> | ||||
|                 <a class="s-button icon-magnify-in" | ||||
|                    ng-click="zoomController.zoom(-1)" | ||||
|                    ng-show="true" | ||||
|                    title="Zoom in"> | ||||
|                 </a> | ||||
|  | ||||
|                         <a class="s-button icon-magnify-in" | ||||
|                            ng-click="scroll.follow = false; zoomController.zoom(-1)" | ||||
|                            ng-show="true" | ||||
|                            title="Zoom in"> | ||||
|                         </a> | ||||
|                 <a class="s-button icon-magnify-out" | ||||
|                    ng-click="zoomController.zoom(1)" | ||||
|                    ng-show="true" | ||||
|                    title="Zoom out"> | ||||
|                 </a> | ||||
|             </div> | ||||
|  | ||||
|                         <a class="s-button icon-magnify-out" | ||||
|                            ng-click="scroll.follow = false; zoomController.zoom(1)" | ||||
|                            ng-show="true" | ||||
|                            title="Zoom out"> | ||||
|                         </a> | ||||
|                     </div> | ||||
|             <div style="overflow: hidden; position: absolute; left: 0; top: 0; right: 0; height: 30px;" mct-scroll-x="scroll.x"> | ||||
|                 <mct-include key="'timeline-ticks'" | ||||
|                              parameters="{ | ||||
|                                          fullWidth: zoomController.width(timelineController.end()), | ||||
|                                          start: scroll.x, | ||||
|                                          width: scroll.width, | ||||
|                                          step: zoomController.toPixels(zoomController.zoom()), | ||||
|                                          toMillis: zoomController.toMillis | ||||
|                                          }"> | ||||
|                 </mct-include> | ||||
|             </div> | ||||
|  | ||||
|                     <div style="overflow: hidden; position: absolute; left: 0; top: 0; right: 0; height: 30px;" mct-scroll-x="scroll.x"> | ||||
|                         <mct-include key="'timeline-ticks'" | ||||
|                                      parameters="{ | ||||
|                                                  fullWidth: zoomController.width(timelineController.end()), | ||||
|                                                  start: scroll.x, | ||||
|                                                  width: scroll.width, | ||||
|                                                  step: zoomController.toPixels(zoomController.zoom()), | ||||
|                                                  toMillis: zoomController.toMillis | ||||
|                                                  }"> | ||||
|                         </mct-include> | ||||
|                     </div> | ||||
|                     <div ng-if="toiController.isActive()" class="l-follow-line s-follow-line" | ||||
|                          ng-style="{ left: toiController.x() - scroll.x + 'px' }"></div> | ||||
|             <div class="t-swimlanes-holder l-swimlanes-holder" | ||||
|                  mct-scroll-x="scroll.x" | ||||
|                  mct-scroll-y="scroll.y"> | ||||
|                 <div class="l-width-control" | ||||
|                      ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }"> | ||||
|                     <div class="t-swimlane s-swimlane l-swimlane" | ||||
|                          ng-repeat="swimlane in timelineController.swimlanes()" | ||||
|                          ng-class="{ | ||||
|                                    exceeded: swimlane.exceeded(), | ||||
|                                    selected: selection.selected(swimlane), | ||||
|                                    'drop-into': swimlane.highlight(), | ||||
|                                    'drop-after': swimlane.highlightBottom() | ||||
|                                    }" | ||||
|                          ng-click="selection.select(swimlane)" | ||||
|                          mct-swimlane-drop="swimlane"> | ||||
|  | ||||
|                     <div class="t-swimlanes-holder l-swimlanes-holder" | ||||
|                          mct-scroll-x="scroll.x" | ||||
|                          mct-scroll-y="scroll.y"> | ||||
|                         <div class="l-width-control" | ||||
|                              ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }"> | ||||
|                             <div class="t-swimlane s-swimlane l-swimlane" | ||||
|                                  ng-repeat="swimlane in timelineController.swimlanes()" | ||||
|                                  ng-class="{ | ||||
|                                            exceeded: swimlane.exceeded(), | ||||
|                                            selected: selection.selected(swimlane), | ||||
|                                            'drop-into': swimlane.highlight(), | ||||
|                                            'drop-after': swimlane.highlightBottom() | ||||
|                                            }" | ||||
|                                  ng-click="selection.select(swimlane)" | ||||
|                                  mct-swimlane-drop="swimlane"> | ||||
|                         <mct-representation key="'gantt'" | ||||
|                                             mct-object="swimlane.domainObject" | ||||
|                                             parameters="{ | ||||
|                                                         scroll: scroll, | ||||
|                                                         toPixels: zoomController.toPixels | ||||
|                                                         }"> | ||||
|                         </mct-representation> | ||||
|  | ||||
|                                 <mct-representation key="'gantt'" | ||||
|                                                     mct-object="swimlane.domainObject" | ||||
|                                                     parameters="{ | ||||
|                                                                 scroll: scroll, | ||||
|                                                                 toPixels: zoomController.toPixels | ||||
|                                                                 }"> | ||||
|                                 </mct-representation> | ||||
|  | ||||
|                                 <span ng-if="selection.selected(swimlane)"> | ||||
|                                     <span ng-repeat="handle in timelineController.handles()" | ||||
|                                           ng-style="handle.style(zoomController)" | ||||
|                                           style="position: absolute; top: 0px; bottom: 0px;" | ||||
|                                           class="handle" | ||||
|                                           ng-class="{ start: $index === 0, mid: $index === 1, end: $index > 1 }" | ||||
|                                           mct-drag-down="handle.begin()" | ||||
|                                           mct-drag="handle.drag(delta[0], zoomController); timelineController.refresh()" | ||||
|                                           mct-drag-up="handle.finish()"> | ||||
|                                     </span> | ||||
|                                 </span> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                         <span ng-if="selection.selected(swimlane)"> | ||||
|                             <span ng-repeat="handle in timelineController.handles()" | ||||
|                                   ng-style="handle.style(zoomController)" | ||||
|                                   style="position: absolute; top: 0px; bottom: 0px;" | ||||
|                                   class="handle" | ||||
|                                   ng-class="{ start: $index === 0, mid: $index === 1, end: $index > 1 }" | ||||
|                                   mct-drag-down="handle.begin()" | ||||
|                                   mct-drag="handle.drag(delta[0], zoomController); timelineController.refresh()" | ||||
|                                   mct-drag-up="handle.finish()"> | ||||
|                             </span> | ||||
|                         </span> | ||||
|                     </div> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|  | ||||
|                 <!-- HORZ SPLITTER --> | ||||
|                 <mct-splitter></mct-splitter> | ||||
|         <!-- HORZ SPLITTER --> | ||||
|         <mct-splitter></mct-splitter> | ||||
|  | ||||
|                 <!-- BOTTOM PANE RESOURCE GRAPHS AND RIGHT PANE HORIZONTAL SCROLL CONTROL --> | ||||
|                 <div class="split-pane-component l-timeline-resource-graph l-timeline-pane t-pane-h l-pane-btm"> | ||||
|                     <div class="l-graphs-holder" | ||||
|                          mct-resize="scroll.width = bounds.width"> | ||||
|                         <div class="t-graphs l-graphs"> | ||||
|                             <mct-include key="'timeline-resource-graphs'" | ||||
|                                          parameters="{ | ||||
|                                                      origin: zoomController.toMillis(scroll.x), | ||||
|                                                      duration: zoomController.toMillis(scroll.width), | ||||
|                                                      graphs: timelineController.graphs() | ||||
|                                                      }"> | ||||
|                             </mct-include> | ||||
|                         </div> | ||||
|                         <div ng-if="toiController.isActive()" class="l-follow-line s-follow-line" | ||||
|                              ng-style="{ left: toiController.x() - scroll.x + 'px' }"></div> | ||||
|                     </div> | ||||
|                     <div mct-scroll-x="scroll.x" | ||||
|                          class="t-pane-r-scroll-h-control l-scroll-control s-scroll-control"> | ||||
|                         <div class="l-width-control" | ||||
|                              ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }"> | ||||
|                         </div> | ||||
|                     </div> | ||||
|         <!-- BOTTOM PANE RESOURCE GRAPHS AND RIGHT PANE HORIZONTAL SCROLL CONTROL --> | ||||
|         <div class="split-pane-component l-timeline-resource-graph l-timeline-pane t-pane-h l-pane-btm"> | ||||
|             <div class="l-graphs-holder" | ||||
|                  mct-resize="scroll.width = bounds.width"> | ||||
|                 <div class="t-graphs l-graphs"> | ||||
|                     <mct-include key="'timeline-resource-graphs'" | ||||
|                                  parameters="{ | ||||
|                                              origin: zoomController.toMillis(scroll.x), | ||||
|                                              duration: zoomController.toMillis(scroll.width), | ||||
|                                              graphs: timelineController.graphs() | ||||
|                                              }"> | ||||
|                     </mct-include> | ||||
|                 </div> | ||||
|             </mct-split-pane> | ||||
|         </span> | ||||
|  | ||||
|  | ||||
|             </div> | ||||
|             <div mct-scroll-x="scroll.x" | ||||
|                  class="t-pane-r-scroll-h-control l-scroll-control s-scroll-control"> | ||||
|                 <div class="l-width-control" | ||||
|                      ng-style="{ width: zoomController.width(timelineController.end()) + 'px' }"> | ||||
|                 </div> | ||||
|             </div> | ||||
|         </div> | ||||
|     </mct-split-pane> | ||||
|     </span> | ||||
| </mct-split-pane> | ||||
| </div> | ||||
|   | ||||
| @@ -1,111 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([], function () { | ||||
|  | ||||
|     /** | ||||
|      * Tracks time-of-interest in timelines, updating both scroll state | ||||
|      * (when appropriate) and positioning of the displayed line. | ||||
|      */ | ||||
|     function TimelineTOIController(openmct, timerService, $scope) { | ||||
|         this.openmct = openmct; | ||||
|         this.timerService = timerService; | ||||
|         this.$scope = $scope; | ||||
|  | ||||
|         this.change = this.change.bind(this); | ||||
|         this.bounds = this.bounds.bind(this); | ||||
|         this.destroy = this.destroy.bind(this); | ||||
|  | ||||
|         this.timerService.on('change', this.change); | ||||
|         this.openmct.time.on('bounds', this.bounds); | ||||
|  | ||||
|         this.$scope.$on('$destroy', this.destroy); | ||||
|  | ||||
|         this.$scope.scroll.follow = this.timerService.hasTimer(); | ||||
|         if (this.$scope.zoomController) { | ||||
|             this.bounds(this.openmct.time.bounds()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
|     /** | ||||
|      * Handle a `change` event from the timer service; track the | ||||
|      * new timer. | ||||
|      */ | ||||
|     TimelineTOIController.prototype.change = function () { | ||||
|         this.$scope.scroll.follow = | ||||
|             this.$scope.scroll.follow || this.timerService.hasTimer(); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Handle a `bounds` event from the time API; scroll the timeline | ||||
|      * to match the current bounds, if currently in follow mode. | ||||
|      */ | ||||
|     TimelineTOIController.prototype.bounds = function (bounds) { | ||||
|         if (this.isFollowing()) { | ||||
|             var start = this.timerService.convert(bounds.start); | ||||
|             var end = this.timerService.convert(bounds.end); | ||||
|             this.duration = bounds.end - bounds.start; | ||||
|             this.$scope.zoomController.bounds(start, end); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Handle a `$destroy` event from scope; detach all observers. | ||||
|      */ | ||||
|     TimelineTOIController.prototype.destroy = function () { | ||||
|         this.timerService.off('change', this.change); | ||||
|         this.openmct.time.off('bounds', this.bounds); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Get the x position of the time-of-interest line, | ||||
|      * in pixels from the left edge of the timeline area. | ||||
|      */ | ||||
|     TimelineTOIController.prototype.x = function () { | ||||
|         var now = this.timerService.now(); | ||||
|  | ||||
|         if (now === undefined) { | ||||
|             return undefined; | ||||
|         } | ||||
|  | ||||
|         return this.$scope.zoomController.toPixels(this.timerService.now()); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Check if there is an active time-of-interest to be shown. | ||||
|      * @return {boolean} true when active | ||||
|      */ | ||||
|     TimelineTOIController.prototype.isActive = function () { | ||||
|         return this.x() !== undefined; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Check if the timeline should be following time conductor bounds. | ||||
|      * @return {boolean} true when following | ||||
|      */ | ||||
|     TimelineTOIController.prototype.isFollowing = function () { | ||||
|         return !!this.$scope.scroll.follow && this.timerService.now() !== undefined; | ||||
|     }; | ||||
|  | ||||
|     return TimelineTOIController; | ||||
| }); | ||||
| @@ -32,8 +32,7 @@ define( | ||||
|             // Prefer to start with the middle index | ||||
|             var zoomLevels = ZOOM_CONFIGURATION.levels || [1000], | ||||
|                 zoomIndex = Math.floor(zoomLevels.length / 2), | ||||
|                 tickWidth = ZOOM_CONFIGURATION.width || 200, | ||||
|                 lastWidth = Number.MAX_VALUE; // Don't constrain prematurely | ||||
|                 tickWidth = ZOOM_CONFIGURATION.width || 200; | ||||
|  | ||||
|             function toMillis(pixels) { | ||||
|                 return (pixels / tickWidth) * zoomLevels[zoomIndex]; | ||||
| @@ -56,29 +55,19 @@ define( | ||||
|  | ||||
|             function setScroll(x) { | ||||
|                 $window.requestAnimationFrame(function () { | ||||
|                     $scope.scroll.x = Math.min( | ||||
|                         Math.max(x, 0), | ||||
|                         lastWidth - $scope.scroll.width | ||||
|                     ); | ||||
|                     $scope.scroll.x = x; | ||||
|                     $scope.$apply(); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function initializeZoomFromStartEnd(start, end) { | ||||
|                 var duration = end - start; | ||||
|             function initializeZoomFromTimespan(timespan) { | ||||
|                 var timelineDuration = timespan.getDuration(); | ||||
|                 zoomIndex = 0; | ||||
|                 while (toMillis($scope.scroll.width) < duration && | ||||
|                 while (toMillis($scope.scroll.width) < timelineDuration && | ||||
|                         zoomIndex < zoomLevels.length - 1) { | ||||
|                     zoomIndex += 1; | ||||
|                 } | ||||
|                 setScroll(toPixels(start)); | ||||
|             } | ||||
|  | ||||
|             function initializeZoomFromTimespan(timespan) { | ||||
|                 return initializeZoomFromStartEnd( | ||||
|                     timespan.getStart(), | ||||
|                     timespan.getEnd() | ||||
|                 ); | ||||
|                 setScroll(toPixels(timespan.getStart())); | ||||
|             } | ||||
|  | ||||
|             function initializeZoom() { | ||||
| @@ -112,13 +101,6 @@ define( | ||||
|                     } | ||||
|                     return zoomLevels[zoomIndex]; | ||||
|                 }, | ||||
|                 /** | ||||
|                  * Adjust the current zoom bounds to fit both the | ||||
|                  * start and the end time provided. | ||||
|                  * @param {number} start the starting timestamp | ||||
|                  * @param {number} end the ending timestamp | ||||
|                  */ | ||||
|                 bounds: initializeZoomFromStartEnd, | ||||
|                 /** | ||||
|                  * Set the zoom level to fit the bounds of the timeline | ||||
|                  * being viewed. | ||||
| @@ -137,14 +119,14 @@ define( | ||||
|                  */ | ||||
|                 toMillis: toMillis, | ||||
|                 /** | ||||
|                  * Set the maximum timestamp value to be displayed, and get | ||||
|                  * the pixel width necessary to display this value. | ||||
|                  * Get the pixel width necessary to fit the specified | ||||
|                  * timestamp, expressed as an offset in milliseconds from | ||||
|                  * the start of the timeline. | ||||
|                  * @param {number} timestamp the time to display | ||||
|                  */ | ||||
|                 width: function (timestamp) { | ||||
|                     var pixels = Math.ceil(toPixels(timestamp * (1 + PADDING))); | ||||
|                     lastWidth = Math.max($scope.scroll.width, pixels); | ||||
|                     return lastWidth; | ||||
|                     return Math.max($scope.scroll.width, pixels); | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|   | ||||
| @@ -1,81 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['./SwimlaneDragConstants'], | ||||
|     function (SwimlaneDragConstants) { | ||||
|  | ||||
|         /** | ||||
|          * Defines the `mct-resource-graph-drop` directive. When a drop occurs | ||||
|          * on an element with this attribute, the swimlane targeted by the drop | ||||
|          * will receive the dropped domain object (at which point it can handle | ||||
|          * the drop, typically by toggling the swimlane graph.) | ||||
|          * @param {DndService} dndService drag-and-drop service | ||||
|          */ | ||||
|         function MCTResourceGraphDrop(dndService) { | ||||
|  | ||||
|             function link(scope, element, attrs) { | ||||
|                 // Handle dragover | ||||
|                 element.on('dragover', function (e) { | ||||
|                     var swimlane = dndService.getData( | ||||
|                         SwimlaneDragConstants.TIMELINE_SWIMLANE_DRAG_TYPE | ||||
|                     ); | ||||
|  | ||||
|                     if (typeof swimlane !== "undefined" && !swimlane.graph()) { | ||||
|                         element.addClass('drop-over'); | ||||
|                         scope.$apply(); | ||||
|                         e.preventDefault(); | ||||
|                     } | ||||
|                 }); | ||||
|                 // Handle drops | ||||
|                 element.on('drop', function (e) { | ||||
|                     var swimlane = dndService.getData( | ||||
|                         SwimlaneDragConstants.TIMELINE_SWIMLANE_DRAG_TYPE | ||||
|                     ); | ||||
|  | ||||
|                     element.removeClass('drop-over'); | ||||
|  | ||||
|                     // Only toggle if the graph isn't already set | ||||
|                     if (typeof swimlane !== "undefined" && !swimlane.graph()) { | ||||
|                         swimlane.toggleGraph(); | ||||
|                         e.preventDefault(); | ||||
|                     } | ||||
|                 }); | ||||
|                 // Clear highlights when drag leaves this swimlane | ||||
|                 element.on('dragleave', function (e) { | ||||
|                     element.removeClass('drop-over'); | ||||
|                     scope.$apply(); | ||||
|                     e.preventDefault(); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|                 // Applies to attributes | ||||
|                 restrict: "A", | ||||
|                 // Link using above function | ||||
|                 link: link | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         return MCTResourceGraphDrop; | ||||
|     } | ||||
| ); | ||||
| @@ -1,138 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     "../../src/controllers/TimelineTOIController", | ||||
|     "EventEmitter" | ||||
| ], function (TimelineTOIController, EventEmitter) { | ||||
|     describe("The timeline TOI controller", function () { | ||||
|         var mockmct; | ||||
|         var mockTimerService; | ||||
|         var mockScope; | ||||
|         var controller; | ||||
|  | ||||
|         beforeEach(function () { | ||||
|             mockmct = { time: new EventEmitter() }; | ||||
|             mockmct.time.bounds = jasmine.createSpy('bounds'); | ||||
|             mockTimerService = new EventEmitter(); | ||||
|             mockTimerService.getTimer = jasmine.createSpy('getTimer'); | ||||
|             mockTimerService.hasTimer = jasmine.createSpy('hasTimer'); | ||||
|             mockTimerService.now = jasmine.createSpy('now'); | ||||
|             mockTimerService.convert = jasmine.createSpy('convert'); | ||||
|             mockScope = new EventEmitter(); | ||||
|             mockScope.$on = mockScope.on.bind(mockScope); | ||||
|             mockScope.zoomController = jasmine.createSpyObj('zoom', [ | ||||
|                 'bounds', | ||||
|                 'toPixels' | ||||
|             ]); | ||||
|             mockScope.scroll = { x: 10, width: 1000 }; | ||||
|  | ||||
|             spyOn(mockmct.time, "on").andCallThrough(); | ||||
|             spyOn(mockmct.time, "off").andCallThrough(); | ||||
|             spyOn(mockTimerService, "on").andCallThrough(); | ||||
|             spyOn(mockTimerService, "off").andCallThrough(); | ||||
|  | ||||
|             controller = new TimelineTOIController( | ||||
|                 mockmct, | ||||
|                 mockTimerService, | ||||
|                 mockScope | ||||
|             ); | ||||
|         }); | ||||
|  | ||||
|         it("reports an undefined x position initially", function () { | ||||
|             expect(controller.x()).toBeUndefined(); | ||||
|         }); | ||||
|  | ||||
|         it("listens for bounds changes", function () { | ||||
|             expect(mockmct.time.on) | ||||
|                 .toHaveBeenCalledWith('bounds', controller.bounds); | ||||
|         }); | ||||
|  | ||||
|         it("listens for timer changes", function () { | ||||
|             expect(mockTimerService.on) | ||||
|                 .toHaveBeenCalledWith('change', controller.change); | ||||
|         }); | ||||
|  | ||||
|         it("is not active", function () { | ||||
|             expect(controller.isActive()).toBe(false); | ||||
|         }); | ||||
|  | ||||
|         describe("on $destroy from scope", function () { | ||||
|             beforeEach(function () { | ||||
|                 mockScope.emit("$destroy"); | ||||
|             }); | ||||
|  | ||||
|             it("unregisters listeners", function () { | ||||
|                 expect(mockmct.time.off) | ||||
|                     .toHaveBeenCalledWith('bounds', controller.bounds); | ||||
|                 expect(mockTimerService.off) | ||||
|                     .toHaveBeenCalledWith('change', controller.change); | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         describe("when a timer and timestamp present", function () { | ||||
|             var mockTimer; | ||||
|             var testNow; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 testNow = 333221; | ||||
|                 mockScope.zoomController.toPixels | ||||
|                     .andCallFake(function (millis) { | ||||
|                         return millis * 2; | ||||
|                     }); | ||||
|                 mockTimerService.emit('change', mockTimer); | ||||
|                 mockTimerService.now.andReturn(testNow); | ||||
|             }); | ||||
|  | ||||
|             it("reports an x value from the zoomController", function () { | ||||
|                 var now = mockTimerService.now(); | ||||
|                 var expected = mockScope.zoomController.toPixels(now); | ||||
|                 expect(controller.x()).toEqual(expected); | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         describe("when follow mode is disabled", function () { | ||||
|             beforeEach(function () { | ||||
|                 mockScope.scroll.follow = false; | ||||
|             }); | ||||
|  | ||||
|             it("ignores bounds events", function () { | ||||
|                 mockmct.time.emit('bounds', { start: 0, end: 1000 }); | ||||
|                 expect(mockScope.zoomController.bounds) | ||||
|                     .not.toHaveBeenCalled(); | ||||
|             }); | ||||
|         }); | ||||
|  | ||||
|         describe("when follow mode is enabled", function () { | ||||
|             beforeEach(function () { | ||||
|                 mockScope.scroll.follow = true; | ||||
|                 mockTimerService.now.andReturn(500); | ||||
|             }); | ||||
|  | ||||
|             it("zooms on bounds events", function () { | ||||
|                 mockmct.time.emit('bounds', { start: 0, end: 1000 }); | ||||
|                 expect(mockScope.zoomController.bounds) | ||||
|                     .toHaveBeenCalled(); | ||||
|             }); | ||||
|         }); | ||||
|     }); | ||||
| }); | ||||
| @@ -1,159 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     ['../../src/directives/MCTResourceGraphDrop', '../../src/directives/SwimlaneDragConstants'], | ||||
|     function (MCTResourceGraphDrop, SwimlaneDragConstants) { | ||||
|  | ||||
|         describe("The mct-resource-graph-drop directive", function () { | ||||
|             var mockDndService, | ||||
|                 mockScope, | ||||
|                 mockElement, | ||||
|                 testAttrs, | ||||
|                 mockSwimlane, | ||||
|                 testEvent, | ||||
|                 handlers, | ||||
|                 directive; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 handlers = {}; | ||||
|  | ||||
|                 mockDndService = jasmine.createSpyObj( | ||||
|                     'dndService', | ||||
|                     ['setData', 'getData', 'removeData'] | ||||
|                 ); | ||||
|                 mockScope = jasmine.createSpyObj('$scope', ['$eval', '$apply']); | ||||
|                 mockElement = jasmine.createSpyObj('element', ['on', 'addClass', 'removeClass']); | ||||
|                 testAttrs = { mctSwimlaneDrop: "mockSwimlane" }; | ||||
|                 mockSwimlane = jasmine.createSpyObj( | ||||
|                     "swimlane", | ||||
|                     ['graph', 'toggleGraph'] | ||||
|                 ); | ||||
|  | ||||
|                 testEvent = { | ||||
|                     dataTransfer: { getData: jasmine.createSpy() }, | ||||
|                     preventDefault: jasmine.createSpy(), | ||||
|                     stopPropagation: jasmine.createSpy() | ||||
|                 }; | ||||
|  | ||||
|                 testEvent.dataTransfer.getData.andReturn('abc'); | ||||
|                 mockDndService.getData.andCallFake(function (key) { | ||||
|                     return key === SwimlaneDragConstants.TIMELINE_SWIMLANE_DRAG_TYPE ? | ||||
|                         mockSwimlane : undefined; | ||||
|                 }); | ||||
|  | ||||
|                 mockSwimlane.graph.andReturn(false); | ||||
|  | ||||
|                 directive = new MCTResourceGraphDrop(mockDndService); | ||||
|                 directive.link(mockScope, mockElement, testAttrs); | ||||
|  | ||||
|                 mockElement.on.calls.forEach(function (call) { | ||||
|                     handlers[call.args[0]] = call.args[1]; | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             it("is available as an attribute", function () { | ||||
|                 expect(directive.restrict).toEqual("A"); | ||||
|             }); | ||||
|  | ||||
|             [false, true].forEach(function (graphing) { | ||||
|                 describe("when swimlane graph is " + (graphing ? "" : "not ") + "enabled", function () { | ||||
|                     beforeEach(function () { | ||||
|                         mockSwimlane.graph.andReturn(graphing); | ||||
|                     }); | ||||
|  | ||||
|  | ||||
|                     describe("on dragover", function () { | ||||
|                         var prefix = !graphing ? "does" : "does not"; | ||||
|  | ||||
|                         beforeEach(function ()  { | ||||
|                             handlers.dragover(testEvent); | ||||
|                         }); | ||||
|  | ||||
|                         it(prefix + " add a drop-over class", function () { | ||||
|                             var expectAddClass = expect(mockElement.addClass); | ||||
|                             (!graphing ? expectAddClass : expectAddClass.not) | ||||
|                                 .toHaveBeenCalledWith('drop-over'); | ||||
|                         }); | ||||
|  | ||||
|                         it(prefix + " call $apply on scope", function () { | ||||
|                             var expectApply = expect(mockScope.$apply); | ||||
|                             (!graphing ? expectApply : expectApply.not) | ||||
|                                 .toHaveBeenCalled(); | ||||
|                         }); | ||||
|  | ||||
|                         it(prefix + " prevent default", function () { | ||||
|                             var expectPreventDefault = expect(testEvent.preventDefault); | ||||
|                             (!graphing ? expectPreventDefault : expectPreventDefault.not) | ||||
|                                 .toHaveBeenCalled(); | ||||
|                         }); | ||||
|                     }); | ||||
|  | ||||
|                     describe("on drop", function () { | ||||
|                         var prefix = !graphing ? "does" : "does not"; | ||||
|  | ||||
|                         beforeEach(function ()  { | ||||
|                             handlers.drop(testEvent); | ||||
|                         }); | ||||
|  | ||||
|                         it("removes any drop-over class", function () { | ||||
|                             expect(mockElement.removeClass) | ||||
|                                 .toHaveBeenCalledWith('drop-over'); | ||||
|                         }); | ||||
|  | ||||
|                         it(prefix + " toggle the swimlane's resource graph", function () { | ||||
|                             var expectToggle = expect(mockSwimlane.toggleGraph); | ||||
|                             (!graphing ? expectToggle : expectToggle.not) | ||||
|                                 .toHaveBeenCalled(); | ||||
|                         }); | ||||
|  | ||||
|                         it(prefix + " prevent default", function () { | ||||
|                             var expectPreventDefault = expect(testEvent.preventDefault); | ||||
|                             (!graphing ? expectPreventDefault : expectPreventDefault.not) | ||||
|                                 .toHaveBeenCalled(); | ||||
|                         }); | ||||
|                     }); | ||||
|  | ||||
|                     describe("on dragleave", function () { | ||||
|                         beforeEach(function ()  { | ||||
|                             handlers.dragleave(testEvent); | ||||
|                         }); | ||||
|  | ||||
|                         it("removes any drop-over class", function () { | ||||
|                             expect(mockElement.removeClass) | ||||
|                                 .toHaveBeenCalledWith('drop-over'); | ||||
|                         }); | ||||
|  | ||||
|                         it("calls $apply on scope", function () { | ||||
|                             expect(mockScope.$apply).toHaveBeenCalled(); | ||||
|                         }); | ||||
|  | ||||
|                         it("calls preventDefault on events", function () { | ||||
|                             expect(testEvent.preventDefault).toHaveBeenCalled(); | ||||
|                         }); | ||||
|                     }); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|         }); | ||||
|     } | ||||
| ); | ||||
| @@ -27,7 +27,7 @@ | ||||
|                          ng-required="ngRequired || compositeCtrl.isNonEmpty(ngModel[field])" | ||||
|                          ng-pattern="ngPattern" | ||||
|                          options="item.options" | ||||
|                          structure="item" | ||||
|                          structure="row" | ||||
|                          field="$index"> | ||||
|             </mct-control> | ||||
|             <span class="composite-control-label"> | ||||
|   | ||||
							
								
								
									
										16
									
								
								src/MCT.js
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/MCT.js
									
									
									
									
									
								
							| @@ -106,9 +106,9 @@ define([ | ||||
|          * | ||||
|          * @type {module:openmct.ViewRegistry} | ||||
|          * @memberof module:openmct.MCT# | ||||
|          * @name objectViews | ||||
|          * @name mainViews | ||||
|          */ | ||||
|         this.objectViews = new ViewRegistry(); | ||||
|         this.mainViews = new ViewRegistry(); | ||||
|  | ||||
|         /** | ||||
|          * Registry for views which should appear in the Inspector area. | ||||
| @@ -255,18 +255,6 @@ define([ | ||||
|             this.legacyExtension('types', legacyDefinition); | ||||
|         }.bind(this)); | ||||
|  | ||||
|         this.objectViews.getAllProviders().forEach(function (p) { | ||||
|             this.legacyExtension('views', { | ||||
|                 key: p.key, | ||||
|                 provider: p, | ||||
|                 name: p.name, | ||||
|                 cssClass: p.cssClass, | ||||
|                 description: p.description, | ||||
|                 editable: p.editable, | ||||
|                 template: '<mct-view mct-provider-key="' + p.key + '"/>' | ||||
|             }); | ||||
|         }, this); | ||||
|  | ||||
|         legacyRegistry.register('adapter', this.legacyBundle); | ||||
|         legacyRegistry.enable('adapter'); | ||||
|         /** | ||||
|   | ||||
| @@ -24,6 +24,7 @@ define([ | ||||
|     'legacyRegistry', | ||||
|     './actions/ActionDialogDecorator', | ||||
|     './capabilities/AdapterCapability', | ||||
|     './controllers/AdaptedViewController', | ||||
|     './directives/MCTView', | ||||
|     './services/Instantiate', | ||||
|     './services/MissingModelCompatibilityDecorator', | ||||
| @@ -31,11 +32,13 @@ define([ | ||||
|     './policies/AdapterCompositionPolicy', | ||||
|     './policies/AdaptedViewPolicy', | ||||
|     './runs/AlternateCompositionInitializer', | ||||
|     './runs/TimeSettingsURLHandler' | ||||
|     './runs/TimeSettingsURLHandler', | ||||
|     'text!./templates/adapted-view-template.html' | ||||
| ], function ( | ||||
|     legacyRegistry, | ||||
|     ActionDialogDecorator, | ||||
|     AdapterCapability, | ||||
|     AdaptedViewController, | ||||
|     MCTView, | ||||
|     Instantiate, | ||||
|     MissingModelCompatibilityDecorator, | ||||
| @@ -43,15 +46,15 @@ define([ | ||||
|     AdapterCompositionPolicy, | ||||
|     AdaptedViewPolicy, | ||||
|     AlternateCompositionInitializer, | ||||
|     TimeSettingsURLHandler | ||||
|     TimeSettingsURLHandler, | ||||
|     adaptedViewTemplate | ||||
| ) { | ||||
|     legacyRegistry.register('src/adapter', { | ||||
|         "extensions": { | ||||
|             "directives": [ | ||||
|                 { | ||||
|                     key: "mctView", | ||||
|                     implementation: MCTView, | ||||
|                     depends: ["openmct"] | ||||
|                     implementation: MCTView | ||||
|                 } | ||||
|             ], | ||||
|             capabilities: [ | ||||
| @@ -60,6 +63,16 @@ define([ | ||||
|                     implementation: AdapterCapability | ||||
|                 } | ||||
|             ], | ||||
|             controllers: [ | ||||
|                 { | ||||
|                     key: "AdaptedViewController", | ||||
|                     implementation: AdaptedViewController, | ||||
|                     depends: [ | ||||
|                         '$scope', | ||||
|                         'openmct' | ||||
|                     ] | ||||
|                 } | ||||
|             ], | ||||
|             services: [ | ||||
|                 { | ||||
|                     key: "instantiate", | ||||
| @@ -122,6 +135,12 @@ define([ | ||||
|                     depends: ["openmct", "$location", "$rootScope"] | ||||
|                 } | ||||
|             ], | ||||
|             views: [ | ||||
|                 { | ||||
|                     key: "adapted-view", | ||||
|                     template: adaptedViewTemplate | ||||
|                 } | ||||
|             ], | ||||
|             licenses: [ | ||||
|                 { | ||||
|                     "name": "almond", | ||||
|   | ||||
| @@ -22,12 +22,10 @@ | ||||
|  | ||||
| define([ | ||||
|     './synchronizeMutationCapability', | ||||
|     './AlternateCompositionCapability', | ||||
|     './patchViewCapability' | ||||
|     './AlternateCompositionCapability' | ||||
| ], function ( | ||||
|     synchronizeMutationCapability, | ||||
|     AlternateCompositionCapability, | ||||
|     patchViewCapability | ||||
|     AlternateCompositionCapability | ||||
| ) { | ||||
|  | ||||
|     /** | ||||
| @@ -48,9 +46,6 @@ define([ | ||||
|             capabilities.mutation = | ||||
|                 synchronizeMutationCapability(capabilities.mutation); | ||||
|         } | ||||
|         if (capabilities.view) { | ||||
|             capabilities.view = patchViewCapability(capabilities.view); | ||||
|         } | ||||
|         if (AlternateCompositionCapability.appliesTo(model, id)) { | ||||
|             capabilities.composition = function (domainObject) { | ||||
|                 return new AlternateCompositionCapability(this.$injector, domainObject); | ||||
|   | ||||
| @@ -1,60 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     'lodash' | ||||
| ], function ( | ||||
|     _ | ||||
| ) { | ||||
|  | ||||
|     function patchViewCapability(viewConstructor) { | ||||
|         return function makeCapability(domainObject) { | ||||
|             var capability = viewConstructor(domainObject); | ||||
|             var oldInvoke = capability.invoke.bind(capability); | ||||
|  | ||||
|             capability.invoke = function () { | ||||
|                 var availableViews = oldInvoke(); | ||||
|                 var newDomainObject = capability | ||||
|                     .domainObject | ||||
|                     .useCapability('adapter'); | ||||
|  | ||||
|                 return _(availableViews).map(function (v, i) { | ||||
|                     var vd = { | ||||
|                         view: v, | ||||
|                         priority: i + 100 // arbitrary to allow new views to | ||||
|                         // be defaults by returning priority less than 100. | ||||
|                     }; | ||||
|                     if (v.provider && v.provider.priority) { | ||||
|                         vd.priority = v.provider.priority(newDomainObject); | ||||
|                     } | ||||
|                     return vd; | ||||
|                 }) | ||||
|                 .sortBy('priority') | ||||
|                 .map('view') | ||||
|                 .value(); | ||||
|             }; | ||||
|             return capability; | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     return patchViewCapability; | ||||
| }); | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -20,38 +20,21 @@ | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| 
 | ||||
| define( | ||||
|     ['moment'], | ||||
|     function (moment) { | ||||
|         var NO_TIMER = "No timer being followed"; | ||||
| define([], function () { | ||||
|     function AdaptedViewController($scope, openmct) { | ||||
|         function refresh(legacyObject) { | ||||
|             if (!legacyObject) { | ||||
|                 $scope.view = undefined; | ||||
|                 return; | ||||
|             } | ||||
| 
 | ||||
|         /** | ||||
|          * Indicator that displays the active timer, as well as its | ||||
|          * current state. | ||||
|          * @implements {Indicator} | ||||
|          * @memberof platform/features/clock | ||||
|          */ | ||||
|         function FollowIndicator(timerService) { | ||||
|             this.timerService = timerService; | ||||
|             var domainObject = legacyObject.useCapability('adapter'); | ||||
|             var providers = openmct.mainViews.get(domainObject); | ||||
|             $scope.view = providers[0] && providers[0].view(domainObject); | ||||
|         } | ||||
| 
 | ||||
|         FollowIndicator.prototype.getGlyphClass = function () { | ||||
|             return ""; | ||||
|         }; | ||||
| 
 | ||||
|         FollowIndicator.prototype.getCssClass = function () { | ||||
|             return (this.timerService.getTimer()) ? "icon-timer s-status-ok" : "icon-timer"; | ||||
|         }; | ||||
| 
 | ||||
|         FollowIndicator.prototype.getText = function () { | ||||
|             var timer = this.timerService.getTimer(); | ||||
|             return (timer) ? 'Following timer ' + timer.getModel().name : NO_TIMER; | ||||
|         }; | ||||
| 
 | ||||
|         FollowIndicator.prototype.getDescription = function () { | ||||
|             return ""; | ||||
|         }; | ||||
| 
 | ||||
|         return FollowIndicator; | ||||
|         $scope.$watch('domainObject', refresh); | ||||
|     } | ||||
| ); | ||||
| 
 | ||||
|     return AdaptedViewController; | ||||
| }); | ||||
| @@ -21,23 +21,18 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([ | ||||
|     'angular', | ||||
|     './Region' | ||||
| ], function ( | ||||
|     angular, | ||||
|     Region | ||||
| ) { | ||||
|     function MCTView(openmct) { | ||||
|     function MCTView() { | ||||
|         return { | ||||
|             restrict: 'E', | ||||
|             restrict: 'A', | ||||
|             link: function (scope, element, attrs) { | ||||
|                 var provider = openmct.objectViews.getByProviderKey(attrs.mctProviderKey); | ||||
|                 var view = new provider.view(scope.domainObject.useCapability('adapter')); | ||||
|                 var domElement = element[0]; | ||||
|  | ||||
|                 view.show(domElement); | ||||
|  | ||||
|                 if (view.destroy) { | ||||
|                     scope.$on('$destroy', function () { | ||||
|                         view.destroy(domElement); | ||||
|                     }); | ||||
|                 } | ||||
|                 var region = new Region(element[0]); | ||||
|                 scope.$watch(attrs.mctView, region.show.bind(region)); | ||||
|             } | ||||
|         }; | ||||
|     } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2009-2016, United States Government | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
| @@ -20,37 +20,26 @@ | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| 
 | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
| 
 | ||||
|         /** | ||||
|          * Designates a specific timer for following. Timelines, for example, | ||||
|          * use the actively followed timer to display a time-of-interest line | ||||
|          * and interpret time conductor bounds in the Timeline's relative | ||||
|          * time frame. | ||||
|          * | ||||
|          * @implements {Action} | ||||
|          * @memberof platform/features/clock | ||||
|          * @constructor | ||||
|          * @param {ActionContext} context the context for this action | ||||
|          */ | ||||
|         function FollowTimerAction(timerService, context) { | ||||
|             var domainObject = | ||||
|                 context.domainObject && | ||||
|                 context.domainObject.useCapability('adapter'); | ||||
|             this.perform = | ||||
|                 timerService.setTimer.bind(timerService, domainObject); | ||||
|         } | ||||
| 
 | ||||
|         FollowTimerAction.appliesTo = function (context) { | ||||
|             var model = | ||||
|                 (context.domainObject && context.domainObject.getModel()) || | ||||
|                 {}; | ||||
| 
 | ||||
|             return model.type === 'timer'; | ||||
|         }; | ||||
| 
 | ||||
|         return FollowTimerAction; | ||||
| define([], function () { | ||||
|     function Region(element) { | ||||
|         this.activeView = undefined; | ||||
|         this.element = element; | ||||
|     } | ||||
| ); | ||||
| 
 | ||||
|     Region.prototype.clear = function () { | ||||
|         if (this.activeView) { | ||||
|             this.activeView.destroy(); | ||||
|             this.activeView = undefined; | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     Region.prototype.show = function (view) { | ||||
|         this.clear(); | ||||
|         this.activeView = view; | ||||
|         if (this.activeView) { | ||||
|             this.activeView.show(this.element); | ||||
|         } | ||||
|     }; | ||||
| 
 | ||||
|     return Region; | ||||
| }); | ||||
| @@ -29,9 +29,9 @@ define([], function () { | ||||
|         view, | ||||
|         legacyObject | ||||
|     ) { | ||||
|         if (view.hasOwnProperty('provider')) { | ||||
|         if (view.key === 'adapted-view') { | ||||
|             var domainObject = legacyObject.useCapability('adapter'); | ||||
|             return view.provider.canView(domainObject); | ||||
|             return this.openmct.mainViews.get(domainObject).length > 0; | ||||
|         } | ||||
|         return true; | ||||
|     }; | ||||
|   | ||||
| @@ -50,18 +50,11 @@ define([ | ||||
|         this.rootProvider = new RootObjectProvider(this.rootRegistry); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Set fallback provider, this is an internal API for legacy reasons. | ||||
|      * @private | ||||
|      */ | ||||
|     ObjectAPI.prototype.supersecretSetFallbackProvider = function (p) { | ||||
|         this.fallbackProvider = p; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * Retrieve the provider for a given identifier. | ||||
|      * @private | ||||
|      */ | ||||
|     // Retrieve the provider for a given key. | ||||
|     ObjectAPI.prototype.getProvider = function (identifier) { | ||||
|         if (identifier.key === 'ROOT') { | ||||
|             return this.rootProvider; | ||||
| @@ -142,28 +135,27 @@ define([ | ||||
|      * @returns {Promise} a promise which will resolve when the domain object | ||||
|      *          has been saved, or be rejected if it cannot be saved | ||||
|      */ | ||||
|     ObjectAPI.prototype.get = function (identifier) { | ||||
|         identifier = utils.parseKeyString(identifier); | ||||
|         var provider = this.getProvider(identifier); | ||||
|  | ||||
|         if (!provider) { | ||||
|             throw new Error('No Provider Matched'); | ||||
|         } | ||||
|     [ | ||||
|         'save', | ||||
|         'delete', | ||||
|         'get' | ||||
|     ].forEach(function (method) { | ||||
|         ObjectAPI.prototype[method] = function () { | ||||
|             var identifier = arguments[0], | ||||
|                 provider = this.getProvider(identifier); | ||||
|  | ||||
|         if (!provider.get) { | ||||
|             throw new Error('Provider does not support get!'); | ||||
|         } | ||||
|             if (!provider) { | ||||
|                 throw new Error('No Provider Matched'); | ||||
|             } | ||||
|  | ||||
|         return provider.get(identifier); | ||||
|     }; | ||||
|             if (!provider[method]) { | ||||
|                 throw new Error('Provider does not support [' + method + '].'); | ||||
|             } | ||||
|  | ||||
|     ObjectAPI.prototype.delete = function () { | ||||
|         throw new Error('Delete not implemented'); | ||||
|     }; | ||||
|  | ||||
|     ObjectAPI.prototype.save = function () { | ||||
|         throw new Error('Save not implemented'); | ||||
|     }; | ||||
|             return provider[method].apply(provider, arguments); | ||||
|         }; | ||||
|     }); | ||||
|  | ||||
|     /** | ||||
|      * Add a root-level object. | ||||
|   | ||||
| @@ -28,7 +28,7 @@ define([ | ||||
|     './timeConductor/plugin', | ||||
|     '../../example/imagery/plugin', | ||||
|     '../../platform/import-export/bundle', | ||||
|     './telemetryMean/plugin' | ||||
|     './slideshow/plugin' | ||||
| ], function ( | ||||
|     _, | ||||
|     UTCTimeSystem, | ||||
| @@ -37,7 +37,7 @@ define([ | ||||
|     TimeConductorPlugin, | ||||
|     ExampleImagery, | ||||
|     ImportExport, | ||||
|     TelemetryMean | ||||
|     Slideshow | ||||
| ) { | ||||
|     var bundleMap = { | ||||
|         CouchDB: 'platform/persistence/couch', | ||||
| @@ -60,6 +60,8 @@ define([ | ||||
|  | ||||
|     plugins.ImportExport = ImportExport; | ||||
|  | ||||
|     plugins.Slideshow = Slideshow; | ||||
|  | ||||
|     /** | ||||
|      * A tabular view showing the latest values of multiple telemetry points at | ||||
|      * once. Formatted so that labels and values are aligned. | ||||
| @@ -122,7 +124,6 @@ define([ | ||||
|     }; | ||||
|  | ||||
|     plugins.ExampleImagery = ExampleImagery; | ||||
|     plugins.TelemetryMean = TelemetryMean; | ||||
|  | ||||
|     return plugins; | ||||
| }); | ||||
|   | ||||
							
								
								
									
										93
									
								
								src/plugins/slideshow/plugin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								src/plugins/slideshow/plugin.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([], function () { | ||||
|     var SLIDESHOW_TEMPLATE = | ||||
|         '<span ng-controller="SlideshowController as slideshow">' + | ||||
|         '<mct-representation key="slideshow.key()" mct-object="slideshow.object()">' + | ||||
|         '</mct-representation></span>'; | ||||
|  | ||||
|     function SlideshowController($scope, $interval) { | ||||
|         this.composition = []; | ||||
|         this.counter = 0; | ||||
|  | ||||
|         $scope.$watch('domainObject', this.update.bind(this)); | ||||
|  | ||||
|         var interval = $interval(function () { | ||||
|             this.counter += 1; | ||||
|         }.bind(this), 4000); | ||||
|         //$scope.$on("$destroy", interval.cancel.bind(interval)); | ||||
|     } | ||||
|  | ||||
|     SlideshowController.prototype.update = function (domainObject) { | ||||
|         var composition = domainObject.useCapability("composition"); | ||||
|  | ||||
|         if (!composition) { | ||||
|             this.composition = []; | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         composition.then(function (composition) { | ||||
|             this.composition = composition; | ||||
|         }.bind(this)); | ||||
|     }; | ||||
|  | ||||
|     SlideshowController.prototype.object = function () { | ||||
|         return Array.isArray(this.composition) && this.composition.length ? | ||||
|             this.composition[this.counter % this.composition.length] : | ||||
|             undefined; | ||||
|     }; | ||||
|  | ||||
|     SlideshowController.prototype.key = function () { | ||||
|         var object = this.object(); | ||||
|         var view = object && object.useCapability('view')[0]; | ||||
|         return view && view.key; | ||||
|     }; | ||||
|  | ||||
|     return function slideshow(options) { | ||||
|         return function install(openmct) { | ||||
|             openmct.types.addType('slideshow', { | ||||
|                 name: "Slideshow", | ||||
|                 description: "A slideshow display of other objects", | ||||
|                 cssClass: 'icon-object', | ||||
|                 initialize: function (slideshow) { | ||||
|                     slideshow.composition = []; | ||||
|                 }, | ||||
|                 creatable: true | ||||
|             }); | ||||
|  | ||||
|             openmct.legacyExtension("controllers", { | ||||
|                 key: "SlideshowController", | ||||
|                 implementation: SlideshowController, | ||||
|                 depends: [ "$scope", "$interval" ] | ||||
|             }); | ||||
|  | ||||
|             openmct.legacyExtension("views", { | ||||
|                 key: "slideshow", | ||||
|                 type: "slideshow", | ||||
|                 editable: true, | ||||
|                 gestures: [ "drop" ], | ||||
|                 template: SLIDESHOW_TEMPLATE | ||||
|             }); | ||||
|         }; | ||||
|     }; | ||||
| }); | ||||
| @@ -1,76 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define(['./src/MeanTelemetryProvider'], function (MeanTelemetryProvider) { | ||||
|     var DEFAULT_SAMPLES = 10; | ||||
|  | ||||
|     function plugin() { | ||||
|         return function install(openmct) { | ||||
|             openmct.types.addType('telemetry-mean', { | ||||
|                 name: 'Telemetry Mean', | ||||
|                 description: 'Provides telemetry values that represent the mean of the last N values of a telemetry stream', | ||||
|                 creatable: true, | ||||
|                 cssClass: 'icon-telemetry', | ||||
|                 initialize: function (domainObject) { | ||||
|                     domainObject.samples = DEFAULT_SAMPLES; | ||||
|                     domainObject.telemetry = {}; | ||||
|                     domainObject.telemetry.values = | ||||
|                         openmct.time.getAllTimeSystems().map(function (timeSystem, index) { | ||||
|                             return { | ||||
|                                 key: timeSystem.key, | ||||
|                                 name: timeSystem.name, | ||||
|                                 hints: { | ||||
|                                     domain: index + 1 | ||||
|                                 } | ||||
|                             }; | ||||
|                         }); | ||||
|                     domainObject.telemetry.values.push({ | ||||
|                         key: "value", | ||||
|                         name: "Value", | ||||
|                         hints: { | ||||
|                             range: 1 | ||||
|                         } | ||||
|                     }); | ||||
|                 }, | ||||
|                 form: [ | ||||
|                     { | ||||
|                         "key": "telemetryPoint", | ||||
|                         "name": "Telemetry Point", | ||||
|                         "control": "textfield", | ||||
|                         "required": true, | ||||
|                         "cssClass": "l-input-lg" | ||||
|                     }, | ||||
|                     { | ||||
|                         "key": "samples", | ||||
|                         "name": "Samples to Average", | ||||
|                         "control": "textfield", | ||||
|                         "required": true, | ||||
|                         "cssClass": "l-input-sm" | ||||
|                     } | ||||
|                 ] | ||||
|             }); | ||||
|             openmct.telemetry.addProvider(new MeanTelemetryProvider(openmct)); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     return plugin; | ||||
| }); | ||||
| @@ -1,125 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| /*jshint latedef: nofunc */ | ||||
| /*global console */ | ||||
| define([ | ||||
|     '../../../api/objects/object-utils', | ||||
|     './TelemetryAverager' | ||||
| ], function (objectUtils, TelemetryAverager) { | ||||
|  | ||||
|     function MeanTelemetryProvider(openmct) { | ||||
|         this.openmct = openmct; | ||||
|         this.telemetryAPI = openmct.telemetry; | ||||
|         this.timeAPI = openmct.time; | ||||
|         this.objectAPI = openmct.objects; | ||||
|         this.perObjectProviders = {}; | ||||
|     } | ||||
|  | ||||
|     MeanTelemetryProvider.prototype.canProvideTelemetry = function (domainObject) { | ||||
|         return domainObject.type === 'telemetry-mean'; | ||||
|     }; | ||||
|  | ||||
|     MeanTelemetryProvider.prototype.supportsRequest = | ||||
|         MeanTelemetryProvider.prototype.supportsSubscribe = | ||||
|             MeanTelemetryProvider.prototype.canProvideTelemetry; | ||||
|  | ||||
|     MeanTelemetryProvider.prototype.subscribe = function (domainObject, callback) { | ||||
|         var wrappedUnsubscribe; | ||||
|         var unsubscribeCalled = false; | ||||
|         var objectId = objectUtils.parseKeyString(domainObject.telemetryPoint); | ||||
|         var samples = domainObject.samples; | ||||
|  | ||||
|         this.objectAPI.get(objectId) | ||||
|             .then(function (linkedDomainObject) { | ||||
|                 if (!unsubscribeCalled) { | ||||
|                     wrappedUnsubscribe = this.subscribeToAverage(linkedDomainObject, samples, callback); | ||||
|                 } | ||||
|             }.bind(this)) | ||||
|             .catch(logError); | ||||
|  | ||||
|         return function unsubscribe() { | ||||
|             unsubscribeCalled = true; | ||||
|             if (wrappedUnsubscribe !== undefined) { | ||||
|                 wrappedUnsubscribe(); | ||||
|             } | ||||
|         }; | ||||
|     }; | ||||
|  | ||||
|     MeanTelemetryProvider.prototype.subscribeToAverage = function (domainObject, samples, callback) { | ||||
|         var telemetryAverager = new TelemetryAverager(this.telemetryAPI, this.timeAPI, domainObject, samples); | ||||
|  | ||||
|         return this.telemetryAPI.subscribe(domainObject, function (telemetryDatum) { | ||||
|             var avgData = telemetryAverager.createAverageDatum(telemetryDatum); | ||||
|  | ||||
|             if (telemetryAverager.sampleCount() === samples) { | ||||
|                 callback(avgData); | ||||
|             } | ||||
|         }.bind(this)); | ||||
|     }; | ||||
|  | ||||
|     MeanTelemetryProvider.prototype.request = function (domainObject, request) { | ||||
|         var objectId = objectUtils.parseKeyString(domainObject.telemetryPoint); | ||||
|         var samples = domainObject.samples; | ||||
|  | ||||
|         return this.objectAPI.get(objectId).then(function (linkedDomainObject) { | ||||
|             return this.requestAverageTelemetry(linkedDomainObject, request, samples); | ||||
|         }.bind(this)); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     MeanTelemetryProvider.prototype.requestAverageTelemetry = function (domainObject, request, samples) { | ||||
|         var averageData = []; | ||||
|         var telemetryAverager = new TelemetryAverager(this.telemetryAPI, this.timeAPI, domainObject, samples); | ||||
|  | ||||
|         return this.telemetryAPI.request(domainObject, request).then(function (telemetryData) { | ||||
|             telemetryData.forEach(function (datum) { | ||||
|                 var avgDatum = telemetryAverager.createAverageDatum(datum); | ||||
|  | ||||
|                 if (telemetryAverager.sampleCount() === samples) { | ||||
|                     averageData.push(avgDatum); | ||||
|                 } | ||||
|             }.bind(this)); | ||||
|  | ||||
|             return averageData; | ||||
|         }.bind(this)); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     MeanTelemetryProvider.prototype.getLinkedObject = function (domainObject) { | ||||
|         var objectId = objectUtils.parseKeyString(domainObject.telemetryPoint); | ||||
|         return this.objectAPI.get(objectId); | ||||
|     }; | ||||
|  | ||||
|     function logError(error) { | ||||
|         if (error.stack) { | ||||
|             console.error(error.stack); | ||||
|         } else { | ||||
|             console.error(error); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     return MeanTelemetryProvider; | ||||
| }); | ||||
| @@ -1,460 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT Web, Copyright (c) 2014-2015, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT Web is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT Web includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| /*jshint latedef: nofunc */ | ||||
| define([ | ||||
|     "./MeanTelemetryProvider", | ||||
|     "./MockTelemetryApi" | ||||
| ], function ( | ||||
|     MeanTelemetryProvider, | ||||
|     MockTelemetryApi | ||||
| ) { | ||||
|     var RANGE_KEY = 'value'; | ||||
|  | ||||
|     describe("The Mean Telemetry Provider", function () { | ||||
|         var mockApi; | ||||
|         var meanTelemetryProvider; | ||||
|         var outstandingPromises = 0; | ||||
|         var mockDomainObject; | ||||
|         var associatedObject; | ||||
|  | ||||
|         beforeEach(function () { | ||||
|             createMockApi(); | ||||
|             setTimeSystemTo('utc'); | ||||
|             createMockObjects(); | ||||
|             meanTelemetryProvider = new MeanTelemetryProvider(mockApi); | ||||
|         }); | ||||
|  | ||||
|         it("supports telemetry-mean objects only", function () { | ||||
|             var mockTelemetryMeanObject = mockObjectWithType('telemetry-mean'); | ||||
|             var mockOtherObject = mockObjectWithType('other'); | ||||
|  | ||||
|             expect(meanTelemetryProvider.canProvideTelemetry(mockTelemetryMeanObject)).toBe(true); | ||||
|             expect(meanTelemetryProvider.canProvideTelemetry(mockOtherObject)).toBe(false); | ||||
|         }); | ||||
|  | ||||
|         describe("the subscribe function", function () { | ||||
|             var subscriptionCallback; | ||||
|  | ||||
|             beforeEach(function () { | ||||
|                 subscriptionCallback = jasmine.createSpy('subscriptionCallback'); | ||||
|             }); | ||||
|  | ||||
|             it("subscribes to telemetry for the associated object", function () { | ||||
|                 meanTelemetryProvider.subscribe(mockDomainObject); | ||||
|  | ||||
|                 expectObjectWasSubscribedTo(associatedObject); | ||||
|             }); | ||||
|  | ||||
|             it("returns a function that unsubscribes from the associated object", function () { | ||||
|                 var unsubscribe = meanTelemetryProvider.subscribe(mockDomainObject); | ||||
|  | ||||
|                 waitsFor(allPromisesToBeResolved); | ||||
|                 runs(unsubscribe); | ||||
|  | ||||
|                 expectUnsubscribeFrom(associatedObject); | ||||
|             }); | ||||
|  | ||||
|             it("returns an average only when the sample size is reached", function () { | ||||
|                 var inputTelemetry = [ | ||||
|                     {'utc': 1, 'defaultRange': 123.1231}, | ||||
|                     {'utc': 2, 'defaultRange': 321.3223}, | ||||
|                     {'utc': 3, 'defaultRange': 111.4446}, | ||||
|                     {'utc': 4, 'defaultRange': 555.2313} | ||||
|                 ]; | ||||
|  | ||||
|                 setSampleSize(5); | ||||
|                 meanTelemetryProvider.subscribe(mockDomainObject, subscriptionCallback); | ||||
|                 feedInputTelemetry(inputTelemetry); | ||||
|  | ||||
|                 expectNoAverageForTelemetry(inputTelemetry); | ||||
|             }); | ||||
|  | ||||
|             it("correctly averages a sample of five values", function () { | ||||
|                 var inputTelemetry = [ | ||||
|                     {'utc': 1, 'defaultRange': 123.1231}, | ||||
|                     {'utc': 2, 'defaultRange': 321.3223}, | ||||
|                     {'utc': 3, 'defaultRange': 111.4446}, | ||||
|                     {'utc': 4, 'defaultRange': 555.2313}, | ||||
|                     {'utc': 5, 'defaultRange': 1.1231} | ||||
|                 ]; | ||||
|                 var expectedAverages = [{ | ||||
|                     'utc': 5, 'value': 222.44888 | ||||
|                 }]; | ||||
|  | ||||
|                 setSampleSize(5); | ||||
|                 meanTelemetryProvider.subscribe(mockDomainObject, subscriptionCallback); | ||||
|                 feedInputTelemetry(inputTelemetry); | ||||
|  | ||||
|                 expectAveragesForTelemetry(expectedAverages, inputTelemetry); | ||||
|             }); | ||||
|  | ||||
|             it("correctly averages a sample of ten values", function () { | ||||
|                 var inputTelemetry = [ | ||||
|                     {'utc': 1, 'defaultRange': 123.1231}, | ||||
|                     {'utc': 2, 'defaultRange': 321.3223}, | ||||
|                     {'utc': 3, 'defaultRange': 111.4446}, | ||||
|                     {'utc': 4, 'defaultRange': 555.2313}, | ||||
|                     {'utc': 5, 'defaultRange': 1.1231}, | ||||
|                     {'utc': 6, 'defaultRange': 2323.12}, | ||||
|                     {'utc': 7, 'defaultRange': 532.12}, | ||||
|                     {'utc': 8, 'defaultRange': 453.543}, | ||||
|                     {'utc': 9, 'defaultRange': 89.2111}, | ||||
|                     {'utc': 10, 'defaultRange': 0.543} | ||||
|                 ]; | ||||
|                 var expectedAverages = [{ | ||||
|                     'utc': 10, 'value': 451.07815 | ||||
|                 }]; | ||||
|  | ||||
|                 setSampleSize(10); | ||||
|                 meanTelemetryProvider.subscribe(mockDomainObject, subscriptionCallback); | ||||
|                 feedInputTelemetry(inputTelemetry); | ||||
|  | ||||
|                 expectAveragesForTelemetry(expectedAverages, inputTelemetry); | ||||
|             }); | ||||
|  | ||||
|             it("only averages values within its sample window", function () { | ||||
|                 var inputTelemetry = [ | ||||
|                     {'utc': 1, 'defaultRange': 123.1231}, | ||||
|                     {'utc': 2, 'defaultRange': 321.3223}, | ||||
|                     {'utc': 3, 'defaultRange': 111.4446}, | ||||
|                     {'utc': 4, 'defaultRange': 555.2313}, | ||||
|                     {'utc': 5, 'defaultRange': 1.1231}, | ||||
|                     {'utc': 6, 'defaultRange': 2323.12}, | ||||
|                     {'utc': 7, 'defaultRange': 532.12}, | ||||
|                     {'utc': 8, 'defaultRange': 453.543}, | ||||
|                     {'utc': 9, 'defaultRange': 89.2111}, | ||||
|                     {'utc': 10, 'defaultRange': 0.543} | ||||
|                 ]; | ||||
|                 var expectedAverages = [ | ||||
|                     {'utc': 5, 'value': 222.44888}, | ||||
|                     {'utc': 6, 'value': 662.4482599999999}, | ||||
|                     {'utc': 7, 'value': 704.6078}, | ||||
|                     {'utc': 8, 'value': 773.02748}, | ||||
|                     {'utc': 9, 'value': 679.8234399999999}, | ||||
|                     {'utc': 10, 'value': 679.70742} | ||||
|                 ]; | ||||
|  | ||||
|                 setSampleSize(5); | ||||
|                 meanTelemetryProvider.subscribe(mockDomainObject, subscriptionCallback); | ||||
|                 feedInputTelemetry(inputTelemetry); | ||||
|  | ||||
|                 expectAveragesForTelemetry(expectedAverages, inputTelemetry); | ||||
|             }); | ||||
|             describe("given telemetry input with range values", function () { | ||||
|                 var inputTelemetry; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     inputTelemetry = [{ | ||||
|                         'utc': 1, | ||||
|                         'rangeKey': 5678, | ||||
|                         'otherKey': 9999 | ||||
|                     }]; | ||||
|                     setSampleSize(1); | ||||
|                 }); | ||||
|                 it("uses the 'rangeKey' input range, when it is the default, to calculate the average", function () { | ||||
|                     var averageTelemetryForRangeKey = [{ | ||||
|                         'utc': 1, | ||||
|                         'value': 5678 | ||||
|                     }]; | ||||
|  | ||||
|                     meanTelemetryProvider.subscribe(mockDomainObject, subscriptionCallback); | ||||
|                     mockApi.telemetry.setDefaultRangeTo('rangeKey'); | ||||
|                     feedInputTelemetry(inputTelemetry); | ||||
|  | ||||
|                     expectAveragesForTelemetry(averageTelemetryForRangeKey, inputTelemetry); | ||||
|                 }); | ||||
|  | ||||
|                 it("uses the 'otherKey' input range, when it is the default, to calculate the average", function () { | ||||
|                     var averageTelemetryForOtherKey = [{ | ||||
|                         'utc': 1, | ||||
|                         'value': 9999 | ||||
|                     }]; | ||||
|  | ||||
|                     meanTelemetryProvider.subscribe(mockDomainObject, subscriptionCallback); | ||||
|                     mockApi.telemetry.setDefaultRangeTo('otherKey'); | ||||
|                     feedInputTelemetry(inputTelemetry); | ||||
|  | ||||
|                     expectAveragesForTelemetry(averageTelemetryForOtherKey, inputTelemetry); | ||||
|  | ||||
|                 }); | ||||
|             }); | ||||
|             describe("given telemetry input with range values", function () { | ||||
|                 var inputTelemetry; | ||||
|  | ||||
|                 beforeEach(function () { | ||||
|                     inputTelemetry = [{ | ||||
|                         'utc': 1, | ||||
|                         'rangeKey': 5678, | ||||
|                         'otherKey': 9999 | ||||
|                     }]; | ||||
|                     setSampleSize(1); | ||||
|                 }); | ||||
|                 it("uses the 'rangeKey' input range, when it is the default, to calculate the average", function () { | ||||
|                     var averageTelemetryForRangeKey = [{ | ||||
|                         'utc': 1, | ||||
|                         'value': 5678 | ||||
|                     }]; | ||||
|  | ||||
|                     meanTelemetryProvider.subscribe(mockDomainObject, subscriptionCallback); | ||||
|                     mockApi.telemetry.setDefaultRangeTo('rangeKey'); | ||||
|                     feedInputTelemetry(inputTelemetry); | ||||
|  | ||||
|                     expectAveragesForTelemetry(averageTelemetryForRangeKey, inputTelemetry); | ||||
|                 }); | ||||
|  | ||||
|                 it("uses the 'otherKey' input range, when it is the default, to calculate the average", function () { | ||||
|                     var averageTelemetryForOtherKey = [{ | ||||
|                         'utc': 1, | ||||
|                         'value': 9999 | ||||
|                     }]; | ||||
|  | ||||
|                     meanTelemetryProvider.subscribe(mockDomainObject, subscriptionCallback); | ||||
|                     mockApi.telemetry.setDefaultRangeTo('otherKey'); | ||||
|                     feedInputTelemetry(inputTelemetry); | ||||
|  | ||||
|                     expectAveragesForTelemetry(averageTelemetryForOtherKey, inputTelemetry); | ||||
|                 }); | ||||
|             }); | ||||
|  | ||||
|             function feedInputTelemetry(inputTelemetry) { | ||||
|                 waitsFor(allPromisesToBeResolved); | ||||
|                 runs(function () { | ||||
|                     inputTelemetry.forEach(mockApi.telemetry.mockReceiveTelemetry); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function expectNoAverageForTelemetry(inputTelemetry) { | ||||
|                 waitsFor(allPromisesToBeResolved); | ||||
|                 runs(function () { | ||||
|                     expect(subscriptionCallback).not.toHaveBeenCalled(); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function expectAveragesForTelemetry(expectedAverages) { | ||||
|                 waitsFor(allPromisesToBeResolved); | ||||
|                 runs(function () { | ||||
|                     expectedAverages.forEach(function (averageDatum) { | ||||
|                         expect(subscriptionCallback).toHaveBeenCalledWith(averageDatum); | ||||
|                     }); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function expectObjectWasSubscribedTo(object) { | ||||
|                 waitsFor(allPromisesToBeResolved); | ||||
|                 runs(function () { | ||||
|                     expect(mockApi.telemetry.subscribe).toHaveBeenCalledWith(object, jasmine.any(Function)); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function expectUnsubscribeFrom() { | ||||
|                 waitsFor(allPromisesToBeResolved); | ||||
|                 runs(function () { | ||||
|                     expect(mockApi.telemetry.unsubscribe).toHaveBeenCalled(); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|         }); | ||||
|  | ||||
|         describe("the request function", function () { | ||||
|  | ||||
|             it("requests telemetry for the associated object", function () { | ||||
|                 meanTelemetryProvider.request(mockDomainObject); | ||||
|  | ||||
|                 expectTelemetryToBeRequestedFor(associatedObject); | ||||
|             }); | ||||
|  | ||||
|             it("returns an average only when the sample size is reached", function () { | ||||
|                 var inputTelemetry = [ | ||||
|                     {'utc': 1, 'defaultRange': 123.1231}, | ||||
|                     {'utc': 2, 'defaultRange': 321.3223}, | ||||
|                     {'utc': 3, 'defaultRange': 111.4446}, | ||||
|                     {'utc': 4, 'defaultRange': 555.2313} | ||||
|                 ]; | ||||
|                 var promiseForAverage; | ||||
|  | ||||
|                 setSampleSize(5); | ||||
|                 whenTelemetryRequestedReturn(inputTelemetry); | ||||
|                 promiseForAverage = meanTelemetryProvider.request(mockDomainObject); | ||||
|  | ||||
|                 expectEmptyResponse(promiseForAverage); | ||||
|             }); | ||||
|  | ||||
|             it("correctly averages a sample of five values", function () { | ||||
|                 var inputTelemetry = [ | ||||
|                     {'utc': 1, 'defaultRange': 123.1231}, | ||||
|                     {'utc': 2, 'defaultRange': 321.3223}, | ||||
|                     {'utc': 3, 'defaultRange': 111.4446}, | ||||
|                     {'utc': 4, 'defaultRange': 555.2313}, | ||||
|                     {'utc': 5, 'defaultRange': 1.1231} | ||||
|                 ]; | ||||
|                 var promiseForAverage; | ||||
|  | ||||
|                 setSampleSize(5); | ||||
|                 whenTelemetryRequestedReturn(inputTelemetry); | ||||
|                 promiseForAverage = meanTelemetryProvider.request(mockDomainObject); | ||||
|  | ||||
|                 expectAverageToBe(222.44888, promiseForAverage); | ||||
|             }); | ||||
|  | ||||
|             it("correctly averages a sample of ten values", function () { | ||||
|                 var inputTelemetry = [ | ||||
|                     {'utc': 1, 'defaultRange': 123.1231}, | ||||
|                     {'utc': 2, 'defaultRange': 321.3223}, | ||||
|                     {'utc': 3, 'defaultRange': 111.4446}, | ||||
|                     {'utc': 4, 'defaultRange': 555.2313}, | ||||
|                     {'utc': 5, 'defaultRange': 1.1231}, | ||||
|                     {'utc': 6, 'defaultRange': 2323.12}, | ||||
|                     {'utc': 7, 'defaultRange': 532.12}, | ||||
|                     {'utc': 8, 'defaultRange': 453.543}, | ||||
|                     {'utc': 9, 'defaultRange': 89.2111}, | ||||
|                     {'utc': 10, 'defaultRange': 0.543} | ||||
|                 ]; | ||||
|                 var promiseForAverage; | ||||
|  | ||||
|                 setSampleSize(10); | ||||
|                 whenTelemetryRequestedReturn(inputTelemetry); | ||||
|                 promiseForAverage = meanTelemetryProvider.request(mockDomainObject); | ||||
|  | ||||
|                 expectAverageToBe(451.07815, promiseForAverage); | ||||
|             }); | ||||
|  | ||||
|             it("only averages values within its sample window", function () { | ||||
|                 var inputTelemetry = [ | ||||
|                     {'utc': 1, 'defaultRange': 123.1231}, | ||||
|                     {'utc': 2, 'defaultRange': 321.3223}, | ||||
|                     {'utc': 3, 'defaultRange': 111.4446}, | ||||
|                     {'utc': 4, 'defaultRange': 555.2313}, | ||||
|                     {'utc': 5, 'defaultRange': 1.1231}, | ||||
|                     {'utc': 6, 'defaultRange': 2323.12}, | ||||
|                     {'utc': 7, 'defaultRange': 532.12}, | ||||
|                     {'utc': 8, 'defaultRange': 453.543}, | ||||
|                     {'utc': 9, 'defaultRange': 89.2111}, | ||||
|                     {'utc': 10, 'defaultRange': 0.543} | ||||
|                 ]; | ||||
|                 var promiseForAverage; | ||||
|  | ||||
|                 setSampleSize(5); | ||||
|                 whenTelemetryRequestedReturn(inputTelemetry); | ||||
|                 promiseForAverage = meanTelemetryProvider.request(mockDomainObject); | ||||
|  | ||||
|                 expectAverageToBe(679.70742, promiseForAverage); | ||||
|             }); | ||||
|  | ||||
|             function expectAverageToBe(expectedValue, promiseForAverage) { | ||||
|                 var averageData; | ||||
|  | ||||
|                 promiseForAverage.then(function (data) { | ||||
|                     averageData = data; | ||||
|                 }); | ||||
|  | ||||
|                 waitsFor(function () { | ||||
|                     return averageData !== undefined; | ||||
|                 }, 'data to return from request', 1); | ||||
|                 runs(function () { | ||||
|                     var averageDatum = averageData[averageData.length - 1]; | ||||
|                     expect(averageDatum[RANGE_KEY]).toBe(expectedValue); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function expectEmptyResponse(promiseForAverage) { | ||||
|                 var averageData; | ||||
|  | ||||
|                 promiseForAverage.then(function (data) { | ||||
|                     averageData = data; | ||||
|                 }); | ||||
|  | ||||
|                 waitsFor(function () { | ||||
|                     return averageData !== undefined; | ||||
|                 }, 'data to return from request', 1); | ||||
|                 runs(function () { | ||||
|                     expect(averageData.length).toBe(0); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             function whenTelemetryRequestedReturn(telemetry) { | ||||
|                 mockApi.telemetry.request.andReturn(resolvePromiseWith(telemetry)); | ||||
|             } | ||||
|  | ||||
|             function expectTelemetryToBeRequestedFor(object) { | ||||
|                 waitsFor(allPromisesToBeResolved); | ||||
|                 runs(function () { | ||||
|                     expect(mockApi.telemetry.request).toHaveBeenCalledWith(object, undefined); | ||||
|                 }); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         function createMockObjects() { | ||||
|             mockDomainObject = { | ||||
|                 telemetryPoint: 'someTelemetryPoint' | ||||
|             }; | ||||
|             associatedObject = {}; | ||||
|             mockApi.objects.get.andReturn(resolvePromiseWith(associatedObject)); | ||||
|         } | ||||
|  | ||||
|         function setSampleSize(sampleSize) { | ||||
|             mockDomainObject.samples = sampleSize; | ||||
|         } | ||||
|  | ||||
|         function createMockApi() { | ||||
|             mockApi = { | ||||
|                 telemetry: new MockTelemetryApi(), | ||||
|                 objects: createMockObjectApi(), | ||||
|                 time: createMockTimeApi() | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         function createMockObjectApi() { | ||||
|             return jasmine.createSpyObj('ObjectAPI', [ | ||||
|                 'get' | ||||
|             ]); | ||||
|         } | ||||
|  | ||||
|         function mockObjectWithType(type) { | ||||
|             return { | ||||
|                 type: type | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|         function resolvePromiseWith(value) { | ||||
|             outstandingPromises++; | ||||
|             return Promise.resolve(value).then(function () { | ||||
|                 outstandingPromises--; | ||||
|                 return value; | ||||
|             }); | ||||
|         } | ||||
|  | ||||
|         function allPromisesToBeResolved() { | ||||
|             return outstandingPromises === 0; | ||||
|         } | ||||
|  | ||||
|         function createMockTimeApi() { | ||||
|             return jasmine.createSpyObj("timeApi", ['timeSystem']); | ||||
|         } | ||||
|  | ||||
|         function setTimeSystemTo(timeSystemKey) { | ||||
|             mockApi.time.timeSystem.andReturn({ | ||||
|                 key: timeSystemKey | ||||
|             }); | ||||
|         } | ||||
|     }); | ||||
|  | ||||
| }); | ||||
| @@ -1,106 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| /*global jasmine, spyOn */ | ||||
| define([], function () { | ||||
|  | ||||
|     function MockTelemetryApi() { | ||||
|         this.createSpy('subscribe'); | ||||
|         this.createSpy('getMetadata'); | ||||
|  | ||||
|         this.metadata = this.createMockMetadata(); | ||||
|         this.setDefaultRangeTo('defaultRange'); | ||||
|         this.unsubscribe = jasmine.createSpy('unsubscribe'); | ||||
|         this.mockReceiveTelemetry = this.mockReceiveTelemetry.bind(this); | ||||
|     } | ||||
|  | ||||
|     MockTelemetryApi.prototype.subscribe = function () { | ||||
|         return this.unsubscribe; | ||||
|     }; | ||||
|  | ||||
|     MockTelemetryApi.prototype.getMetadata = function (object) { | ||||
|         return this.metadata; | ||||
|     }; | ||||
|  | ||||
|     MockTelemetryApi.prototype.request = jasmine.createSpy('request'); | ||||
|  | ||||
|     MockTelemetryApi.prototype.getValueFormatter = function (valueMetadata) { | ||||
|         var mockValueFormatter = jasmine.createSpyObj("valueFormatter", [ | ||||
|             "parse" | ||||
|         ]); | ||||
|  | ||||
|         mockValueFormatter.parse.andCallFake(function (value) { | ||||
|             return value[valueMetadata.key]; | ||||
|         }); | ||||
|  | ||||
|         return mockValueFormatter; | ||||
|     }; | ||||
|  | ||||
|     MockTelemetryApi.prototype.mockReceiveTelemetry = function (newTelemetryDatum) { | ||||
|         var subscriptionCallback = this.subscribe.mostRecentCall.args[1]; | ||||
|         subscriptionCallback(newTelemetryDatum); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     MockTelemetryApi.prototype.onRequestReturn = function (telemetryData) { | ||||
|         this.requestTelemetry = telemetryData; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     MockTelemetryApi.prototype.setDefaultRangeTo = function (rangeKey) { | ||||
|         var mockMetadataValue = { | ||||
|             key: rangeKey | ||||
|         }; | ||||
|         this.metadata.valuesForHints.andReturn([mockMetadataValue]); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     MockTelemetryApi.prototype.createMockMetadata = function () { | ||||
|         var mockMetadata = jasmine.createSpyObj("metadata", [ | ||||
|             'value', | ||||
|             'valuesForHints' | ||||
|         ]); | ||||
|  | ||||
|         mockMetadata.value.andCallFake(function (key) { | ||||
|             return { | ||||
|                 key: key | ||||
|             }; | ||||
|         }); | ||||
|         return mockMetadata; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     MockTelemetryApi.prototype.createSpy = function (functionName) { | ||||
|         this[functionName] = this[functionName].bind(this); | ||||
|         spyOn(this, functionName); | ||||
|         this[functionName].andCallThrough(); | ||||
|     }; | ||||
|  | ||||
|     return MockTelemetryApi; | ||||
| }); | ||||
| @@ -1,112 +0,0 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2017, United States Government | ||||
|  * as represented by the Administrator of the National Aeronautics and Space | ||||
|  * Administration. All rights reserved. | ||||
|  * | ||||
|  * Open MCT is licensed under the Apache License, Version 2.0 (the | ||||
|  * "License"); you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * http://www.apache.org/licenses/LICENSE-2.0. | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||||
|  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||||
|  * License for the specific language governing permissions and limitations | ||||
|  * under the License. | ||||
|  * | ||||
|  * Open MCT includes source code licensed under additional open source | ||||
|  * licenses. See the Open Source Licenses file (LICENSES.md) included with | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define([], function () { | ||||
|  | ||||
|     function TelemetryAverager(telemetryAPI, timeAPI, domainObject, samples) { | ||||
|         this.telemetryAPI = telemetryAPI; | ||||
|         this.timeAPI = timeAPI; | ||||
|  | ||||
|         this.domainObject = domainObject; | ||||
|         this.samples = samples; | ||||
|         this.averagingWindow = []; | ||||
|  | ||||
|         this.rangeKey = undefined; | ||||
|         this.rangeFormatter = undefined; | ||||
|         this.setRangeKeyAndFormatter(); | ||||
|  | ||||
|         // Defined dynamically based on current time system | ||||
|         this.domainKey = undefined; | ||||
|         this.domainFormatter = undefined; | ||||
|     } | ||||
|  | ||||
|     TelemetryAverager.prototype.createAverageDatum = function (telemetryDatum) { | ||||
|         this.setDomainKeyAndFormatter(); | ||||
|  | ||||
|         var timeValue = this.domainFormatter.parse(telemetryDatum); | ||||
|         var rangeValue = this.rangeFormatter.parse(telemetryDatum); | ||||
|  | ||||
|         this.averagingWindow.push(rangeValue); | ||||
|         if (this.averagingWindow.length > this.samples) { | ||||
|             this.averagingWindow.shift(); | ||||
|         } | ||||
|         var averageValue = this.calculateMean(); | ||||
|  | ||||
|         var meanDatum = {}; | ||||
|         meanDatum[this.domainKey] = timeValue; | ||||
|         meanDatum.value = averageValue; | ||||
|  | ||||
|         return meanDatum; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     TelemetryAverager.prototype.calculateMean = function () { | ||||
|         var sum = 0; | ||||
|         var i = 0; | ||||
|  | ||||
|         for (; i < this.averagingWindow.length; i++) { | ||||
|             sum += this.averagingWindow[i]; | ||||
|         } | ||||
|  | ||||
|         return sum / this.averagingWindow.length; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     TelemetryAverager.prototype.setDomainKeyAndFormatter = function () { | ||||
|         var domainKey = this.timeAPI.timeSystem().key; | ||||
|         if (domainKey !== this.domainKey) { | ||||
|             this.domainKey = domainKey; | ||||
|             this.domainFormatter = this.getFormatter(domainKey); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     TelemetryAverager.prototype.setRangeKeyAndFormatter = function () { | ||||
|         var metadatas = this.telemetryAPI.getMetadata(this.domainObject); | ||||
|         var rangeValues = metadatas.valuesForHints(['range']); | ||||
|  | ||||
|         this.rangeKey = rangeValues[0].key; | ||||
|         this.rangeFormatter = this.getFormatter(this.rangeKey); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     TelemetryAverager.prototype.getFormatter = function (key) { | ||||
|         var objectMetadata = this.telemetryAPI.getMetadata(this.domainObject); | ||||
|         var valueMetadata = objectMetadata.value(key); | ||||
|  | ||||
|         return this.telemetryAPI.getValueFormatter(valueMetadata); | ||||
|     }; | ||||
|  | ||||
|     TelemetryAverager.prototype.sampleCount = function () { | ||||
|         return this.averagingWindow.length; | ||||
|     }; | ||||
|  | ||||
|     return TelemetryAverager; | ||||
| }); | ||||
| @@ -19,7 +19,6 @@ | ||||
|  * this source code distribution or the Licensing information page available | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
| /*global console */ | ||||
|  | ||||
| define([], function () { | ||||
|     /** | ||||
| @@ -29,7 +28,7 @@ define([], function () { | ||||
|      * @memberof module:openmct | ||||
|      */ | ||||
|     function ViewRegistry() { | ||||
|         this.providers = {}; | ||||
|         this.providers = []; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @@ -40,17 +39,9 @@ define([], function () { | ||||
|      *          which can provide views of this object | ||||
|      */ | ||||
|     ViewRegistry.prototype.get = function (item) { | ||||
|         return this.getAllProviders() | ||||
|             .filter(function (provider) { | ||||
|                 return provider.canView(item); | ||||
|             }); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     ViewRegistry.prototype.getAllProviders = function () { | ||||
|         return Object.values(this.providers); | ||||
|         return this.providers.filter(function (provider) { | ||||
|             return provider.canView(item); | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
| @@ -61,22 +52,7 @@ define([], function () { | ||||
|      * @memberof module:openmct.ViewRegistry# | ||||
|      */ | ||||
|     ViewRegistry.prototype.addProvider = function (provider) { | ||||
|         var key = provider.key; | ||||
|         if (key === undefined) { | ||||
|             throw "View providers must have a unique 'key' property defined"; | ||||
|         } | ||||
|         if (this.providers[key] !== undefined) { | ||||
|             console.warn("Provider already defined for key '%s'. Provider keys must be unique.", key); | ||||
|         } | ||||
|  | ||||
|         this.providers[key] = provider; | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * @private | ||||
|      */ | ||||
|     ViewRegistry.prototype.getByProviderKey = function (key) { | ||||
|         return this.providers[key]; | ||||
|         this.providers.push(provider); | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
| @@ -115,12 +91,6 @@ define([], function () { | ||||
|      * Exposes types of views in Open MCT. | ||||
|      * | ||||
|      * @interface ViewProvider | ||||
|      * @property {string} key a unique identifier for this view | ||||
|      * @property {string} name the human-readable name of this view | ||||
|      * @property {string} [description] a longer-form description (typically | ||||
|      *           a single sentence or short paragraph) of this kind of view | ||||
|      * @property {string} [cssClass] the CSS class to apply to labels for this | ||||
|      *           view (to add icons, for instance) | ||||
|      * @memberof module:openmct | ||||
|      */ | ||||
|  | ||||
| @@ -130,28 +100,15 @@ define([], function () { | ||||
|      * When called by Open MCT, this may include additional arguments | ||||
|      * which are on the path to the object to be viewed; for instance, | ||||
|      * when viewing "A Folder" within "My Items", this method will be | ||||
|      * invoked with "A Folder" (as a domain object) as the first argument | ||||
|      * invoked with "A Folder" (as a domain object) as the first argument, | ||||
|      * and "My Items" as the second argument. | ||||
|      * | ||||
|      * @method canView | ||||
|      * @memberof module:openmct.ViewProvider# | ||||
|      * @param {module:openmct.DomainObject} domainObject the domain object | ||||
|      *        to be viewed | ||||
|      * @returns {boolean} 'true' if the view applies to the provided object, | ||||
|      *          otherwise 'false'. | ||||
|      */ | ||||
|  | ||||
|     /** | ||||
|      * Optional method determining the priority of a given view. If this | ||||
|      * function is not defined on a view provider, then a default priority | ||||
|      * of 100 will be applicable for all objects supported by this view. | ||||
|      * | ||||
|      * @method priority | ||||
|      * @memberof module:openmct.ViewProvider# | ||||
|      * @param {module:openmct.DomainObject} domainObject the domain object | ||||
|      *        to be viewed | ||||
|      * @returns {number} The priority of the view. If multiple views could apply | ||||
|      *          to an object, the view that returns the lowest number will be | ||||
|      *          the default view. | ||||
|      * @returns {boolean} true if this domain object can be viewed using | ||||
|      *          this provider | ||||
|      */ | ||||
|  | ||||
|     /** | ||||
| @@ -169,6 +126,27 @@ define([], function () { | ||||
|      * @returns {module:openmct.View} a view of this domain object | ||||
|      */ | ||||
|  | ||||
|     /** | ||||
|      * Get metadata associated with this view provider. This may be used | ||||
|      * to populate the user interface with options associated with this | ||||
|      * view provider. | ||||
|      * | ||||
|      * @method metadata | ||||
|      * @memberof module:openmct.ViewProvider# | ||||
|      * @returns {module:openmct.ViewProvider~ViewMetadata} view metadata | ||||
|      */ | ||||
|  | ||||
|     /** | ||||
|      * @typedef ViewMetadata | ||||
|      * @memberof module:openmct.ViewProvider~ | ||||
|      * @property {string} name the human-readable name of this view | ||||
|      * @property {string} key a machine-readable name for this view | ||||
|      * @property {string} [description] a longer-form description (typically | ||||
|      *           a single sentence or short paragraph) of this kind of view | ||||
|      * @property {string} cssClass the CSS class to apply to labels for this | ||||
|      *           view (to add icons, for instance) | ||||
|      */ | ||||
|  | ||||
|     return ViewRegistry; | ||||
|  | ||||
| }); | ||||
|   | ||||
| @@ -59,7 +59,7 @@ requirejs.config({ | ||||
|         "moment": "bower_components/moment/moment", | ||||
|         "moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format", | ||||
|         "moment-timezone": "bower_components/moment-timezone/builds/moment-timezone-with-data", | ||||
|         "saveAs": "bower_components/file-saver/FileSaver.min", | ||||
|         "saveAs": "bower_components/FileSaver.js/FileSaver.min", | ||||
|         "screenfull": "bower_components/screenfull/dist/screenfull.min", | ||||
|         "text": "bower_components/text/text", | ||||
|         "uuid": "bower_components/node-uuid/uuid", | ||||
|   | ||||
		Reference in New Issue
	
	Block a user