mirror of
https://github.com/nasa/openmct.git
synced 2025-06-26 11:09:22 +00:00
Compare commits
44 Commits
remove-ang
...
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.legacyRegistry.enable.bind(openmct.legacyRegistry)
|
||||||
);
|
);
|
||||||
openmct.install(openmct.plugins.MyItems());
|
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.Espresso());
|
||||||
openmct.install(openmct.plugins.Generator());
|
openmct.install(openmct.plugins.Generator());
|
||||||
openmct.install(openmct.plugins.ExampleImagery());
|
openmct.install(openmct.plugins.ExampleImagery());
|
||||||
@ -68,6 +69,7 @@
|
|||||||
]
|
]
|
||||||
}));
|
}));
|
||||||
openmct.install(openmct.plugins.SummaryWidget());
|
openmct.install(openmct.plugins.SummaryWidget());
|
||||||
|
openmct.install(openmct.plugins.ActivityModes());
|
||||||
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
||||||
openmct.time.timeSystem('utc');
|
openmct.time.timeSystem('utc');
|
||||||
openmct.start();
|
openmct.start();
|
||||||
|
@ -49,7 +49,8 @@ requirejs.config({
|
|||||||
"d3-format": "node_modules/d3-format/build/d3-format.min",
|
"d3-format": "node_modules/d3-format/build/d3-format.min",
|
||||||
"d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min",
|
"d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min",
|
||||||
"d3-time": "node_modules/d3-time/build/d3-time.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": {
|
"shim": {
|
||||||
"angular": {
|
"angular": {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
"d3-collection": "1.0.x",
|
"d3-collection": "1.0.x",
|
||||||
"d3-color": "1.0.x",
|
"d3-color": "1.0.x",
|
||||||
"d3-format": "1.2.x",
|
"d3-format": "1.2.x",
|
||||||
|
"d3-dsv": "^1.0.8",
|
||||||
"d3-interpolate": "1.1.x",
|
"d3-interpolate": "1.1.x",
|
||||||
"d3-scale": "1.0.x",
|
"d3-scale": "1.0.x",
|
||||||
"d3-selection": "1.3.x",
|
"d3-selection": "1.3.x",
|
||||||
|
@ -204,7 +204,10 @@ define([
|
|||||||
"composition": [],
|
"composition": [],
|
||||||
"start": {
|
"start": {
|
||||||
"timestamp": 0
|
"timestamp": 0
|
||||||
}
|
},
|
||||||
|
"activityStart": {},
|
||||||
|
"activityDuration": {},
|
||||||
|
"activityEnd": {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -341,7 +344,7 @@ define([
|
|||||||
"cssClass": "icon-plot-resource",
|
"cssClass": "icon-plot-resource",
|
||||||
"description": "Graph Resource Utilization",
|
"description": "Graph Resource Utilization",
|
||||||
"control": "button",
|
"control": "button",
|
||||||
"method": "toggleGraph"
|
"method": "test"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"cssClass": "icon-activity-mode",
|
"cssClass": "icon-activity-mode",
|
||||||
@ -374,7 +377,36 @@ define([
|
|||||||
"description": "Edit Properties...",
|
"description": "Edit Properties...",
|
||||||
"control": "button",
|
"control": "button",
|
||||||
"method": "properties"
|
"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",
|
"$scope",
|
||||||
"$q",
|
"$q",
|
||||||
"objectLoader",
|
"objectLoader",
|
||||||
"TIMELINE_MINIMUM_DURATION"
|
"TIMELINE_MINIMUM_DURATION",
|
||||||
|
"openmct"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
ng-click="$event.stopPropagation()"
|
ng-click="$event.stopPropagation()"
|
||||||
ng-controller="TimelineController as timelineController">
|
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 -->
|
<!-- LEFT PANE: TABULAR AND RESOURCE LEGEND AREAS -->
|
||||||
<mct-split-pane anchor="bottom"
|
<mct-split-pane anchor="bottom"
|
||||||
position="pane.y"
|
position="pane.y"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
define({
|
define({
|
||||||
// Pixel width of start/end handles
|
// Pixel width of start/end handles
|
||||||
HANDLE_WIDTH: 32,
|
HANDLE_WIDTH: 16,
|
||||||
// Pixel tolerance for snapping behavior
|
// Pixel tolerance for snapping behavior
|
||||||
SNAP_WIDTH: 16
|
SNAP_WIDTH: 16
|
||||||
});
|
});
|
||||||
|
@ -21,28 +21,57 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define(
|
define(
|
||||||
[],
|
['EventEmitter'],
|
||||||
function () {
|
function (EventEmitter) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes the time span of an activity object.
|
* Describes the time span of an activity object.
|
||||||
* @param model the activity's object model
|
* @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
|
// Get the start time for this timeline
|
||||||
function getStart() {
|
function getStart() {
|
||||||
return model.start.timestamp;
|
return getTimelineActivityStart(parentTimelineModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the end time for this timeline
|
// Get the end time for this timeline
|
||||||
function getEnd() {
|
function getEnd() {
|
||||||
return model.start.timestamp + model.duration.timestamp;
|
return getTimelineActivityEnd(parentTimelineModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the duration of this timeline
|
// Get the duration of this timeline
|
||||||
function getDuration() {
|
function getDuration(flag) {
|
||||||
|
if (flag === 'model') {
|
||||||
return model.duration.timestamp;
|
return model.duration.timestamp;
|
||||||
}
|
}
|
||||||
|
return getTimelineActivityDuration(parentTimelineModel);
|
||||||
|
}
|
||||||
|
|
||||||
// Get the epoch used by this timeline
|
// Get the epoch used by this timeline
|
||||||
function getEpoch() {
|
function getEpoch() {
|
||||||
@ -51,27 +80,36 @@ define(
|
|||||||
|
|
||||||
// Set the start time associated with this object
|
// Set the start time associated with this object
|
||||||
function setStart(value) {
|
function setStart(value) {
|
||||||
var end = getEnd();
|
|
||||||
mutation.mutate(function (m) {
|
parentMutation.mutate(function (m) {
|
||||||
m.start.timestamp = Math.max(value, 0);
|
if (!m.activityStart) {
|
||||||
// Update duration to keep end time
|
m.activityStart = {};
|
||||||
m.duration.timestamp = Math.max(end - value, 0);
|
}
|
||||||
}, model.modified);
|
|
||||||
|
m.activityStart[model.id] = Math.max(value, 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the duration associated with this object
|
// Set the duration associated with this object
|
||||||
function setDuration(value) {
|
function setDuration(value) {
|
||||||
mutation.mutate(function (m) {
|
parentMutation.mutate(function (m) {
|
||||||
m.duration.timestamp = Math.max(value, 0);
|
if (!m.activityDuration) {
|
||||||
}, model.modified);
|
m.activityDuration = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
m.activityDuration[model.id] = Math.max(value, 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the end time associated with this object
|
// Set the end time associated with this object
|
||||||
function setEnd(value) {
|
function setEnd(value) {
|
||||||
var start = getStart();
|
parentMutation.mutate(function (m) {
|
||||||
mutation.mutate(function (m) {
|
if (!m.activityEnd) {
|
||||||
m.duration.timestamp = Math.max(value - start, 0);
|
m.activityEnd = {};
|
||||||
}, model.modified);
|
}
|
||||||
|
|
||||||
|
m.activityEnd[model.id] = Math.max(value, 0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -110,7 +148,15 @@ define(
|
|||||||
* start and end times.
|
* start and end times.
|
||||||
* @returns {string} the epoch
|
* @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
|
* @param {DomainObject} domainObject the Activity
|
||||||
*/
|
*/
|
||||||
function ActivityTimespanCapability($q, domainObject) {
|
function ActivityTimespanCapability($q, domainObject) {
|
||||||
|
|
||||||
|
var parent = domainObject.getCapability('context').parentObject;
|
||||||
|
|
||||||
// Promise time span
|
// Promise time span
|
||||||
function promiseTimeSpan() {
|
function promiseTimeSpan() {
|
||||||
return $q.when(new ActivityTimespan(
|
return $q.when(new ActivityTimespan(
|
||||||
domainObject.getModel(),
|
domainObject.getModel(),
|
||||||
domainObject.getCapability('mutation')
|
domainObject.getCapability('mutation'),
|
||||||
|
parent
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +36,12 @@ define(
|
|||||||
* Controller for the Timeline view.
|
* Controller for the Timeline view.
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function TimelineController($scope, $q, objectLoader, MINIMUM_DURATION) {
|
function TimelineController($scope, $q, objectLoader, MINIMUM_DURATION, openmct) {
|
||||||
var swimlanePopulator = new TimelineSwimlanePopulator(
|
var swimlanePopulator = new TimelineSwimlanePopulator(
|
||||||
objectLoader,
|
objectLoader,
|
||||||
$scope.configuration || {},
|
$scope.configuration || {},
|
||||||
$scope.selection
|
$scope.selection,
|
||||||
|
openmct
|
||||||
),
|
),
|
||||||
graphPopulator = new TimelineGraphPopulator($q),
|
graphPopulator = new TimelineGraphPopulator($q),
|
||||||
dragPopulator = new TimelineDragPopulator(objectLoader);
|
dragPopulator = new TimelineDragPopulator(objectLoader);
|
||||||
|
@ -51,7 +51,6 @@ define(
|
|||||||
handles: function (domainObject) {
|
handles: function (domainObject) {
|
||||||
var type = domainObject.getCapability('type'),
|
var type = domainObject.getCapability('type'),
|
||||||
id = domainObject.getId();
|
id = domainObject.getId();
|
||||||
|
|
||||||
// Instantiate a handle
|
// Instantiate a handle
|
||||||
function instantiate(Handle) {
|
function instantiate(Handle) {
|
||||||
return new Handle(
|
return new Handle(
|
||||||
|
@ -115,11 +115,13 @@ define(
|
|||||||
var timespan = timespans[toId(id)];
|
var timespan = timespans[toId(id)];
|
||||||
// Use as setter if argument is present
|
// Use as setter if argument is present
|
||||||
if ((typeof value === 'number') && timespan) {
|
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.)
|
// and not after the end time.)
|
||||||
timespan.setStart(
|
timespan.setStart(
|
||||||
Math.min(Math.max(value, 0), timespan.getEnd())
|
Math.min(Math.max(value, 0), timespan.getEnd())
|
||||||
);
|
);
|
||||||
|
timespan.setDuration(timespan.getEnd() - Math.min(Math.max(value, 0)));
|
||||||
|
|
||||||
// Mark as dirty for subsequent persistence
|
// Mark as dirty for subsequent persistence
|
||||||
dirty[toId(id)] = true;
|
dirty[toId(id)] = true;
|
||||||
}
|
}
|
||||||
@ -140,10 +142,12 @@ define(
|
|||||||
var timespan = timespans[toId(id)];
|
var timespan = timespans[toId(id)];
|
||||||
// Use as setter if argument is present
|
// Use as setter if argument is present
|
||||||
if ((typeof value === 'number') && timespan) {
|
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(
|
timespan.setEnd(
|
||||||
Math.max(value, timespan.getStart())
|
Math.max(value, timespan.getStart())
|
||||||
);
|
);
|
||||||
|
timespan.setDuration(Math.max(value, timespan.getStart()) - timespan.getStart());
|
||||||
|
|
||||||
// Mark as dirty for subsequent persistence
|
// Mark as dirty for subsequent persistence
|
||||||
dirty[toId(id)] = true;
|
dirty[toId(id)] = true;
|
||||||
}
|
}
|
||||||
@ -198,9 +202,12 @@ define(
|
|||||||
// own adjustments
|
// own adjustments
|
||||||
start = timespan.getStart();
|
start = timespan.getStart();
|
||||||
end = timespan.getEnd();
|
end = timespan.getEnd();
|
||||||
// Update start, then end
|
|
||||||
|
// Update duration, start, then end
|
||||||
|
timespan.setDuration(end - start);
|
||||||
timespan.setStart(start + delta);
|
timespan.setStart(start + delta);
|
||||||
timespan.setEnd(end + delta);
|
timespan.setEnd(end + delta);
|
||||||
|
|
||||||
// Mark as dirty for subsequent persistence
|
// Mark as dirty for subsequent persistence
|
||||||
dirty[toId(spanId)] = true;
|
dirty[toId(spanId)] = true;
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,6 @@ define(
|
|||||||
chooseEnd = diffEnd > 0;
|
chooseEnd = diffEnd > 0;
|
||||||
}
|
}
|
||||||
// Start is chosen if diffEnd didn't snap, or nothing snapped
|
// Start is chosen if diffEnd didn't snap, or nothing snapped
|
||||||
|
|
||||||
// Our delta is relative to our initial state, but
|
// Our delta is relative to our initial state, but
|
||||||
// dragHandler.move is relative to current state, so whichever
|
// dragHandler.move is relative to current state, so whichever
|
||||||
// end we're snapping to, we need to compute a delta
|
// end we're snapping to, we need to compute a delta
|
||||||
|
@ -39,7 +39,7 @@ define(
|
|||||||
* @param configuration the view's configuration object
|
* @param configuration the view's configuration object
|
||||||
* @param {TimelineSwimlane} parent the parent swim lane (if any)
|
* @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(),
|
var id = domainObject.getId(),
|
||||||
highlight = false, // Drop highlight (middle)
|
highlight = false, // Drop highlight (middle)
|
||||||
highlightBottom = false, // Drop highlight (lower)
|
highlightBottom = false, // Drop highlight (lower)
|
||||||
@ -47,13 +47,93 @@ define(
|
|||||||
depth = parent ? (parent.depth + 1) : 0,
|
depth = parent ? (parent.depth + 1) : 0,
|
||||||
timespan,
|
timespan,
|
||||||
path = (!parent || !parent.parent) ? "" : parent.path +
|
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
|
// Look up timespan for this object
|
||||||
domainObject.useCapability('timespan').then(function (t) {
|
domainObject.useCapability('timespan').then(function (t) {
|
||||||
timespan = 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 {
|
return {
|
||||||
/**
|
/**
|
||||||
* Check if this swimlane is currently visible. (That is,
|
* Check if this swimlane is currently visible. (That is,
|
||||||
@ -155,6 +235,15 @@ define(
|
|||||||
timespan: function () {
|
timespan: function () {
|
||||||
return timespan;
|
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
|
// Expose domain object, expansion state, indentation depth
|
||||||
domainObject: domainObject,
|
domainObject: domainObject,
|
||||||
expanded: true,
|
expanded: true,
|
||||||
|
@ -39,7 +39,7 @@ define(
|
|||||||
* timeline view.
|
* timeline view.
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function TimelineSwimlanePopulator(objectLoader, configuration, selection) {
|
function TimelineSwimlanePopulator(objectLoader, configuration, selection, openmct) {
|
||||||
var swimlanes = [],
|
var swimlanes = [],
|
||||||
start = Number.POSITIVE_INFINITY,
|
start = Number.POSITIVE_INFINITY,
|
||||||
end = Number.NEGATIVE_INFINITY,
|
end = Number.NEGATIVE_INFINITY,
|
||||||
@ -72,7 +72,8 @@ define(
|
|||||||
assigner,
|
assigner,
|
||||||
configuration,
|
configuration,
|
||||||
parent,
|
parent,
|
||||||
index || 0
|
index || 0,
|
||||||
|
openmct
|
||||||
), selection);
|
), selection);
|
||||||
// Track start & end times of this domain object
|
// Track start & end times of this domain object
|
||||||
domainObject.useCapability('timespan').then(trackStartEnd);
|
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',
|
'../../platform/import-export/bundle',
|
||||||
'./summaryWidget/plugin',
|
'./summaryWidget/plugin',
|
||||||
'./URLIndicatorPlugin/URLIndicatorPlugin',
|
'./URLIndicatorPlugin/URLIndicatorPlugin',
|
||||||
|
'./activityModes/plugin',
|
||||||
'./telemetryMean/plugin',
|
'./telemetryMean/plugin',
|
||||||
'./plot/plugin',
|
'./plot/plugin',
|
||||||
'./staticRootPlugin/plugin'
|
'./staticRootPlugin/plugin'
|
||||||
@ -43,6 +44,7 @@ define([
|
|||||||
ImportExport,
|
ImportExport,
|
||||||
SummaryWidget,
|
SummaryWidget,
|
||||||
URLIndicatorPlugin,
|
URLIndicatorPlugin,
|
||||||
|
ActivityModes,
|
||||||
TelemetryMean,
|
TelemetryMean,
|
||||||
PlotPlugin,
|
PlotPlugin,
|
||||||
StaticRootPlugin
|
StaticRootPlugin
|
||||||
@ -137,6 +139,7 @@ define([
|
|||||||
plugins.SummaryWidget = SummaryWidget;
|
plugins.SummaryWidget = SummaryWidget;
|
||||||
plugins.TelemetryMean = TelemetryMean;
|
plugins.TelemetryMean = TelemetryMean;
|
||||||
plugins.URLIndicatorPlugin = URLIndicatorPlugin;
|
plugins.URLIndicatorPlugin = URLIndicatorPlugin;
|
||||||
|
plugins.ActivityModes = ActivityModes;
|
||||||
|
|
||||||
return plugins;
|
return plugins;
|
||||||
});
|
});
|
||||||
|
@ -75,7 +75,8 @@ requirejs.config({
|
|||||||
"d3-format": "node_modules/d3-format/build/d3-format.min",
|
"d3-format": "node_modules/d3-format/build/d3-format.min",
|
||||||
"d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min",
|
"d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min",
|
||||||
"d3-time": "node_modules/d3-time/build/d3-time.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": {
|
"shim": {
|
||||||
|
Reference in New Issue
Block a user