Compare commits
	
		
			44 Commits
		
	
	
		
			mobile-hid
			...
			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