mirror of
https://github.com/nasa/openmct.git
synced 2025-06-30 12:43:04 +00:00
Compare commits
52 Commits
api-tutori
...
new-tutori
Author | SHA1 | Date | |
---|---|---|---|
9553e0c64f | |||
da40f4c96e | |||
6fa5a31217 | |||
5bc7a701dc | |||
5cd0516048 | |||
48a603ece8 | |||
abfa56464a | |||
c1d6e21c3c | |||
3bd556a406 | |||
347fb6d882 | |||
b3cf7a5d93 | |||
c7cffdeb3b | |||
d45ae7908d | |||
b10fb4533e | |||
c74fdb816f | |||
40985a56c8 | |||
5c01f0be24 | |||
f7ff5af60b | |||
2088fc52f3 | |||
db33ab143e | |||
8c77d4006a | |||
2fa567b98b | |||
e61f04663a | |||
4b905fa7d2 | |||
5e6e7f018a | |||
53f56b430a | |||
50c934820c | |||
2a10a2cae2 | |||
65325b90fd | |||
cfecc36ae6 | |||
d9f8622459 | |||
8e13819e1e | |||
aaedf5d576 | |||
af9ffaf02d | |||
970acbd56e | |||
46c7399867 | |||
9a6745635d | |||
34dc457aff | |||
a3311e4c57 | |||
ef8efbd53d | |||
6cd99efbb9 | |||
ae2b73a4f5 | |||
0c3ff82cfe | |||
50f303bbdc | |||
2a4944d6ee | |||
3544caf4be | |||
976333d7f7 | |||
6d5530ba9c | |||
77d0134e2e | |||
d3b4ad41c2 | |||
3d3baddd23 | |||
9f9d28deef |
@ -1,6 +1,6 @@
|
||||
# Open MCT [](http://www.apache.org/licenses/LICENSE-2.0)
|
||||
|
||||
Open MCT is a next-generation mission control framework for visualization of data on desktop and mobile devices. It is developed at NASA's Ames Research Center, and is being used by NASA for data analysis of spacecraft missions, as well as planning and operation of experimental rover systems. As a generalizable and open source framework, Open MCT could be used as the basis for building applications for planning, operation, and analysis of any systems producing telemetry data.
|
||||
Open MCT (Open Mission Control Technologies) is a next-generation mission control framework for visualization of data on desktop and mobile devices. It is developed at NASA's Ames Research Center, and is being used by NASA for data analysis of spacecraft missions, as well as planning and operation of experimental rover systems. As a generalizable and open source framework, Open MCT could be used as the basis for building applications for planning, operation, and analysis of any systems producing telemetry data.
|
||||
|
||||
Please visit our [Official Site](https://nasa.github.io/openmct/) and [Getting Started Guide](https://nasa.github.io/openmct/getting-started/)
|
||||
|
||||
|
@ -131,7 +131,7 @@ Keeping that in mind, there are a few useful patterns supported by the
|
||||
framework that are useful to keep in mind.
|
||||
|
||||
The specific service infrastructure provided by the platform is described
|
||||
in the [Platform Architecture](Platform.md).
|
||||
in the [Platform Architecture](platform.md).
|
||||
|
||||
## Extension Categories
|
||||
|
||||
|
@ -2261,10 +2261,7 @@ The platform understands the following policy categories (specifiable as the
|
||||
|
||||
* `action`: Determines whether or not a given action is allowable. The candidate
|
||||
argument here is an Action; the context is its action context object.
|
||||
* `composition`: Determines whether or not domain objects of a given type are
|
||||
allowed to contain domain objects of another type. The candidate argument here
|
||||
is the container's `Type`; the context argument is the `Type` of the object to be
|
||||
contained.
|
||||
* `composition`: Determines whether or not domain objects of a given type (first argument, `parentType`) can contain a given object (second argument, `child`).
|
||||
* `view`: Determines whether or not a view is applicable for a domain object.
|
||||
The candidate argument is the view's extension definition; the context argument
|
||||
is the `DomainObject` to be viewed.
|
||||
|
@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
/*global define*/
|
||||
|
||||
define({
|
||||
START_TIME: Date.now() - 24 * 60 * 60 * 1000 // Now minus a day.
|
@ -19,12 +19,11 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['./SinewaveConstants', 'moment'],
|
||||
function (SinewaveConstants, moment) {
|
||||
"use strict";
|
||||
|
||||
var START_TIME = SinewaveConstants.START_TIME,
|
||||
FORMAT_REGEX = /^-?\d+:\d+:\d+$/,
|
@ -74,7 +74,7 @@ define([
|
||||
openmct.legacyExtension(type, extension)
|
||||
})
|
||||
});
|
||||
openmct.types.register("generator", {
|
||||
openmct.types.addType("generator", {
|
||||
label: "Sine Wave Generator",
|
||||
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||
cssClass: "icon-telemetry",
|
26
index.html
26
index.html
@ -25,28 +25,32 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title></title>
|
||||
<script src="openmct-tutorial/lib/http.js">
|
||||
</script>
|
||||
<script src="bower_components/requirejs/require.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/dictionary-plugin.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/realtime-telemetry-plugin.js">
|
||||
</script>
|
||||
<script src="openmct-tutorial/historical-telemetry-plugin.js">
|
||||
</script>
|
||||
<script>
|
||||
require(['openmct'], function (openmct, generatorPlugin) {
|
||||
require(['openmct'], function (openmct) {
|
||||
[
|
||||
'example/imagery',
|
||||
'example/eventGenerator'
|
||||
].forEach(
|
||||
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
|
||||
);
|
||||
openmct.install(openmct.plugins.myItems);
|
||||
openmct.install(openmct.plugins.localStorage);
|
||||
openmct.install(openmct.plugins.espresso);
|
||||
|
||||
openmct.install(openmct.plugins.MyItems());
|
||||
openmct.install(openmct.plugins.LocalStorage());
|
||||
openmct.install(openmct.plugins.Espresso());
|
||||
openmct.install(openmct.plugins.Generator());
|
||||
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||
openmct.install(openmct.plugins.Conductor({
|
||||
defaultTimeSystem: 'utc',
|
||||
defaultTimespan: 30 * 60 * 1000,
|
||||
showConductor: true
|
||||
}));
|
||||
|
||||
openmct.install(DictionaryPlugin());
|
||||
openmct.install(RealtimeTelemetryPlugin());
|
||||
openmct.install(HistoricalTelemetryPlugin());
|
||||
openmct.start();
|
||||
});
|
||||
</script>
|
||||
|
1
openmct-tutorial
Submodule
1
openmct-tutorial
Submodule
Submodule openmct-tutorial added at 7076a15d3a
@ -84,5 +84,11 @@ define([
|
||||
return new Main().run(defaultRegistry);
|
||||
});
|
||||
|
||||
// For now, install conductor by default
|
||||
openmct.install(openmct.plugins.Conductor({
|
||||
showConductor: false
|
||||
}));
|
||||
|
||||
|
||||
return openmct;
|
||||
});
|
||||
|
@ -48,7 +48,7 @@ define([], function () {
|
||||
parent.useCapability('composition')
|
||||
.then(function (composees) {
|
||||
var isOrphan = composees.every(function (c) {
|
||||
return c.getId() !== domainObject.getId()
|
||||
return c.getId() !== domainObject.getId();
|
||||
});
|
||||
if (isOrphan) {
|
||||
parent.getCapability('action').perform('navigate');
|
||||
|
@ -33,7 +33,7 @@ define([
|
||||
mockContext,
|
||||
mockActionCapability,
|
||||
mockEditor,
|
||||
testParentModel,
|
||||
testParentComposition,
|
||||
testId,
|
||||
mockThrottledFns;
|
||||
|
||||
@ -41,7 +41,6 @@ define([
|
||||
testId = 'some-identifier';
|
||||
|
||||
mockThrottledFns = [];
|
||||
testParentModel = {};
|
||||
|
||||
mockTopic = jasmine.createSpy('topic');
|
||||
mockThrottle = jasmine.createSpy('throttle');
|
||||
@ -55,14 +54,12 @@ define([
|
||||
mockDomainObject = jasmine.createSpyObj('domainObject', [
|
||||
'getId',
|
||||
'getCapability',
|
||||
'getModel',
|
||||
'hasCapability'
|
||||
]);
|
||||
mockParentObject = jasmine.createSpyObj('domainObject', [
|
||||
'getId',
|
||||
'getCapability',
|
||||
'getModel',
|
||||
'hasCapability'
|
||||
'useCapability'
|
||||
]);
|
||||
mockContext = jasmine.createSpyObj('context', ['getParent']);
|
||||
mockActionCapability = jasmine.createSpyObj('action', ['perform']);
|
||||
@ -75,9 +72,7 @@ define([
|
||||
mockThrottledFns.push(mockThrottledFn);
|
||||
return mockThrottledFn;
|
||||
});
|
||||
mockTopic.andCallFake(function (k) {
|
||||
return k === 'mutation' && mockMutationTopic;
|
||||
});
|
||||
mockTopic.andReturn(mockMutationTopic);
|
||||
mockDomainObject.getId.andReturn(testId);
|
||||
mockDomainObject.getCapability.andCallFake(function (c) {
|
||||
return {
|
||||
@ -88,12 +83,13 @@ define([
|
||||
mockDomainObject.hasCapability.andCallFake(function (c) {
|
||||
return !!mockDomainObject.getCapability(c);
|
||||
});
|
||||
mockParentObject.getModel.andReturn(testParentModel);
|
||||
mockParentObject.getCapability.andCallFake(function (c) {
|
||||
return {
|
||||
action: mockActionCapability
|
||||
}[c];
|
||||
});
|
||||
testParentComposition = [];
|
||||
mockParentObject.useCapability.andReturn(Promise.resolve(testParentComposition));
|
||||
mockContext.getParent.andReturn(mockParentObject);
|
||||
mockNavigationService.getNavigation.andReturn(mockDomainObject);
|
||||
mockEditor.isEditContextRoot.andReturn(false);
|
||||
@ -126,7 +122,9 @@ define([
|
||||
var prefix = isOrphan ? "" : "non-";
|
||||
describe("for " + prefix + "orphan objects", function () {
|
||||
beforeEach(function () {
|
||||
testParentModel.composition = isOrphan ? [] : [testId];
|
||||
if (!isOrphan) {
|
||||
testParentComposition.push(mockDomainObject);
|
||||
}
|
||||
});
|
||||
|
||||
[false, true].forEach(function (isEditRoot) {
|
||||
@ -136,13 +134,31 @@ define([
|
||||
function itNavigatesAsExpected() {
|
||||
if (isOrphan && !isEditRoot) {
|
||||
it("navigates to the parent", function () {
|
||||
expect(mockActionCapability.perform)
|
||||
.toHaveBeenCalledWith('navigate');
|
||||
var done = false;
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
});
|
||||
setTimeout(function () {
|
||||
done = true;
|
||||
}, 5);
|
||||
runs(function () {
|
||||
expect(mockActionCapability.perform)
|
||||
.toHaveBeenCalledWith('navigate');
|
||||
});
|
||||
});
|
||||
} else {
|
||||
it("does nothing", function () {
|
||||
expect(mockActionCapability.perform)
|
||||
.not.toHaveBeenCalled();
|
||||
var done = false;
|
||||
waitsFor(function () {
|
||||
return done;
|
||||
});
|
||||
setTimeout(function () {
|
||||
done = true;
|
||||
}, 5);
|
||||
runs(function () {
|
||||
expect(mockActionCapability.perform)
|
||||
.not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -157,7 +173,6 @@ define([
|
||||
mockNavigationService.addListener.mostRecentCall
|
||||
.args[0](mockDomainObject);
|
||||
});
|
||||
|
||||
itNavigatesAsExpected();
|
||||
});
|
||||
|
||||
|
@ -54,8 +54,7 @@ define(
|
||||
AddActionProvider.prototype.getActions = function (actionContext) {
|
||||
var context = actionContext || {},
|
||||
key = context.key,
|
||||
destination = context.domainObject,
|
||||
self = this;
|
||||
destination = context.domainObject;
|
||||
|
||||
// We only provide Add actions, and we need a
|
||||
// domain object to serve as the container for the
|
||||
@ -66,16 +65,16 @@ define(
|
||||
}
|
||||
|
||||
// Introduce one create action per type
|
||||
['timeline', 'activity'].map(function (type) {
|
||||
return ['timeline', 'activity'].map(function (type) {
|
||||
return new AddAction(
|
||||
type,
|
||||
this.typeService.getType(type),
|
||||
destination,
|
||||
context,
|
||||
self.$q,
|
||||
self.dialogService,
|
||||
self.policyService
|
||||
this.$q,
|
||||
this.dialogService,
|
||||
this.policyService
|
||||
);
|
||||
});
|
||||
}, this);
|
||||
};
|
||||
|
||||
return AddActionProvider;
|
||||
|
@ -59,12 +59,12 @@ define(
|
||||
domainObject = this.domainObject,
|
||||
policyService = this.policyService;
|
||||
|
||||
function validateLocation(locatingObject) {
|
||||
var locatingType = locatingObject &&
|
||||
locatingObject.getCapability('type');
|
||||
return locatingType && policyService.allow(
|
||||
function validateLocation(parent) {
|
||||
var parentType = parent &&
|
||||
parent.getCapability('type');
|
||||
return parentType && policyService.allow(
|
||||
"composition",
|
||||
locatingType,
|
||||
parentType,
|
||||
domainObject
|
||||
);
|
||||
}
|
||||
@ -118,7 +118,7 @@ define(
|
||||
formModel = this.createModel(formValue);
|
||||
|
||||
formModel.location = parent.getId();
|
||||
this.domainObject.useCapability("mutation", function (model) {
|
||||
this.domainObject.useCapability("mutation", function () {
|
||||
return formModel;
|
||||
});
|
||||
return this.domainObject;
|
||||
|
@ -31,9 +31,7 @@ define(
|
||||
var mockTypeService,
|
||||
mockDialogService,
|
||||
mockPolicyService,
|
||||
mockCreationPolicy,
|
||||
mockCompositionPolicy,
|
||||
mockPolicyMap = {},
|
||||
mockTypeMap,
|
||||
mockTypes,
|
||||
mockDomainObject,
|
||||
mockQ,
|
||||
@ -55,49 +53,33 @@ define(
|
||||
);
|
||||
mockType.hasFeature.andReturn(true);
|
||||
mockType.getName.andReturn(name);
|
||||
mockType.getKey.andReturn(name);
|
||||
return mockType;
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockTypeService = jasmine.createSpyObj(
|
||||
"typeService",
|
||||
["listTypes"]
|
||||
);
|
||||
mockDialogService = jasmine.createSpyObj(
|
||||
"dialogService",
|
||||
["getUserInput"]
|
||||
);
|
||||
mockPolicyService = jasmine.createSpyObj(
|
||||
"policyService",
|
||||
["allow"]
|
||||
["getType"]
|
||||
);
|
||||
mockDialogService = {};
|
||||
mockPolicyService = {};
|
||||
mockDomainObject = {};
|
||||
|
||||
mockDomainObject = jasmine.createSpyObj(
|
||||
"domainObject",
|
||||
["getCapability"]
|
||||
);
|
||||
|
||||
//Mocking getCapability because AddActionProvider uses the
|
||||
// type capability of the destination object.
|
||||
mockDomainObject.getCapability.andReturn({});
|
||||
|
||||
mockTypes = ["A", "B", "C"].map(createMockType);
|
||||
mockTypes = [
|
||||
"timeline",
|
||||
"activity",
|
||||
"other"
|
||||
].map(createMockType);
|
||||
mockTypeMap = {};
|
||||
|
||||
mockTypes.forEach(function (type) {
|
||||
mockPolicyMap[type.getName()] = true;
|
||||
mockTypeMap[type.getKey()] = type;
|
||||
});
|
||||
|
||||
mockCreationPolicy = function (type) {
|
||||
return mockPolicyMap[type.getName()];
|
||||
};
|
||||
|
||||
mockCompositionPolicy = function () {
|
||||
return true;
|
||||
};
|
||||
|
||||
mockPolicyService.allow.andReturn(true);
|
||||
|
||||
mockTypeService.listTypes.andReturn(mockTypes);
|
||||
mockTypeService.getType.andCallFake(function (key) {
|
||||
return mockTypeMap[key];
|
||||
});
|
||||
|
||||
provider = new AddActionProvider(
|
||||
mockQ,
|
||||
@ -107,29 +89,16 @@ define(
|
||||
);
|
||||
});
|
||||
|
||||
it("checks for creatability", function () {
|
||||
provider.getActions({
|
||||
it("provides actions for timeline and activity", function () {
|
||||
var actions = provider.getActions({
|
||||
key: "add",
|
||||
domainObject: mockDomainObject
|
||||
});
|
||||
expect(actions.length).toBe(2);
|
||||
expect(actions[0].metadata.type).toBe('timeline');
|
||||
expect(actions[1].metadata.type).toBe('activity');
|
||||
|
||||
// Make sure it was creation which was used to check
|
||||
expect(mockPolicyService.allow)
|
||||
.toHaveBeenCalledWith("creation", mockTypes[0]);
|
||||
});
|
||||
|
||||
it("checks for composability of type", function () {
|
||||
provider.getActions({
|
||||
key: "add",
|
||||
domainObject: mockDomainObject
|
||||
});
|
||||
|
||||
expect(mockPolicyService.allow).toHaveBeenCalledWith(
|
||||
"composition",
|
||||
jasmine.any(Object),
|
||||
jasmine.any(Object)
|
||||
);
|
||||
|
||||
expect(mockDomainObject.getCapability).toHaveBeenCalledWith('type');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -175,7 +175,7 @@ define(
|
||||
expect(mockPolicyService.allow).toHaveBeenCalledWith(
|
||||
'composition',
|
||||
mockOtherType,
|
||||
mockType
|
||||
mockDomainObject
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
@import "logo-and-bg";
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../general/res/sass/_mixins";
|
||||
|
@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../general/res/sass/_mixins";
|
||||
|
@ -38,22 +38,20 @@ define(
|
||||
function CompositionPolicy() {
|
||||
}
|
||||
|
||||
CompositionPolicy.prototype.allow = function (candidate, context) {
|
||||
var type = context.getCapability('type');
|
||||
var typeKey = type.getKey();
|
||||
var candidateDef = candidate.getDefinition();
|
||||
|
||||
// A candidate without containment rules can contain anything.
|
||||
if (!candidateDef.contains) {
|
||||
CompositionPolicy.prototype.allow = function (parentType, child) {
|
||||
var parentDef = parentType.getDefinition();
|
||||
|
||||
// A parent without containment rules can contain anything.
|
||||
if (!parentDef.contains) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// If any containment rule matches context type, the candidate
|
||||
// can contain this type.
|
||||
return candidateDef.contains.some(function (c) {
|
||||
return parentDef.contains.some(function (c) {
|
||||
// Simple containment rules are supported typeKeys.
|
||||
if (typeof c === 'string') {
|
||||
return c === typeKey;
|
||||
return c === child.getCapability('type').getKey();
|
||||
}
|
||||
// More complicated rules require context to have all specified
|
||||
// capabilities.
|
||||
@ -61,7 +59,7 @@ define(
|
||||
c.has = [c.has];
|
||||
}
|
||||
return c.has.every(function (capability) {
|
||||
return context.hasCapability(capability);
|
||||
return child.hasCapability(capability);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
@ -79,7 +79,7 @@ define(
|
||||
expect(mockPolicyService.allow).toHaveBeenCalledWith(
|
||||
'composition',
|
||||
mockTypes[0],
|
||||
mockTypes[1]
|
||||
mockDomainObjects[1]
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -24,60 +24,94 @@ define(
|
||||
["../src/CompositionPolicy"],
|
||||
function (CompositionPolicy) {
|
||||
describe("Composition policy", function () {
|
||||
var mockInjector,
|
||||
mockTypeService,
|
||||
mockCapabilityService,
|
||||
mockTypes,
|
||||
var typeA,
|
||||
typeB,
|
||||
typeC,
|
||||
mockChildObject,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
mockInjector = jasmine.createSpyObj('$injector', ['get']);
|
||||
mockTypeService = jasmine.createSpyObj(
|
||||
'typeService',
|
||||
['listTypes']
|
||||
typeA = jasmine.createSpyObj(
|
||||
'type A-- the particular kind',
|
||||
['getKey', 'getDefinition']
|
||||
);
|
||||
mockCapabilityService = jasmine.createSpyObj(
|
||||
'capabilityService',
|
||||
['getCapabilities']
|
||||
);
|
||||
// Both types can only contain b, let's say
|
||||
mockTypes = ['a', 'b'].map(function (type) {
|
||||
var mockType = jasmine.createSpyObj(
|
||||
'type-' + type,
|
||||
['getKey', 'getDefinition', 'getInitialModel']
|
||||
);
|
||||
mockType.getKey.andReturn(type);
|
||||
mockType.getDefinition.andReturn({
|
||||
contains: ['b']
|
||||
});
|
||||
mockType.getInitialModel.andReturn({});
|
||||
return mockType;
|
||||
typeA.getKey.andReturn('a');
|
||||
typeA.getDefinition.andReturn({
|
||||
contains: ['a']
|
||||
});
|
||||
|
||||
mockInjector.get.andCallFake(function (name) {
|
||||
return {
|
||||
typeService: mockTypeService,
|
||||
capabilityService: mockCapabilityService
|
||||
}[name];
|
||||
|
||||
typeB = jasmine.createSpyObj(
|
||||
'type B-- anything goes',
|
||||
['getKey', 'getDefinition']
|
||||
);
|
||||
typeB.getKey.andReturn('b');
|
||||
typeB.getDefinition.andReturn({
|
||||
contains: ['a', 'b']
|
||||
});
|
||||
|
||||
mockTypeService.listTypes.andReturn(mockTypes);
|
||||
mockCapabilityService.getCapabilities.andReturn({});
|
||||
typeC = jasmine.createSpyObj(
|
||||
'type C-- distinguishing and interested in telemetry',
|
||||
['getKey', 'getDefinition']
|
||||
);
|
||||
typeC.getKey.andReturn('c');
|
||||
typeC.getDefinition.andReturn({
|
||||
contains: [{has: 'telemetry'}]
|
||||
});
|
||||
|
||||
policy = new CompositionPolicy(mockInjector);
|
||||
mockChildObject = jasmine.createSpyObj(
|
||||
'childObject',
|
||||
['getCapability', 'hasCapability']
|
||||
);
|
||||
|
||||
policy = new CompositionPolicy();
|
||||
});
|
||||
|
||||
// Test basic composition policy here; test more closely at
|
||||
// the unit level in ContainmentTable for 'has' support, et al
|
||||
it("enforces containment rules defined by types", function () {
|
||||
expect(policy.allow(mockTypes[0], mockTypes[1]))
|
||||
.toBeTruthy();
|
||||
expect(policy.allow(mockTypes[1], mockTypes[1]))
|
||||
.toBeTruthy();
|
||||
expect(policy.allow(mockTypes[1], mockTypes[0]))
|
||||
.toBeFalsy();
|
||||
expect(policy.allow(mockTypes[0], mockTypes[0]))
|
||||
.toBeFalsy();
|
||||
describe('enforces simple containment rules', function () {
|
||||
|
||||
it('allows when type matches', function () {
|
||||
mockChildObject.getCapability.andReturn(typeA);
|
||||
expect(policy.allow(typeA, mockChildObject))
|
||||
.toBeTruthy();
|
||||
|
||||
expect(policy.allow(typeB, mockChildObject))
|
||||
.toBeTruthy();
|
||||
|
||||
mockChildObject.getCapability.andReturn(typeB);
|
||||
expect(policy.allow(typeB, mockChildObject))
|
||||
.toBeTruthy();
|
||||
});
|
||||
|
||||
|
||||
it('disallows when type doesn\'t match', function () {
|
||||
|
||||
mockChildObject.getCapability.andReturn(typeB);
|
||||
expect(policy.allow(typeA, mockChildObject))
|
||||
.toBeFalsy();
|
||||
|
||||
mockChildObject.getCapability.andReturn(typeC);
|
||||
expect(policy.allow(typeA, mockChildObject))
|
||||
.toBeFalsy();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('enforces capability-based containment rules', function () {
|
||||
it('allows when object has capability', function () {
|
||||
mockChildObject.hasCapability.andReturn(true);
|
||||
expect(policy.allow(typeC, mockChildObject))
|
||||
.toBeTruthy();
|
||||
expect(mockChildObject.hasCapability)
|
||||
.toHaveBeenCalledWith('telemetry');
|
||||
});
|
||||
|
||||
it('skips when object doesn\'t have capability', function () {
|
||||
mockChildObject.hasCapability.andReturn(false);
|
||||
expect(policy.allow(typeC, mockChildObject))
|
||||
.toBeFalsy();
|
||||
expect(mockChildObject.hasCapability)
|
||||
.toHaveBeenCalledWith('telemetry');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -44,16 +44,16 @@ define(
|
||||
var model = parentObject && parentObject.getModel(),
|
||||
composition = (model || {}).composition || [];
|
||||
if (composition.indexOf(id) === -1) {
|
||||
// $log.warn([
|
||||
// "Attempted to contextualize",
|
||||
// id,
|
||||
// "in",
|
||||
// parentObject && parentObject.getId(),
|
||||
// "but that object does not contain",
|
||||
// id,
|
||||
// "in its composition.",
|
||||
// "Unexpected behavior may follow."
|
||||
// ].join(" "));
|
||||
$log.warn([
|
||||
"Attempted to contextualize",
|
||||
id,
|
||||
"in",
|
||||
parentObject && parentObject.getId(),
|
||||
"but that object does not contain",
|
||||
id,
|
||||
"in its composition.",
|
||||
"Unexpected behavior may follow."
|
||||
].join(" "));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ define(
|
||||
expect(policyService.allow).toHaveBeenCalledWith(
|
||||
"composition",
|
||||
parentCandidate.capabilities.type,
|
||||
object.capabilities.type
|
||||
object
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -114,7 +114,7 @@ define(
|
||||
expect(mockPolicyService.allow).toHaveBeenCalledWith(
|
||||
"composition",
|
||||
parentCandidate.capabilities.type,
|
||||
object.capabilities.type
|
||||
object
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -124,7 +124,7 @@ define(
|
||||
expect(policyService.allow).toHaveBeenCalledWith(
|
||||
"composition",
|
||||
parentCandidate.capabilities.type,
|
||||
object.capabilities.type
|
||||
object
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -21,11 +21,9 @@
|
||||
*****************************************************************************/
|
||||
|
||||
define([
|
||||
"./src/ConductorTelemetryDecorator",
|
||||
"./src/ConductorRepresenter",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ConductorTelemetryDecorator,
|
||||
ConductorRepresenter,
|
||||
legacyRegistry
|
||||
) {
|
||||
@ -39,16 +37,6 @@ define([
|
||||
"openmct"
|
||||
]
|
||||
}
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"type": "decorator",
|
||||
"provides": "telemetryService",
|
||||
"implementation": ConductorTelemetryDecorator,
|
||||
"depends": [
|
||||
"openmct"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2015, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT Web includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
define(
|
||||
function () {
|
||||
|
||||
/**
|
||||
* Decorates the `telemetryService` such that requests are
|
||||
* mediated by the time conductor. This is a modified version of the
|
||||
* decorator used in the old TimeConductor that integrates with the
|
||||
* new TimeConductor API.
|
||||
*
|
||||
* @constructor
|
||||
* @memberof platform/features/conductor
|
||||
* @implements {TelemetryService}
|
||||
* @param {platform/features/conductor.TimeConductor} conductor
|
||||
* the service which exposes the global time conductor
|
||||
* @param {TelemetryService} telemetryService the decorated service
|
||||
*/
|
||||
function ConductorTelemetryDecorator(openmct, telemetryService) {
|
||||
this.conductor = openmct.conductor;
|
||||
this.telemetryService = telemetryService;
|
||||
|
||||
this.amendRequests = ConductorTelemetryDecorator.prototype.amendRequests.bind(this);
|
||||
}
|
||||
|
||||
function amendRequest(request, bounds, timeSystem) {
|
||||
request = request || {};
|
||||
request.start = bounds.start;
|
||||
request.end = bounds.end;
|
||||
request.domain = timeSystem.metadata.key;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
ConductorTelemetryDecorator.prototype.amendRequests = function (requests) {
|
||||
var bounds = this.conductor.bounds(),
|
||||
timeSystem = this.conductor.timeSystem();
|
||||
|
||||
return (requests || []).map(function (request) {
|
||||
return amendRequest(request, bounds, timeSystem);
|
||||
});
|
||||
};
|
||||
|
||||
ConductorTelemetryDecorator.prototype.requestTelemetry = function (requests) {
|
||||
return this.telemetryService
|
||||
.requestTelemetry(this.amendRequests(requests));
|
||||
};
|
||||
|
||||
ConductorTelemetryDecorator.prototype.subscribe = function (callback, requests) {
|
||||
var unsubscribeFunc = this.telemetryService.subscribe(callback, this.amendRequests(requests)),
|
||||
conductor = this.conductor,
|
||||
self = this;
|
||||
|
||||
function amendRequests() {
|
||||
return self.amendRequests(requests);
|
||||
}
|
||||
|
||||
conductor.on('bounds', amendRequests);
|
||||
return function () {
|
||||
unsubscribeFunc();
|
||||
conductor.off('bounds', amendRequests);
|
||||
};
|
||||
};
|
||||
|
||||
return ConductorTelemetryDecorator;
|
||||
}
|
||||
);
|
@ -72,7 +72,7 @@ define([
|
||||
"timeConductorViewService",
|
||||
"formatService",
|
||||
"DEFAULT_TIMECONDUCTOR_MODE",
|
||||
"SHOW_TIMECONDUCTOR",
|
||||
"SHOW_TIMECONDUCTOR"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
@import "../../../../../commonUI/general/res/sass/constants";
|
||||
@import "../../../../../commonUI/general/res/sass/mixins";
|
||||
|
@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
@import "../../../../../commonUI/general/res/sass/constants";
|
||||
@import "../../../../../commonUI/general/res/sass/mixins";
|
||||
|
@ -41,10 +41,10 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function TimeConductorController(
|
||||
$scope,
|
||||
$window,
|
||||
$location,
|
||||
openmct,
|
||||
$scope,
|
||||
$window,
|
||||
$location,
|
||||
openmct,
|
||||
conductorViewService,
|
||||
formatService,
|
||||
DEFAULT_MODE,
|
||||
@ -68,6 +68,11 @@ define(
|
||||
this.modes = conductorViewService.availableModes();
|
||||
this.validation = new TimeConductorValidation(this.conductor);
|
||||
this.formatService = formatService;
|
||||
|
||||
//Check if the default mode defined is actually available
|
||||
if (this.modes[DEFAULT_MODE] === undefined) {
|
||||
DEFAULT_MODE = 'fixed';
|
||||
}
|
||||
this.DEFAULT_MODE = DEFAULT_MODE;
|
||||
|
||||
// Construct the provided time system definitions
|
||||
|
@ -130,8 +130,10 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
mockLocation,
|
||||
{conductor: mockTimeConductor},
|
||||
mockConductorViewService,
|
||||
mockTimeSystems,
|
||||
mockFormatService
|
||||
mockFormatService,
|
||||
'fixed',
|
||||
true
|
||||
|
||||
);
|
||||
|
||||
tsListener = getListener(mockTimeConductor.on, "timeSystem");
|
||||
@ -244,7 +246,6 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
var ts1Metadata;
|
||||
var ts2Metadata;
|
||||
var ts3Metadata;
|
||||
var mockTimeSystemConstructors;
|
||||
|
||||
beforeEach(function () {
|
||||
mode = "realtime";
|
||||
@ -276,11 +277,7 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
];
|
||||
|
||||
//Wrap in mock constructors
|
||||
mockTimeSystemConstructors = mockTimeSystems.map(function (mockTimeSystem) {
|
||||
return function () {
|
||||
return mockTimeSystem;
|
||||
};
|
||||
});
|
||||
mockConductorViewService.systems = mockTimeSystems;
|
||||
|
||||
controller = new TimeConductorController(
|
||||
mockScope,
|
||||
@ -288,8 +285,9 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
mockLocation,
|
||||
{conductor: mockTimeConductor},
|
||||
mockConductorViewService,
|
||||
mockTimeSystemConstructors,
|
||||
mockFormatService
|
||||
mockFormatService,
|
||||
"fixed",
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
@ -434,12 +432,7 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
}
|
||||
};
|
||||
|
||||
mockTimeSystems.push(function () {
|
||||
return timeSystem;
|
||||
});
|
||||
mockTimeSystems.push(function () {
|
||||
return otherTimeSystem;
|
||||
});
|
||||
mockConductorViewService.systems = [timeSystem, otherTimeSystem];
|
||||
|
||||
urlBounds = {
|
||||
start: 100,
|
||||
@ -467,8 +460,9 @@ define(['./TimeConductorController'], function (TimeConductorController) {
|
||||
mockLocation,
|
||||
{conductor: mockTimeConductor},
|
||||
mockConductorViewService,
|
||||
mockTimeSystems,
|
||||
mockFormatService
|
||||
mockFormatService,
|
||||
"fixed",
|
||||
true
|
||||
);
|
||||
|
||||
spyOn(controller, "setMode");
|
||||
|
@ -66,7 +66,7 @@ define([
|
||||
};
|
||||
|
||||
UTCTimeSystem.prototype.defaults = function (defaults) {
|
||||
if (arguments.length > 0){
|
||||
if (arguments.length > 0) {
|
||||
this.defaultValues = defaults;
|
||||
}
|
||||
|
||||
@ -81,7 +81,7 @@ define([
|
||||
deltas: {start: FIFTEEN_MINUTES, end: 0},
|
||||
bounds: {start: now - FIFTEEN_MINUTES, end: now},
|
||||
zoom: {min: FIFTY_YEARS, max: ONE_MINUTE}
|
||||
}
|
||||
};
|
||||
}
|
||||
return this.defaultValues;
|
||||
};
|
||||
|
@ -34,13 +34,14 @@ define(
|
||||
function LayoutCompositionPolicy() {
|
||||
}
|
||||
|
||||
LayoutCompositionPolicy.prototype.allow = function (candidate, context) {
|
||||
var isFolderInLayout =
|
||||
candidate &&
|
||||
context &&
|
||||
candidate.instanceOf('layout') &&
|
||||
context.getCapability('type').instanceOf('folder');
|
||||
return !isFolderInLayout;
|
||||
LayoutCompositionPolicy.prototype.allow = function (parentType, child) {
|
||||
if (parentType.instanceOf('layout') &&
|
||||
child.getCapability('type').instanceOf('folder')) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return LayoutCompositionPolicy;
|
||||
|
@ -24,18 +24,25 @@ define(
|
||||
["../src/LayoutCompositionPolicy"],
|
||||
function (LayoutCompositionPolicy) {
|
||||
describe("Layout's composition policy", function () {
|
||||
var mockCandidate,
|
||||
var mockChild,
|
||||
mockCandidate,
|
||||
mockContext,
|
||||
candidateType,
|
||||
contextType,
|
||||
policy;
|
||||
|
||||
beforeEach(function () {
|
||||
mockChild = jasmine.createSpyObj(
|
||||
'childObject',
|
||||
['getCapability']
|
||||
);
|
||||
mockCandidate =
|
||||
jasmine.createSpyObj('candidateType', ['instanceOf']);
|
||||
mockContext =
|
||||
jasmine.createSpyObj('contextType', ['instanceOf']);
|
||||
|
||||
mockChild.getCapability.andReturn(mockContext);
|
||||
|
||||
mockCandidate.instanceOf.andCallFake(function (t) {
|
||||
return t === candidateType;
|
||||
});
|
||||
@ -49,19 +56,19 @@ define(
|
||||
it("disallows folders in layouts", function () {
|
||||
candidateType = 'layout';
|
||||
contextType = 'folder';
|
||||
expect(policy.allow(mockCandidate, mockContext)).toBe(false);
|
||||
expect(policy.allow(mockCandidate, mockChild)).toBe(false);
|
||||
});
|
||||
|
||||
it("does not disallow folders elsewhere", function () {
|
||||
candidateType = 'nonlayout';
|
||||
contextType = 'folder';
|
||||
expect(policy.allow(mockCandidate, mockContext)).toBe(true);
|
||||
expect(policy.allow(mockCandidate, mockChild)).toBe(true);
|
||||
});
|
||||
|
||||
it("allows things other than folders in layouts", function () {
|
||||
candidateType = 'layout';
|
||||
contextType = 'nonfolder';
|
||||
expect(policy.allow(mockCandidate, mockContext)).toBe(true);
|
||||
expect(policy.allow(mockCandidate, mockChild)).toBe(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
@ -60,7 +60,7 @@
|
||||
</tr>
|
||||
<tr ng-repeat-end
|
||||
ng-style="{ top: visibleRow.offsetY + 'px' }"
|
||||
ng-click="table.onRowClick($event, visibleRow.rowIndex) ">
|
||||
ng-click="table.onRowClick($event, visibleRow.rowIndex)">
|
||||
<td ng-repeat="header in displayHeaders"
|
||||
ng-style="{
|
||||
width: columnWidths[$index] + 'px',
|
||||
|
@ -66,7 +66,8 @@ define(
|
||||
mockDomainObject = jasmine.createSpyObj("domainObject", [
|
||||
"getModel",
|
||||
"getId",
|
||||
"useCapability"
|
||||
"useCapability",
|
||||
"hasCapability"
|
||||
]);
|
||||
mockDomainObject.getModel.andReturn({});
|
||||
mockDomainObject.getId.andReturn("mockId");
|
||||
|
@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../commonUI/general/res/sass/constants";
|
||||
|
@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../commonUI/general/res/sass/constants";
|
||||
|
@ -19,6 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
$output-bourbon-deprecation-warnings: false;
|
||||
@import "bourbon";
|
||||
|
||||
@import "../../../../commonUI/general/res/sass/constants";
|
||||
|
@ -166,13 +166,13 @@ define(
|
||||
|
||||
// Aggregators need other services to aggregate, otherwise they
|
||||
// do nothing.
|
||||
// if (!latest[service]) {
|
||||
// return warn(
|
||||
// aggregator,
|
||||
// "aggregator",
|
||||
// "No services to aggregate for"
|
||||
// );
|
||||
// }
|
||||
if (!latest[service]) {
|
||||
return warn(
|
||||
aggregator,
|
||||
"aggregator",
|
||||
"No services to aggregate for"
|
||||
);
|
||||
}
|
||||
|
||||
dependencies = dependencies.concat([providerSetName]);
|
||||
latest[service] = name;
|
||||
|
@ -32,6 +32,7 @@ define(
|
||||
mockPersistence,
|
||||
mockDomainObject,
|
||||
testModel,
|
||||
testId,
|
||||
decorator;
|
||||
|
||||
beforeEach(function () {
|
||||
@ -41,6 +42,7 @@ define(
|
||||
['getCapabilities']
|
||||
);
|
||||
testModel = { someKey: "some value" };
|
||||
testId = 'someId';
|
||||
mockPersistence = jasmine.createSpyObj(
|
||||
'persistence',
|
||||
['persist', 'refresh']
|
||||
@ -67,9 +69,9 @@ define(
|
||||
// QueuingPersistenceCapability itself, which has its own tests.
|
||||
|
||||
it("delegates to its wrapped service", function () {
|
||||
decorator.getCapabilities(testModel);
|
||||
decorator.getCapabilities(testModel, testId);
|
||||
expect(mockCapabilityService.getCapabilities)
|
||||
.toHaveBeenCalledWith(testModel);
|
||||
.toHaveBeenCalledWith(testModel, testId);
|
||||
});
|
||||
|
||||
it("wraps its persistence capability's constructor", function () {
|
||||
|
@ -18,14 +18,14 @@
|
||||
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.
|
||||
-->
|
||||
-->
|
||||
|
||||
<div class="search-result-item l-flex-row flex-elem grows"
|
||||
ng-class="{selected: ngModel.selectedObject.getId() === domainObject.getId()}">
|
||||
<mct-representation key="'label'"
|
||||
mct-object="domainObject"
|
||||
ng-model="ngModel"
|
||||
ng-click="ngModel.selectedObject = domainObject"
|
||||
ng-click="ngModel.allowSelection(domainObject) && ngModel.onSelection(domainObject)"
|
||||
class="l-flex-row flex-elem grows">
|
||||
</mct-representation>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -139,7 +139,8 @@ define(
|
||||
type = domainObject.getCapability("type"),
|
||||
typeRequest = (type && type.getDefinition().telemetry) || {},
|
||||
modelTelemetry = domainObject.getModel().telemetry,
|
||||
fullRequest = Object.create(typeRequest);
|
||||
fullRequest = Object.create(typeRequest),
|
||||
bounds;
|
||||
|
||||
// Add properties from the telemetry field of this
|
||||
// specific domain object.
|
||||
@ -160,6 +161,12 @@ define(
|
||||
fullRequest.key = domainObject.getId();
|
||||
}
|
||||
|
||||
if (request.start === undefined && request.end === undefined) {
|
||||
bounds = this.openmct.conductor.bounds();
|
||||
fullRequest.start = bounds.start;
|
||||
fullRequest.end = bounds.end;
|
||||
}
|
||||
|
||||
return fullRequest;
|
||||
};
|
||||
|
||||
@ -175,7 +182,7 @@ define(
|
||||
getPointCount: function () {
|
||||
return telemetry.length;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -200,8 +207,8 @@ define(
|
||||
var defaultDomain = (metadata.valuesForHints(['domain'])[0] || {}).key;
|
||||
var defaultRange = (metadata.valuesForHints(['range'])[0] || {}).key;
|
||||
|
||||
var isLegacyProvider = telemetryAPI.findRequestProvider(domainObject)
|
||||
=== telemetryAPI.legacyProvider;
|
||||
var isLegacyProvider = telemetryAPI.findRequestProvider(domainObject) ===
|
||||
telemetryAPI.legacyProvider;
|
||||
|
||||
// Pull out the relevant field from the larger,
|
||||
// structured response.
|
||||
@ -215,7 +222,6 @@ define(
|
||||
return telemetryService.requestTelemetry([fullRequest]);
|
||||
}
|
||||
|
||||
// TODO: Adapt request / options?
|
||||
if (isLegacyProvider) {
|
||||
// If a telemetryService is not available,
|
||||
// getTelemetryService() should reject, and this should
|
||||
@ -263,8 +269,8 @@ define(
|
||||
var defaultDomain = (metadata.valuesForHints(['domain'])[0] || {}).key;
|
||||
var defaultRange = (metadata.valuesForHints(['range'])[0] || {}).key;
|
||||
|
||||
var isLegacyProvider = telemetryAPI.findRequestProvider(domainObject)
|
||||
=== telemetryAPI.legacyProvider;
|
||||
var isLegacyProvider = telemetryAPI.findSubscriptionProvider(domainObject) ===
|
||||
telemetryAPI.legacyProvider;
|
||||
|
||||
function update(telemetry) {
|
||||
callback(asSeries([telemetry], defaultDomain, defaultRange));
|
||||
|
@ -32,8 +32,9 @@ define(
|
||||
mockTelemetryService,
|
||||
mockReject,
|
||||
mockUnsubscribe,
|
||||
telemetry;
|
||||
|
||||
telemetry,
|
||||
mockTelemetryAPI,
|
||||
mockAPI;
|
||||
|
||||
function mockPromise(value) {
|
||||
return {
|
||||
@ -43,6 +44,9 @@ define(
|
||||
};
|
||||
}
|
||||
|
||||
function noop() {
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
mockInjector = jasmine.createSpyObj("$injector", ["get"]);
|
||||
mockQ = jasmine.createSpyObj("$q", ["when", "reject"]);
|
||||
@ -79,7 +83,33 @@ define(
|
||||
// Bubble up...
|
||||
mockReject.then.andReturn(mockReject);
|
||||
|
||||
mockTelemetryAPI = jasmine.createSpyObj("telemetryAPI", [
|
||||
"getMetadata",
|
||||
"subscribe",
|
||||
"request",
|
||||
"findRequestProvider",
|
||||
"findSubscriptionProvider"
|
||||
]);
|
||||
mockTelemetryAPI.getMetadata.andReturn({
|
||||
valuesForHints: function () {
|
||||
return [];
|
||||
}
|
||||
});
|
||||
|
||||
mockAPI = {
|
||||
telemetry: mockTelemetryAPI,
|
||||
conductor: {
|
||||
bounds: function () {
|
||||
return {
|
||||
start: 0,
|
||||
end: 1
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
telemetry = new TelemetryCapability(
|
||||
mockAPI,
|
||||
mockInjector,
|
||||
mockQ,
|
||||
mockLog,
|
||||
@ -113,7 +143,6 @@ define(
|
||||
key: "testKey", // from model
|
||||
start: 42 // from argument
|
||||
}]);
|
||||
|
||||
});
|
||||
|
||||
it("provides an empty series when telemetry is missing", function () {
|
||||
@ -129,7 +158,9 @@ define(
|
||||
expect(telemetry.getMetadata()).toEqual({
|
||||
id: "testId", // from domain object
|
||||
source: "testSource",
|
||||
key: "testKey"
|
||||
key: "testKey",
|
||||
start: 0,
|
||||
end: 1
|
||||
});
|
||||
});
|
||||
|
||||
@ -143,7 +174,9 @@ define(
|
||||
expect(telemetry.getMetadata()).toEqual({
|
||||
id: "testId", // from domain object
|
||||
source: "testSource", // from model
|
||||
key: "testId" // from domain object
|
||||
key: "testId", // from domain object
|
||||
start: 0,
|
||||
end: 1
|
||||
});
|
||||
});
|
||||
|
||||
@ -161,6 +194,57 @@ define(
|
||||
expect(mockLog.warn).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("if a new style telemetry source is available, use it", function () {
|
||||
var mockProvider = {};
|
||||
mockTelemetryAPI.findSubscriptionProvider.andReturn(mockProvider);
|
||||
telemetry.subscribe(noop, {});
|
||||
expect(mockTelemetryService.subscribe).not.toHaveBeenCalled();
|
||||
expect(mockTelemetryAPI.subscribe).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("if a new style telemetry source is not available, revert to old API", function () {
|
||||
mockTelemetryAPI.findSubscriptionProvider.andReturn(undefined);
|
||||
telemetry.subscribe(noop, {});
|
||||
expect(mockTelemetryAPI.subscribe).not.toHaveBeenCalled();
|
||||
expect(mockTelemetryService.subscribe).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("Wraps telemetry returned from the new API as a telemetry series", function () {
|
||||
var returnedTelemetry;
|
||||
var mockTelemetry = [{
|
||||
prop1: "val1",
|
||||
prop2: "val2",
|
||||
prop3: "val3"
|
||||
},
|
||||
{
|
||||
prop1: "val4",
|
||||
prop2: "val5",
|
||||
prop3: "val6"
|
||||
}];
|
||||
var mockProvider = {};
|
||||
var dunzo = false;
|
||||
|
||||
mockTelemetryAPI.findRequestProvider.andReturn(mockProvider);
|
||||
mockTelemetryAPI.request.andReturn(Promise.resolve(mockTelemetry));
|
||||
|
||||
telemetry.requestData({}).then(function (data) {
|
||||
returnedTelemetry = data;
|
||||
dunzo = true;
|
||||
});
|
||||
|
||||
waitsFor(function () {
|
||||
return dunzo;
|
||||
});
|
||||
|
||||
runs(function () {
|
||||
expect(returnedTelemetry.getPointCount).toBeDefined();
|
||||
expect(returnedTelemetry.getDomainValue).toBeDefined();
|
||||
expect(returnedTelemetry.getRangeValue).toBeDefined();
|
||||
expect(returnedTelemetry.getPointCount()).toBe(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it("allows subscriptions to updates", function () {
|
||||
var mockCallback = jasmine.createSpy("callback"),
|
||||
subscription = telemetry.subscribe(mockCallback);
|
||||
@ -171,7 +255,9 @@ define(
|
||||
[{
|
||||
id: "testId", // from domain object
|
||||
source: "testSource",
|
||||
key: "testKey"
|
||||
key: "testKey",
|
||||
start: 0,
|
||||
end: 1
|
||||
}]
|
||||
);
|
||||
|
||||
|
@ -26,14 +26,14 @@ define([], function () {
|
||||
}
|
||||
|
||||
AdapterCompositionPolicy.prototype.allow = function (
|
||||
containerType,
|
||||
childObject
|
||||
parentType,
|
||||
child
|
||||
) {
|
||||
var containerObject = containerType.getInitialModel();
|
||||
var container = parentType.getInitialModel();
|
||||
|
||||
return this.openmct.composition.checkPolicy(
|
||||
containerObject,
|
||||
childObject
|
||||
container,
|
||||
child
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -146,7 +146,7 @@ define([
|
||||
utils.toOldFormat(domainObject),
|
||||
utils.makeKeyString(domainObject.identifier));
|
||||
var limitEvaluator = oldObject.getCapability("limit");
|
||||
|
||||
|
||||
if (!limitEvaluator) {
|
||||
return;
|
||||
}
|
||||
@ -159,8 +159,7 @@ define([
|
||||
};
|
||||
|
||||
return function (openmct, instantiate) {
|
||||
// Push onto the start of the default providers array so that it's
|
||||
// always the last resort
|
||||
// Legacy provider should always be the fallback.
|
||||
var provider = new LegacyTelemetryProvider(openmct, instantiate);
|
||||
openmct.telemetry.legacyProvider = provider;
|
||||
openmct.telemetry.requestProviders.push(provider);
|
||||
|
@ -176,8 +176,9 @@ define([
|
||||
* @private
|
||||
*/
|
||||
TelemetryAPI.prototype.findSubscriptionProvider = function (domainObject) {
|
||||
var args = Array.prototype.slice.apply(arguments);
|
||||
function supportsDomainObject(provider) {
|
||||
return provider.supportsSubscribe(domainObject);
|
||||
return provider.supportsSubscribe.apply(provider, args);
|
||||
}
|
||||
|
||||
return this.subscriptionProviders.filter(supportsDomainObject)[0];
|
||||
@ -187,8 +188,9 @@ define([
|
||||
* @private
|
||||
*/
|
||||
TelemetryAPI.prototype.findRequestProvider = function (domainObject, options) {
|
||||
var args = Array.prototype.slice.apply(arguments);
|
||||
function supportsDomainObject(provider) {
|
||||
return provider.supportsRequest(domainObject);
|
||||
return provider.supportsRequest.apply(provider, args);
|
||||
}
|
||||
|
||||
return this.requestProviders.filter(supportsDomainObject)[0];
|
||||
@ -330,8 +332,7 @@ define([
|
||||
*/
|
||||
TelemetryAPI.prototype.limitEvaluator = function () {
|
||||
return this.legacyProvider.limitEvaluator.apply(this.legacyProvider, arguments);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
return TelemetryAPI;
|
||||
});
|
||||
|
@ -51,7 +51,7 @@ define(['./Type'], function (Type) {
|
||||
* @method addType
|
||||
* @memberof module:openmct.TypeRegistry#
|
||||
*/
|
||||
TypeRegistry.prototype.register = function (typeKey, typeDef) {
|
||||
TypeRegistry.prototype.addType = function (typeKey, typeDef) {
|
||||
this.types[typeKey] = new Type(typeDef);
|
||||
};
|
||||
|
||||
|
@ -23,24 +23,26 @@
|
||||
define([
|
||||
'lodash',
|
||||
'../../platform/features/conductor/utcTimeSystem/src/UTCTimeSystem',
|
||||
'./generator/plugin'
|
||||
'../../example/generator/plugin'
|
||||
], function (
|
||||
_,
|
||||
UTCTimeSystem,
|
||||
GeneratorPlugin
|
||||
) {
|
||||
var bundleMap = {
|
||||
couchDB: 'platform/persistence/couch',
|
||||
elasticsearch: 'platform/persistence/elastic',
|
||||
espresso: 'platform/commonUI/themes/espresso',
|
||||
localStorage: 'platform/persistence/local',
|
||||
myItems: 'platform/features/my-items',
|
||||
snow: 'platform/commonUI/themes/snow'
|
||||
CouchDB: 'platform/persistence/couch',
|
||||
Elasticsearch: 'platform/persistence/elastic',
|
||||
Espresso: 'platform/commonUI/themes/espresso',
|
||||
LocalStorage: 'platform/persistence/local',
|
||||
MyItems: 'platform/features/my-items',
|
||||
Snow: 'platform/commonUI/themes/snow'
|
||||
};
|
||||
|
||||
var plugins = _.mapValues(bundleMap, function (bundleName, pluginName) {
|
||||
return function (openmct) {
|
||||
openmct.legacyRegistry.enable(bundleName);
|
||||
return function pluginConstructor() {
|
||||
return function (openmct) {
|
||||
openmct.legacyRegistry.enable(bundleName);
|
||||
};
|
||||
};
|
||||
});
|
||||
|
||||
@ -50,47 +52,59 @@ define([
|
||||
"implementation": UTCTimeSystem,
|
||||
"depends": ["$timeout"]
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
var conductorInstalled = false;
|
||||
|
||||
plugins.Conductor = function (options) {
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
|
||||
function applyDefaults(openmct, timeConductorViewService) {
|
||||
var defaults = {};
|
||||
var timeSystem = timeConductorViewService.systems.find(function (ts) {
|
||||
return ts.metadata.key === options.defaultTimeSystem;
|
||||
});
|
||||
if (timeSystem !== undefined) {
|
||||
defaults = timeSystem.defaults();
|
||||
|
||||
if (options.defaultTimespan !== undefined) {
|
||||
defaults.deltas.start = options.defaultTimespan;
|
||||
defaults.bounds.start = defaults.bounds.end - options.defaultTimespan;
|
||||
timeSystem.defaults(defaults);
|
||||
}
|
||||
|
||||
openmct.conductor.timeSystem(timeSystem, defaults.bounds);
|
||||
}
|
||||
}
|
||||
|
||||
return function (openmct) {
|
||||
openmct.legacyExtension('constants', {
|
||||
key: 'DEFAULT_TIMECONDUCTOR_MODE',
|
||||
value: options.showConductor ? 'fixed' : 'realtime',
|
||||
priority: 'mandatory'
|
||||
});
|
||||
openmct.legacyExtension('constants', {
|
||||
key: 'SHOW_TIMECONDUCTOR',
|
||||
value: options.showConductor,
|
||||
priority: 'mandatory'
|
||||
priority: conductorInstalled ? 'mandatory' : 'fallback'
|
||||
});
|
||||
if (options.showConductor !== undefined) {
|
||||
openmct.legacyExtension('constants', {
|
||||
key: 'SHOW_TIMECONDUCTOR',
|
||||
value: options.showConductor,
|
||||
priority: conductorInstalled ? 'mandatory' : 'fallback'
|
||||
});
|
||||
}
|
||||
if (options.defaultTimeSystem !== undefined || options.defaultTimespan !== undefined) {
|
||||
openmct.legacyExtension('runs', {
|
||||
implementation: function (openmct, $timeout, timeConductorViewService) {
|
||||
var timeSystem = timeConductorViewService.systems.find(function (ts) {
|
||||
return ts.metadata.key === options.defaultTimeSystem;
|
||||
});
|
||||
if (options.defaultTimespan !== undefined && timeSystem !== undefined) {
|
||||
var defaults = timeSystem.defaults();
|
||||
defaults.deltas.start = options.defaultTimespan;
|
||||
defaults.bounds.start = defaults.bounds.end - options.defaultTimespan;
|
||||
timeSystem.defaults(defaults);
|
||||
}
|
||||
if (timeSystem!== undefined) {
|
||||
openmct.conductor.timeSystem(timeSystem, defaults.bounds);
|
||||
}
|
||||
},
|
||||
depends: ["openmct", "$timeout", "timeConductorViewService"]
|
||||
implementation: applyDefaults,
|
||||
depends: ["openmct", "timeConductorViewService"]
|
||||
});
|
||||
}
|
||||
|
||||
openmct.legacyRegistry.enable('platform/features/conductor/core');
|
||||
openmct.legacyRegistry.enable('platform/features/conductor/compatibility');
|
||||
if (!conductorInstalled) {
|
||||
openmct.legacyRegistry.enable('platform/features/conductor/core');
|
||||
openmct.legacyRegistry.enable('platform/features/conductor/compatibility');
|
||||
}
|
||||
conductorInstalled = true;
|
||||
};
|
||||
};
|
||||
|
||||
@ -112,7 +126,7 @@ define([
|
||||
openmct.legacyRegistry.enable(bundleName);
|
||||
}
|
||||
|
||||
openmct.legacyRegistry.enable(bundleMap.couchDB);
|
||||
openmct.legacyRegistry.enable(bundleMap.CouchDB);
|
||||
};
|
||||
};
|
||||
|
||||
@ -134,7 +148,7 @@ define([
|
||||
openmct.legacyRegistry.enable(bundleName);
|
||||
}
|
||||
|
||||
openmct.legacyRegistry.enable(bundleMap.elasticsearch);
|
||||
openmct.legacyRegistry.enable(bundleMap.Elasticsearch);
|
||||
};
|
||||
};
|
||||
|
||||
|
Reference in New Issue
Block a user