Compare commits
	
		
			44 Commits
		
	
	
		
			misc-ui-8
			...
			activity-i
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 6da0044adf | ||
|   | 76a88fc1e5 | ||
|   | 6901684124 | ||
|   | dbb5b9bb4c | ||
|   | dce20825ea | ||
|   | 5fa9925ea1 | ||
|   | d774458b17 | ||
|   | 22f464e02b | ||
|   | ef8f52769e | ||
|   | f25987cfed | ||
|   | 684dd4ff8c | ||
|   | a36b86516f | ||
|   | 99e103fd9d | ||
|   | 2224fba618 | ||
|   | b3fcbddeb7 | ||
|   | b3ababd67e | ||
|   | 0e3c5e1199 | ||
|   | d72db1ff8c | ||
|   | bade2e1678 | ||
|   | 4bd1a192ed | ||
|   | 89ab47d835 | ||
|   | 27dfb18991 | ||
|   | 9e57a661ea | ||
|   | 116e346aaf | ||
|   | 78cfdd3942 | ||
|   | a8ecdf98b5 | ||
|   | fee74883c6 | ||
|   | 2e8e6306ee | ||
|   | 7f2cc89f42 | ||
|   | 321271bd4d | ||
|   | 006e99fb07 | ||
|   | 63dc4b6253 | ||
|   | 85868f690e | ||
|   | b1f34f7cd7 | ||
|   | 8785d9a9d7 | ||
|   | 3a6e1fd301 | ||
|   | 8161e4fc89 | ||
|   | abf7654027 | ||
|   | 8fba707321 | ||
|   | 8ad5cca936 | ||
|   | 754d484501 | ||
|   | 74717b59c3 | ||
|   | ffdb19787b | ||
|   | 5dc0d8c7f8 | 
| @@ -37,7 +37,8 @@ | ||||
|                 openmct.legacyRegistry.enable.bind(openmct.legacyRegistry) | ||||
|             ); | ||||
|             openmct.install(openmct.plugins.MyItems()); | ||||
|             openmct.install(openmct.plugins.LocalStorage()); | ||||
|             // openmct.install(openmct.plugins.LocalStorage()); | ||||
|             openmct.install(openmct.plugins.CouchDB('http://127.0.0.1:5984/openmct')); | ||||
|             openmct.install(openmct.plugins.Espresso()); | ||||
|             openmct.install(openmct.plugins.Generator()); | ||||
|             openmct.install(openmct.plugins.ExampleImagery()); | ||||
| @@ -68,6 +69,7 @@ | ||||
|                 ] | ||||
|             })); | ||||
|             openmct.install(openmct.plugins.SummaryWidget()); | ||||
|             openmct.install(openmct.plugins.ActivityModes()); | ||||
|             openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0}); | ||||
|             openmct.time.timeSystem('utc'); | ||||
|             openmct.start(); | ||||
|   | ||||
| @@ -49,7 +49,8 @@ requirejs.config({ | ||||
|         "d3-format": "node_modules/d3-format/build/d3-format.min", | ||||
|         "d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min", | ||||
|         "d3-time": "node_modules/d3-time/build/d3-time.min", | ||||
|         "d3-time-format": "node_modules/d3-time-format/build/d3-time-format.min" | ||||
|         "d3-time-format": "node_modules/d3-time-format/build/d3-time-format.min", | ||||
|         "d3-dsv": "node_modules/d3-dsv/build/d3-dsv.min" | ||||
|     }, | ||||
|     "shim": { | ||||
|         "angular": { | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
|     "d3-collection": "1.0.x", | ||||
|     "d3-color": "1.0.x", | ||||
|     "d3-format": "1.2.x", | ||||
|     "d3-dsv": "^1.0.8", | ||||
|     "d3-interpolate": "1.1.x", | ||||
|     "d3-scale": "1.0.x", | ||||
|     "d3-selection": "1.3.x", | ||||
|   | ||||
| @@ -204,7 +204,10 @@ define([ | ||||
|                         "composition": [], | ||||
|                         "start": { | ||||
|                             "timestamp": 0 | ||||
|                         } | ||||
|                         }, | ||||
|                         "activityStart": {}, | ||||
|                         "activityDuration": {}, | ||||
|                         "activityEnd": {} | ||||
|                     } | ||||
|                 }, | ||||
|                 { | ||||
| @@ -341,7 +344,7 @@ define([ | ||||
|                                         "cssClass": "icon-plot-resource", | ||||
|                                         "description": "Graph Resource Utilization", | ||||
|                                         "control": "button", | ||||
|                                         "method": "toggleGraph" | ||||
|                                         "method": "test" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         "cssClass": "icon-activity-mode", | ||||
| @@ -374,7 +377,36 @@ define([ | ||||
|                                         "description": "Edit Properties...", | ||||
|                                         "control": "button", | ||||
|                                         "method": "properties" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         "cssClass": "icon-duplicate", | ||||
|                                         "description": "Make copies of activities", | ||||
|                                         "control": "dialog-button", | ||||
|                                         "dialog": { | ||||
|                                             "control": "textfield", | ||||
|                                             "name": "Number of copies (1 to 5)", | ||||
|                                             "cssClass": "l-input-sm numeric" | ||||
|                                         }, | ||||
|                                         "property": "makeCopies" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         "cssClass": "icon-layers", | ||||
|                                         "description": "Fragment Activity", | ||||
|                                         "control": "dialog-button", | ||||
|                                         "dialog": { | ||||
|                                             "control": "textfield", | ||||
|                                             "name": "Number of fragments (2 to 5)", | ||||
|                                             "cssClass": "l-input-sm numeric" | ||||
|                                         }, | ||||
|                                         "property": "fragment" | ||||
|                                     }, | ||||
|                                     { | ||||
|                                         "cssClass": "icon-resync", | ||||
|                                         "description": "Update Duration from imported activity", | ||||
|                                         "control": "button", | ||||
|                                         "method": "updateDuration" | ||||
|                                     } | ||||
|  | ||||
|                                 ] | ||||
|                             }, | ||||
|                             { | ||||
| @@ -464,7 +496,8 @@ define([ | ||||
|                         "$scope", | ||||
|                         "$q", | ||||
|                         "objectLoader", | ||||
|                         "TIMELINE_MINIMUM_DURATION" | ||||
|                         "TIMELINE_MINIMUM_DURATION", | ||||
|                         "openmct" | ||||
|                     ] | ||||
|                 }, | ||||
|                 { | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
|      ng-click="$event.stopPropagation()" | ||||
|      ng-controller="TimelineController as timelineController"> | ||||
|  | ||||
| <mct-split-pane anchor="left" class="abs" position="pane.x"> | ||||
| <mct-split-pane anchor="left" class="abs" position="pane.x" alias="timelineCenter"> | ||||
|     <!-- LEFT PANE: TABULAR AND RESOURCE LEGEND AREAS --> | ||||
|     <mct-split-pane anchor="bottom" | ||||
|                     position="pane.y" | ||||
|   | ||||
| @@ -25,7 +25,7 @@ | ||||
|  */ | ||||
| define({ | ||||
|     // Pixel width of start/end handles | ||||
|     HANDLE_WIDTH: 32, | ||||
|     HANDLE_WIDTH: 16, | ||||
|     // Pixel tolerance for snapping behavior | ||||
|     SNAP_WIDTH: 16 | ||||
| }); | ||||
|   | ||||
| @@ -21,27 +21,56 @@ | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| define( | ||||
|     [], | ||||
|     function () { | ||||
|  | ||||
|     ['EventEmitter'], | ||||
|     function (EventEmitter) { | ||||
|         /** | ||||
|          * Describes the time span of an activity object. | ||||
|          * @param model the activity's object model | ||||
|          */ | ||||
|         function ActivityTimespan(model, mutation) { | ||||
|         function ActivityTimespan(model, mutation, parent) { | ||||
|             var parentTimelineModel = parent.getModel(), | ||||
|                 parentMutation = parent.getCapability('mutation'); | ||||
|  | ||||
|             function getTimelineActivityStart(domainObjectModel) { | ||||
|                 if (domainObjectModel.activityStart && domainObjectModel.activityStart[model.id]) { | ||||
|                     return domainObjectModel.activityStart[model.id]; | ||||
|                 } else { | ||||
|                     return model.start.timestamp; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             function getTimelineActivityDuration(domainObjectModel) { | ||||
|                 if (domainObjectModel.activityDuration && domainObjectModel.activityDuration[model.id]) { | ||||
|                     return domainObjectModel.activityDuration[model.id]; | ||||
|                 } else { | ||||
|                     return model.duration.timestamp; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             function getTimelineActivityEnd(domainObjectModel) { | ||||
|                 if (domainObjectModel.activityEnd && domainObjectModel.activityEnd[model.id]) { | ||||
|                     return domainObjectModel.activityEnd[model.id]; | ||||
|                 } else { | ||||
|                     return getTimelineActivityStart(parentTimelineModel) + getTimelineActivityDuration(parentTimelineModel); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             // Get the start time for this timeline | ||||
|             function getStart() { | ||||
|                 return model.start.timestamp; | ||||
|                 return getTimelineActivityStart(parentTimelineModel); | ||||
|             } | ||||
|  | ||||
|             // Get the end time for this timeline | ||||
|             function getEnd() { | ||||
|                 return model.start.timestamp + model.duration.timestamp; | ||||
|                 return getTimelineActivityEnd(parentTimelineModel); | ||||
|             } | ||||
|  | ||||
|             // Get the duration of this timeline | ||||
|             function getDuration() { | ||||
|                 return model.duration.timestamp; | ||||
|             function getDuration(flag) { | ||||
|                 if (flag === 'model') { | ||||
|                     return model.duration.timestamp; | ||||
|                 } | ||||
|                 return getTimelineActivityDuration(parentTimelineModel); | ||||
|             } | ||||
|  | ||||
|             // Get the epoch used by this timeline | ||||
| @@ -51,27 +80,36 @@ define( | ||||
|  | ||||
|             // Set the start time associated with this object | ||||
|             function setStart(value) { | ||||
|                 var end = getEnd(); | ||||
|                 mutation.mutate(function (m) { | ||||
|                     m.start.timestamp = Math.max(value, 0); | ||||
|                     // Update duration to keep end time | ||||
|                     m.duration.timestamp = Math.max(end - value, 0); | ||||
|                 }, model.modified); | ||||
|  | ||||
|                 parentMutation.mutate(function (m) { | ||||
|                     if (!m.activityStart) { | ||||
|                         m.activityStart = {}; | ||||
|                     } | ||||
|  | ||||
|                     m.activityStart[model.id] = Math.max(value, 0); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             // Set the duration associated with this object | ||||
|             function setDuration(value) { | ||||
|                 mutation.mutate(function (m) { | ||||
|                     m.duration.timestamp = Math.max(value, 0); | ||||
|                 }, model.modified); | ||||
|                 parentMutation.mutate(function (m) { | ||||
|                     if (!m.activityDuration) { | ||||
|                         m.activityDuration = {}; | ||||
|                     } | ||||
|  | ||||
|                     m.activityDuration[model.id] = Math.max(value, 0); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             // Set the end time associated with this object | ||||
|             function setEnd(value) { | ||||
|                 var start = getStart(); | ||||
|                 mutation.mutate(function (m) { | ||||
|                     m.duration.timestamp = Math.max(value - start, 0); | ||||
|                 }, model.modified); | ||||
|                 parentMutation.mutate(function (m) { | ||||
|                     if (!m.activityEnd) { | ||||
|                         m.activityEnd = {}; | ||||
|                     } | ||||
|  | ||||
|                     m.activityEnd[model.id] = Math.max(value, 0); | ||||
|                 }); | ||||
|             } | ||||
|  | ||||
|             return { | ||||
| @@ -110,7 +148,15 @@ define( | ||||
|                  * start and end times. | ||||
|                  * @returns {string} the epoch | ||||
|                  */ | ||||
|                 getEpoch: getEpoch | ||||
|                 getEpoch: getEpoch, | ||||
|  | ||||
|                 getModel: function () { | ||||
|                     return model; | ||||
|                 }, | ||||
|  | ||||
|                 getParent: function () { | ||||
|                     return parent; | ||||
|                 } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -32,11 +32,15 @@ define( | ||||
|          * @param {DomainObject} domainObject the Activity | ||||
|          */ | ||||
|         function ActivityTimespanCapability($q, domainObject) { | ||||
|  | ||||
|             var parent = domainObject.getCapability('context').parentObject; | ||||
|  | ||||
|             // Promise time span | ||||
|             function promiseTimeSpan() { | ||||
|                 return $q.when(new ActivityTimespan( | ||||
|                     domainObject.getModel(), | ||||
|                     domainObject.getCapability('mutation') | ||||
|                     domainObject.getCapability('mutation'), | ||||
|                     parent | ||||
|                 )); | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -36,11 +36,12 @@ define( | ||||
|          * Controller for the Timeline view. | ||||
|          * @constructor | ||||
|          */ | ||||
|         function TimelineController($scope, $q, objectLoader, MINIMUM_DURATION) { | ||||
|         function TimelineController($scope, $q, objectLoader, MINIMUM_DURATION, openmct) { | ||||
|             var swimlanePopulator = new TimelineSwimlanePopulator( | ||||
|                     objectLoader, | ||||
|                     $scope.configuration || {}, | ||||
|                     $scope.selection | ||||
|                     $scope.selection, | ||||
|                     openmct | ||||
|                 ), | ||||
|                 graphPopulator = new TimelineGraphPopulator($q), | ||||
|                 dragPopulator = new TimelineDragPopulator(objectLoader); | ||||
|   | ||||
| @@ -51,7 +51,6 @@ define( | ||||
|                 handles: function (domainObject) { | ||||
|                     var type = domainObject.getCapability('type'), | ||||
|                         id = domainObject.getId(); | ||||
|  | ||||
|                     // Instantiate a handle | ||||
|                     function instantiate(Handle) { | ||||
|                         return new Handle( | ||||
|   | ||||
| @@ -115,11 +115,13 @@ define( | ||||
|                     var timespan = timespans[toId(id)]; | ||||
|                     // Use as setter if argument is present | ||||
|                     if ((typeof value === 'number') && timespan) { | ||||
|                         // Set the start (ensuring that it's non-negative, | ||||
|                         // Set the start and duration(ensuring that it's non-negative, | ||||
|                         // and not after the end time.) | ||||
|                         timespan.setStart( | ||||
|                             Math.min(Math.max(value, 0), timespan.getEnd()) | ||||
|                         ); | ||||
|                         timespan.setDuration(timespan.getEnd() - Math.min(Math.max(value, 0))); | ||||
|  | ||||
|                         // Mark as dirty for subsequent persistence | ||||
|                         dirty[toId(id)] = true; | ||||
|                     } | ||||
| @@ -140,10 +142,12 @@ define( | ||||
|                     var timespan = timespans[toId(id)]; | ||||
|                     // Use as setter if argument is present | ||||
|                     if ((typeof value === 'number') && timespan) { | ||||
|                         // Set the end (ensuring it doesn't precede start) | ||||
|                         // Set the end and duration (ensuring it doesn't precede start) | ||||
|                         timespan.setEnd( | ||||
|                             Math.max(value, timespan.getStart()) | ||||
|                         ); | ||||
|                         timespan.setDuration(Math.max(value, timespan.getStart()) - timespan.getStart()); | ||||
|  | ||||
|                         // Mark as dirty for subsequent persistence | ||||
|                         dirty[toId(id)] = true; | ||||
|                     } | ||||
| @@ -198,9 +202,12 @@ define( | ||||
|                             // own adjustments | ||||
|                             start = timespan.getStart(); | ||||
|                             end = timespan.getEnd(); | ||||
|                             // Update start, then end | ||||
|  | ||||
|                             // Update duration, start, then end | ||||
|                             timespan.setDuration(end - start); | ||||
|                             timespan.setStart(start + delta); | ||||
|                             timespan.setEnd(end + delta); | ||||
|  | ||||
|                             // Mark as dirty for subsequent persistence | ||||
|                             dirty[toId(spanId)] = true; | ||||
|                         } | ||||
|   | ||||
| @@ -68,7 +68,6 @@ define( | ||||
|                     chooseEnd = diffEnd > 0; | ||||
|                 } | ||||
|                 // Start is chosen if diffEnd didn't snap, or nothing snapped | ||||
|  | ||||
|                 // Our delta is relative to our initial state, but | ||||
|                 // dragHandler.move is relative to current state, so whichever | ||||
|                 // end we're snapping to, we need to compute a delta | ||||
|   | ||||
| @@ -39,7 +39,7 @@ define( | ||||
|          * @param configuration the view's configuration object | ||||
|          * @param {TimelineSwimlane} parent the parent swim lane (if any) | ||||
|          */ | ||||
|         function TimelineSwimlane(domainObject, assigner, configuration, parent, index) { | ||||
|         function TimelineSwimlane(domainObject, assigner, configuration, parent, index, openmct) { | ||||
|             var id = domainObject.getId(), | ||||
|                 highlight = false, // Drop highlight (middle) | ||||
|                 highlightBottom = false, // Drop highlight (lower) | ||||
| @@ -47,13 +47,93 @@ define( | ||||
|                 depth = parent ? (parent.depth + 1) : 0, | ||||
|                 timespan, | ||||
|                 path = (!parent || !parent.parent) ? "" : parent.path + | ||||
|                         parent.domainObject.getModel().name + " > "; | ||||
|                         parent.domainObject.getModel().name + " > ", | ||||
|                 instantiate = openmct.$injector.get("instantiate"), | ||||
|                 copy = 1; | ||||
|  | ||||
|             // Look up timespan for this object | ||||
|             domainObject.useCapability('timespan').then(function (t) { | ||||
|                 timespan = t; | ||||
|             }); | ||||
|  | ||||
|             function makeCopies(input) { | ||||
|                 if (input !== undefined) { | ||||
|                     var number = Number(input); | ||||
|  | ||||
|                     if (!isNaN(number)) { | ||||
|  | ||||
|                         if (number >= 1 && number <= 5) { | ||||
|                             var parentComposition = timespan.getParent().getCapability('composition'), | ||||
|                                 timespanModel = timespan.getModel(); | ||||
|  | ||||
|                             for (var i = 1; i <= number; i++) { | ||||
|                                 var activityId = timespanModel.id + '-copy-' + copy, | ||||
|                                     activityModel = { | ||||
|                                         name: timespanModel.name + ' Copy ' + copy, | ||||
|                                         start: {timestamp: timespan.getStart(), epoch: "SET"}, | ||||
|                                         duration: {timestamp: timespan.getDuration(), epoch: "SET"}, | ||||
|                                         type: 'activity', | ||||
|                                         relationships: timespanModel.relationships, | ||||
|                                         id: activityId | ||||
|                                     }, | ||||
|                                     activityInstance = instantiate(activityModel); | ||||
|  | ||||
|                                 activityInstance.getCapability('location').setPrimaryLocation(timespan.getParent().model.id); | ||||
|  | ||||
|                                 parentComposition.add(activityInstance); | ||||
|                                 copy++; | ||||
|                             } | ||||
|                         } else { | ||||
|                             window.alert("Please enter a Number between 1 and 5"); | ||||
|                         } | ||||
|                     } else { | ||||
|                         window.alert("Please enter a Number"); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             function fragment(input) { | ||||
|  | ||||
|                 if (input !== undefined) { | ||||
|                     var number = Number(input), | ||||
|                         frag = 1; | ||||
|  | ||||
|                     if (!isNaN(number)) { | ||||
|  | ||||
|                         if (number >= 2 && number <= 5) { | ||||
|                             var parentComposition = timespan.getParent().getCapability('composition'), | ||||
|                                 timespanModel = timespan.getModel(), | ||||
|                                 duration = (timespan.getEnd() - timespan.getStart()) / number; | ||||
|  | ||||
|                             timespan.setDuration(duration); | ||||
|                             timespan.setEnd(timespan.getStart() + duration); | ||||
|  | ||||
|                             for (var i = 1; i < number; i++) { | ||||
|                                 var activityId = timespanModel.id + '-fragment-' + frag, | ||||
|                                     activityModel = { | ||||
|                                         name: timespanModel.name + ' Fragment ' + frag, | ||||
|                                         start: {timestamp: timespan.getStart(), epoch: "SET"}, | ||||
|                                         duration: {timestamp: duration, epoch: "SET"}, | ||||
|                                         type: 'activity', | ||||
|                                         relationships: timespanModel.relationships, | ||||
|                                         id: activityId | ||||
|                                     }, | ||||
|                                     activityInstance = instantiate(activityModel); | ||||
|  | ||||
|                                 activityInstance.getCapability('location').setPrimaryLocation(timespan.getParent().model.id); | ||||
|  | ||||
|                                 parentComposition.add(activityInstance); | ||||
|                                 frag++; | ||||
|                             } | ||||
|                         } else { | ||||
|                             window.alert("Please enter a Number between 2 and 5"); | ||||
|                         } | ||||
|                     } else { | ||||
|                         window.alert("Please enter a Number"); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             return { | ||||
|                 /** | ||||
|                  * Check if this swimlane is currently visible. (That is, | ||||
| @@ -155,6 +235,15 @@ define( | ||||
|                 timespan: function () { | ||||
|                     return timespan; | ||||
|                 }, | ||||
|                 updateDuration: function () { | ||||
|                     var duration = timespan.getDuration('model'), | ||||
|                         start = timespan.getStart(); | ||||
|  | ||||
|                     timespan.setDuration(duration); | ||||
|                     timespan.setEnd(start + duration); | ||||
|                 }, | ||||
|                 makeCopies: makeCopies, | ||||
|                 fragment: fragment, | ||||
|                 // Expose domain object, expansion state, indentation depth | ||||
|                 domainObject: domainObject, | ||||
|                 expanded: true, | ||||
|   | ||||
| @@ -39,7 +39,7 @@ define( | ||||
|          * timeline view. | ||||
|          * @constructor | ||||
|          */ | ||||
|         function TimelineSwimlanePopulator(objectLoader, configuration, selection) { | ||||
|         function TimelineSwimlanePopulator(objectLoader, configuration, selection, openmct) { | ||||
|             var swimlanes = [], | ||||
|                 start = Number.POSITIVE_INFINITY, | ||||
|                 end = Number.NEGATIVE_INFINITY, | ||||
| @@ -72,7 +72,8 @@ define( | ||||
|                         assigner, | ||||
|                         configuration, | ||||
|                         parent, | ||||
|                         index || 0 | ||||
|                         index || 0, | ||||
|                         openmct | ||||
|                     ), selection); | ||||
|                     // Track start & end times of this domain object | ||||
|                     domainObject.useCapability('timespan').then(trackStartEnd); | ||||
|   | ||||
							
								
								
									
										31
									
								
								src/plugins/activityModes/plugin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/plugins/activityModes/plugin.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| define([ | ||||
|     './src/actions/activityModesImportAction', | ||||
|     './src/policies/ActionPolicy' | ||||
| ], | ||||
| function (ActivityModes, ActionPolicy) { | ||||
|     function plugin() { | ||||
|  | ||||
|         return function install(openmct) { | ||||
|  | ||||
|             openmct.legacyExtension('actions', { | ||||
|                 key: "import-csv", | ||||
|                 category: ["contextual"], | ||||
|                 implementation: ActivityModes, | ||||
|                 cssClass: "major icon-import", | ||||
|                 name: "Import Activity Definitions from CSV", | ||||
|                 description: "Import activities from a CSV file", | ||||
|                 depends: [ | ||||
|                     "dialogService", | ||||
|                     "openmct" | ||||
|                 ] | ||||
|             }); | ||||
|  | ||||
|             openmct.legacyExtension('policies', { | ||||
|                 category: 'action', | ||||
|                 implementation: ActionPolicy | ||||
|             }); | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     return plugin; | ||||
| }); | ||||
| @@ -0,0 +1,172 @@ | ||||
| define(['d3-dsv'], function (d3Dsv) { | ||||
|  | ||||
|     function ActivityModesImportAction(dialogService, openmct, context) { | ||||
|         this.dialogService = dialogService; | ||||
|         this.openmct = openmct; | ||||
|         this.context = context; | ||||
|         this.parent = this.context.domainObject; | ||||
|         this.instantiate = this.openmct.$injector.get("instantiate"); | ||||
|         this.objectService = this.openmct.$injector.get("objectService").objectService; | ||||
|         this.populateActivities = this.populateActivities.bind(this); | ||||
|     } | ||||
|  | ||||
|     ActivityModesImportAction.prototype.perform = function () { | ||||
|         this.parentId = this.parent.getId(); | ||||
|  | ||||
|         this.dialogService.getUserInput(this.getFormModel(), function () {}) | ||||
|         .then(function (form) { | ||||
|             if (form.selectFile.name.slice(-3) !== 'csv') { | ||||
|                 this.displayError(); | ||||
|             } | ||||
|  | ||||
|             this.csvParse(form.selectFile.body).then(this.populateActivities); | ||||
|         }.bind(this)); | ||||
|     }; | ||||
|  | ||||
|     ActivityModesImportAction.prototype.csvParse = function (csvString) { | ||||
|         return new Promise(function (resolve, reject) { | ||||
|             var parsedObject = d3Dsv.csvParse(csvString); | ||||
|  | ||||
|             return parsedObject ? resolve(parsedObject) : reject('Could not parse provided file'); | ||||
|         }); | ||||
|     }; | ||||
|  | ||||
|     ActivityModesImportAction.prototype.populateActivities = function (csvObjects) { | ||||
|         this.parentComposition = this.parent.getCapability("composition"); | ||||
|         this.blockingDialog = this.showBlockingMessage(); | ||||
|  | ||||
|         var activitiesObjects = {}, | ||||
|             activityModesObjects = {}; | ||||
|  | ||||
|         csvObjects.forEach(function (activity, index) { | ||||
|             var newActivity = {}, | ||||
|                 newActivityMode = {}, | ||||
|                 duration = !isNaN(Number(activity.duration)) ? 1000 * Number(activity.duration) : 0; | ||||
|  | ||||
|             newActivity.name = activity.name; | ||||
|             newActivity.id = activity.id ? ('activity-' + activity.id) : ('activity-' + index + '-' + this.parentId); | ||||
|             newActivity.start = {timestamp: 0, epoch: "SET"}; | ||||
|             newActivity.duration = {timestamp: duration, epoch: "SET"}; | ||||
|             newActivity.type = "activity"; | ||||
|             newActivity.composition = []; | ||||
|             newActivity.relationships = {modes: []}; | ||||
|  | ||||
|             newActivityMode.name = activity.name + ' Resources'; | ||||
|             newActivityMode.id = activity.id ? ('activity-mode-' + activity.id) : ('activity-mode-' + index + '-' + this.parentId); | ||||
|             newActivityMode.resources = {comms: Number(activity.comms) || 0, power: Number(activity.power) || 0}; | ||||
|             newActivityMode.type = 'mode'; | ||||
|  | ||||
|             newActivity.relationships.modes.push(newActivityMode.id); | ||||
|  | ||||
|             activitiesObjects[newActivity.id] = newActivity; | ||||
|             activityModesObjects[newActivityMode.id] = newActivityMode; | ||||
|         }.bind(this)); | ||||
|  | ||||
|         this.instantiateActivityModes(activityModesObjects); | ||||
|         this.instantiateActivities(activitiesObjects); | ||||
|     }; | ||||
|  | ||||
|     ActivityModesImportAction.prototype.instantiateActivityModes = function (activityModesObjects) { | ||||
|         var activityModesArray = Object.keys(activityModesObjects); | ||||
|  | ||||
|         this.objectService.getObjects(activityModesArray).then( | ||||
|             function (previousActivityModes) { | ||||
|                 activityModesArray.forEach(function (activityModeId) { | ||||
|                     previousActivityModes[activityModeId].getCapability('mutation').mutate(function (prev) { | ||||
|                         var activityMode = activityModesObjects[activityModeId]; | ||||
|  | ||||
|                         prev.name = activityMode.name; | ||||
|                         prev.resources = activityMode.resources; | ||||
|                         prev.type = activityMode.type; | ||||
|                         prev.id = activityMode.id; | ||||
|                     }); | ||||
|                 }); | ||||
|             } | ||||
|         ); | ||||
|     }; | ||||
|  | ||||
|     ActivityModesImportAction.prototype.instantiateActivities = function (activitiesObjects) { | ||||
|         var activityObjectArray = Object.keys(activitiesObjects); | ||||
|  | ||||
|         this.objectService.getObjects(activityObjectArray).then( | ||||
|             function (objects) { | ||||
|                 activityObjectArray.forEach(function (activityId, index) { | ||||
|                     var activity = activitiesObjects[activityId]; | ||||
|  | ||||
|                     objects[activityId].getCapability('mutation').mutate(function (prevActivity) { | ||||
|                         prevActivity.name = activity.name; | ||||
|                         prevActivity.start = activity.start; | ||||
|                         prevActivity.duration = activity.duration; | ||||
|                         prevActivity.type = activity.type; | ||||
|                         prevActivity.composition = activity.composition; | ||||
|                         prevActivity.relationships = activity.relationships; | ||||
|                         prevActivity.id = activity.id; | ||||
|                     }); | ||||
|  | ||||
|                     objects[activityId].getCapability('location').setPrimaryLocation(this.parentId); | ||||
|  | ||||
|                     if ((index === (activityObjectArray.length - 1)) && this.blockingDialog) { | ||||
|                         this.blockingDialog.dismiss(); | ||||
|                     } | ||||
|                 }.bind(this)); | ||||
|  | ||||
|                 this.parentComposition.domainObject.getCapability('mutation').mutate(function (parentComposition) { | ||||
|                     parentComposition.composition = activityObjectArray; | ||||
|                 }); | ||||
|             }.bind(this) | ||||
|         ); | ||||
|     }; | ||||
|  | ||||
|     ActivityModesImportAction.prototype.showBlockingMessage = function () { | ||||
|         var model = { | ||||
|             title: "Importing", | ||||
|             actionText:  "Importing Activities from CSV", | ||||
|             severity: "info", | ||||
|             unknownProgress: true | ||||
|         }; | ||||
|  | ||||
|         return this.dialogService.showBlockingMessage(model); | ||||
|     }; | ||||
|  | ||||
|     ActivityModesImportAction.prototype.displayError = function () { | ||||
|         var dialog, | ||||
|         perform = this.perform.bind(this), | ||||
|         model = { | ||||
|             title: "Invalid File", | ||||
|             actionText:  "The selected file was not a valid CSV file", | ||||
|             severity: "error", | ||||
|             options: [ | ||||
|                 { | ||||
|                     label: "Ok", | ||||
|                     callback: function () { | ||||
|                         dialog.dismiss(); | ||||
|                         perform(); | ||||
|                     } | ||||
|                 } | ||||
|             ] | ||||
|         }; | ||||
|         dialog = this.dialogService.showBlockingMessage(model); | ||||
|     }; | ||||
|  | ||||
|     ActivityModesImportAction.prototype.getFormModel = function () { | ||||
|         return { | ||||
|             name: 'Import activities from CSV', | ||||
|             sections: [ | ||||
|                 { | ||||
|                     name: 'Import A File', | ||||
|                     rows: [ | ||||
|                         { | ||||
|                             name: 'Select File', | ||||
|                             key: 'selectFile', | ||||
|                             control: 'file-input', | ||||
|                             required: true, | ||||
|                             text: 'Select File' | ||||
|                         } | ||||
|                     ] | ||||
|                 } | ||||
|             ] | ||||
|         }; | ||||
|     }; | ||||
|  | ||||
|     return ActivityModesImportAction; | ||||
| }); | ||||
							
								
								
									
										46
									
								
								src/plugins/activityModes/src/policies/ActionPolicy.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/plugins/activityModes/src/policies/ActionPolicy.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /***************************************************************************** | ||||
|  * Open MCT, Copyright (c) 2014-2018, 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 ActionPolicy() { | ||||
|         } | ||||
|  | ||||
|         ActionPolicy.prototype.allow = function (action, context) { | ||||
|             var key = action.getMetadata().key, | ||||
|                 domainObjectType = | ||||
|                 context.domainObject ? context.domainObject.getModel().type : ''; | ||||
|  | ||||
|             if (key === 'import-csv') { | ||||
|                 if (domainObjectType === 'folder') { | ||||
|                     return true; | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         }; | ||||
|  | ||||
|         return ActionPolicy; | ||||
|     } | ||||
| ); | ||||
| @@ -30,6 +30,7 @@ define([ | ||||
|     '../../platform/import-export/bundle', | ||||
|     './summaryWidget/plugin', | ||||
|     './URLIndicatorPlugin/URLIndicatorPlugin', | ||||
|     './activityModes/plugin', | ||||
|     './telemetryMean/plugin', | ||||
|     './plot/plugin', | ||||
|     './staticRootPlugin/plugin' | ||||
| @@ -43,6 +44,7 @@ define([ | ||||
|     ImportExport, | ||||
|     SummaryWidget, | ||||
|     URLIndicatorPlugin, | ||||
|     ActivityModes, | ||||
|     TelemetryMean, | ||||
|     PlotPlugin, | ||||
|     StaticRootPlugin | ||||
| @@ -137,6 +139,7 @@ define([ | ||||
|     plugins.SummaryWidget = SummaryWidget; | ||||
|     plugins.TelemetryMean = TelemetryMean; | ||||
|     plugins.URLIndicatorPlugin = URLIndicatorPlugin; | ||||
|     plugins.ActivityModes = ActivityModes; | ||||
|  | ||||
|     return plugins; | ||||
| }); | ||||
|   | ||||
| @@ -75,7 +75,8 @@ requirejs.config({ | ||||
|         "d3-format": "node_modules/d3-format/build/d3-format.min", | ||||
|         "d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min", | ||||
|         "d3-time": "node_modules/d3-time/build/d3-time.min", | ||||
|         "d3-time-format": "node_modules/d3-time-format/build/d3-time-format.min" | ||||
|         "d3-time-format": "node_modules/d3-time-format/build/d3-time-format.min", | ||||
|         "d3-dsv": "node_modules/d3-dsv/build/d3-dsv.min" | ||||
|     }, | ||||
|  | ||||
|     "shim": { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user