Compare commits
2 Commits
api-draft
...
prototype-
Author | SHA1 | Date | |
---|---|---|---|
5013646e89 | |||
9925b91405 |
9
.gitignore
vendored
@ -4,11 +4,8 @@
|
||||
*.tgz
|
||||
*.DS_Store
|
||||
|
||||
# Compiled CSS, unless directly added
|
||||
*.sass-cache
|
||||
*COMPILE.css
|
||||
*.css
|
||||
*.css.map
|
||||
|
||||
# Intellij project configuration files
|
||||
*.idea
|
||||
@ -18,7 +15,6 @@
|
||||
|
||||
# Build output
|
||||
target
|
||||
dist
|
||||
|
||||
# Mac OS X Finder
|
||||
.DS_Store
|
||||
@ -26,12 +22,9 @@ dist
|
||||
# Closed source libraries
|
||||
closed-lib
|
||||
|
||||
# Node, Bower dependencies
|
||||
# Node dependencies
|
||||
node_modules
|
||||
bower_components
|
||||
|
||||
# Protractor logs
|
||||
protractor/logs
|
||||
|
||||
# npm-debug log
|
||||
npm-debug.log
|
||||
|
35
.npmignore
@ -1,35 +0,0 @@
|
||||
*.scssc
|
||||
*.zip
|
||||
*.gzip
|
||||
*.tgz
|
||||
*.DS_Store
|
||||
|
||||
*.sass-cache
|
||||
*COMPILE.css
|
||||
|
||||
# Intellij project configuration files
|
||||
*.idea
|
||||
*.iml
|
||||
|
||||
# External dependencies
|
||||
|
||||
# Build output
|
||||
target
|
||||
|
||||
# Mac OS X Finder
|
||||
.DS_Store
|
||||
|
||||
# Closed source libraries
|
||||
closed-lib
|
||||
|
||||
# Node, Bower dependencies
|
||||
node_modules
|
||||
bower_components
|
||||
|
||||
Procfile
|
||||
|
||||
# Protractor logs
|
||||
protractor/logs
|
||||
|
||||
# npm-debug log
|
||||
npm-debug.log
|
@ -291,7 +291,7 @@ checklist.)
|
||||
1. Changes address original issue?
|
||||
2. Unit tests included and/or updated with changes?
|
||||
3. Command line build passes?
|
||||
4. Changes have been smoke-tested?
|
||||
4. Expect to pass code review?
|
||||
|
||||
### Reviewer Checklist
|
||||
|
||||
|
215
LICENSES.md
@ -135,7 +135,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
* Link: http://requirejs.org/
|
||||
|
||||
* Version: 2.1.22
|
||||
* Version: 2.1.9
|
||||
|
||||
* Author: The Dojo Foundation
|
||||
|
||||
@ -153,49 +153,13 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
---
|
||||
|
||||
### requirejs-text
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: https://github.com/requirejs/text
|
||||
|
||||
* Version: 2.0.14
|
||||
|
||||
* Author: The Dojo Foundation
|
||||
|
||||
* Description: Text loading plugin for RequireJS
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2010-2014, The Dojo Foundation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### AngularJS
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: http://angularjs.org/
|
||||
|
||||
* Version: 1.4.4
|
||||
* Version: 1.2.26
|
||||
|
||||
* Author: Google
|
||||
|
||||
@ -203,7 +167,7 @@ THE SOFTWARE.
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
|
||||
Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
@ -219,7 +183,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
* Link: http://angularjs.org/
|
||||
|
||||
* Version: 1.4.4
|
||||
* Version: 1.2.26
|
||||
|
||||
* Author: Google
|
||||
|
||||
@ -227,7 +191,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
|
||||
Copyright (c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
@ -243,7 +207,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
* Link: https://github.com/jakearchibald/es6-promise
|
||||
|
||||
* Version: 3.0.2
|
||||
* Version: 2.0.0
|
||||
|
||||
* Authors: Yehuda Katz, Tom Dale, Stefan Penner and contributors
|
||||
|
||||
@ -267,7 +231,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
* Link: https://github.com/sindresorhus/screenfull.js/
|
||||
|
||||
* Version: 3.0.0
|
||||
* Version: 1.2.0
|
||||
|
||||
* Author: Sindre Sorhus
|
||||
|
||||
@ -291,15 +255,39 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
* Link: https://github.com/broofa/node-uuid
|
||||
|
||||
* Version: 1.4.7
|
||||
* Version: 1.4
|
||||
|
||||
* Author: Robert Kieffer
|
||||
|
||||
* Description: Unique identifer generation.
|
||||
* Description: Unique identifer generation (code adapted.)
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2010-2012 Robert Kieffer
|
||||
Copyright (c) 2010 Robert Kieffer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### Modernizr
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: http://modernizr.com
|
||||
|
||||
* Version: 2.6.2
|
||||
|
||||
* Author: Faruk Ateş
|
||||
|
||||
* Description: Browser/device capability finding
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2009–2015
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
@ -339,7 +327,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
* Link: http://momentjs.com
|
||||
|
||||
* Version: 2.11.1
|
||||
* Version: 2.7.0
|
||||
|
||||
* Authors: Tim Wood, Iskren Chernev, Moment.js contributors
|
||||
|
||||
@ -357,139 +345,6 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||
|
||||
---
|
||||
|
||||
### moment-duration-format
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: https://github.com/jsmreese/moment-duration-format
|
||||
|
||||
* Version: 1.3.0
|
||||
|
||||
* Authors: John Madhavan-Reese
|
||||
|
||||
* Description: Duration parsing/formatting
|
||||
|
||||
#### License
|
||||
|
||||
Copyright 2014 John Madhavan-Reese
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### CSV.js
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: https://github.com/knrz/CSV.js
|
||||
|
||||
* Version: 3.6.4
|
||||
|
||||
* Authors: Kash Nouroozi
|
||||
|
||||
* Description: Encoder for CSV (comma separated values) export
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2014 Kash Nouroozi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### FileSaver.js
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: https://github.com/eligrey/FileSaver.js/
|
||||
|
||||
* Version: 0.0.2
|
||||
|
||||
* Authors: Eli Grey
|
||||
|
||||
* Description: File download initiator (for file exports)
|
||||
|
||||
#### License
|
||||
|
||||
Copyright © 2015 Eli Grey.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### Zepto
|
||||
|
||||
#### Info
|
||||
|
||||
* Link: http://zeptojs.com/
|
||||
|
||||
* Version: 1.1.6
|
||||
|
||||
* Authors: Thomas Fuchs
|
||||
|
||||
* Description: DOM manipulation
|
||||
|
||||
#### License
|
||||
|
||||
Copyright (c) 2010-2016 Thomas Fuchs
|
||||
http://zeptojs.com/
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
---
|
||||
|
||||
### Json.NET
|
||||
|
||||
#### Info
|
||||
|
2
Procfile
@ -1 +1 @@
|
||||
web: node app.js --port $PORT
|
||||
web: node app.js --port $PORT --include example/localstorage
|
103
README.md
@ -20,32 +20,58 @@ directory names) to include in a running instance of Open MCT Web. Adding or
|
||||
removing paths from this list will add or remove bundles from the running
|
||||
application.
|
||||
|
||||
### Bundle Contents
|
||||
|
||||
A bundle directory will contain:
|
||||
|
||||
* `bundle.json`, the declaration of the bundles contents.
|
||||
* A source code directory, named `src` by convention. This contains all
|
||||
JavaScript sources exposed by the bundle. These are declared as
|
||||
AMD modules.
|
||||
* A directory for other resources, named `res` by convention. This
|
||||
contains all HTML templates, CSS files, images, and so forth to be
|
||||
used within a given bundle.
|
||||
* A library directory, named `lib` by convention. This contains all
|
||||
external libraries used and/or exposed by the bundle.
|
||||
* A test directory, named `test` by convention. This contains all unit
|
||||
tests declared for the bundle, as well as a `suite.json` that acts
|
||||
as a listing of these dependencies. See the section on unit testing
|
||||
below.
|
||||
|
||||
Following these bundle conventions is required, at present, to ensure
|
||||
that Open MCT Web (and its build and tests) execute correctly.
|
||||
|
||||
## Tests
|
||||
|
||||
Tests are written for [Jasmine 1.3](http://jasmine.github.io/1.3/introduction.html)
|
||||
and run by [Karma](http://karma-runner.github.io). To run:
|
||||
The repository for Open MCT Web includes a test suite that can be run
|
||||
directly from the web browser, `test.html`. This page will:
|
||||
|
||||
`npm test`
|
||||
* Load `bundles.json` to determine which bundles are in the application.
|
||||
* Load `test/suite.json` to determine which source files are to be tested.
|
||||
This should contain an array of strings, where each is the name of an
|
||||
AMD module in the bundle's source directory. For each source file:
|
||||
* Code coverage instrumentation will be added, via Blanket.
|
||||
* The associated test file will be loaded, via RequireJS. These will
|
||||
be located in the bundle's test folder; the test runner will presume
|
||||
these follow a naming convention where each module to be tested has a
|
||||
corresponding test module with the suffix `Spec` in that folder.
|
||||
* Jasmine will then be invoked to run all tests defined in the loaded
|
||||
test modules. Code coverage reporting will be displayed at the bottom
|
||||
of the test page.
|
||||
|
||||
The test suite is configured to load any scripts ending with `Spec.js` found
|
||||
in the `src` hierarchy. Full configuration details are found in
|
||||
`karma.conf.js`. By convention, unit test scripts should be located
|
||||
alongside the units that they test; for example, `src/foo/Bar.js` would be
|
||||
tested by `src/foo/BarSpec.js`. (For legacy reasons, some existing tests may
|
||||
be located in separate `test` folders near the units they test, but the
|
||||
naming convention is otherwise the same.)
|
||||
|
||||
### Test Reporting
|
||||
|
||||
When `npm test` is run, test results will be written as HTML to
|
||||
`target/tests`. Code coverage information is written to `target/coverage`.
|
||||
At present, the test runner presumes that bundle conventions are followed
|
||||
as above; that is, sources are contained in `src`, and tests are contained
|
||||
in `test`. Additionally, individual test files must use the `Spec` suffix
|
||||
as described above.
|
||||
|
||||
An example of this is expressed in `platform/framework`, which follows
|
||||
bundle conventions.
|
||||
|
||||
### Functional Testing
|
||||
|
||||
The tests described above are all at the unit-level; an additional
|
||||
test suite using [Protractor](https://angular.github.io/protractor/)
|
||||
is under development, in the `protractor` folder.
|
||||
us under development, in the `protractor` folder.
|
||||
|
||||
To run:
|
||||
|
||||
@ -56,36 +82,41 @@ To run:
|
||||
|
||||
## Build
|
||||
|
||||
Open MCT Web is built using [`npm`](http://npmjs.com/)
|
||||
and [`gulp`](http://gulpjs.com/).
|
||||
Open MCT Web includes a Maven command line build. Although Open MCT Web
|
||||
can be run as-is using the repository contents (that is, by viewing
|
||||
`index.html` in a web browser), and its tests can be run in-place
|
||||
similarly (that is, by viewing `test.html` in a browser), the command
|
||||
line build allows machine-driven verification and packaging.
|
||||
|
||||
To build:
|
||||
This build will:
|
||||
|
||||
`npm run prepublish`
|
||||
* Check all sources (excluding those in directories named `lib`) with
|
||||
JSLint for code style compliance. The build will fail if any sources
|
||||
do not satisfy JSLint.
|
||||
* Run unit tests. This is done by running `test.html` in a PhantomJS
|
||||
browser-like environment. The build will fail if any tests fail.
|
||||
* Package the application as a `war` (web archive) file. This is
|
||||
convenient for deployment on Tomcat or similar. This archive will
|
||||
include sources, resources, and libraries for bundles, as well
|
||||
as the top-level files used to initiate running of the application
|
||||
(`index.html` and `bundles.json`).
|
||||
|
||||
This will compile and minify JavaScript sources, as well as copy over assets.
|
||||
The contents of the `dist` folder will contain a runnable Open MCT Web
|
||||
instance (e.g. by starting an HTTP server in that directory), including:
|
||||
|
||||
* A `main.js` file containing Open MCT Web source code.
|
||||
* Various assets in the `example` and `platform` directories.
|
||||
* An `index.html` that runs Open MCT Web in its default configuration.
|
||||
|
||||
Additional `gulp` tasks are defined in [the gulpfile](gulpfile.js).
|
||||
Run as `mvn clean install`.
|
||||
|
||||
### Building Documentation
|
||||
|
||||
Open MCT Web's documentation is generated by an
|
||||
[npm](https://www.npmjs.com/)-based build. It has additional dependencies that
|
||||
may not be available on every platform and thus is not covered in the standard
|
||||
npm install. Ensure your system has [libcairo](http://cairographics.org/)
|
||||
installed and then run the following commands:
|
||||
[npm](https://www.npmjs.com/)-based build:
|
||||
|
||||
* `npm install`
|
||||
* `npm install canvas nomnoml`
|
||||
* `npm install` _(only needs to run once)_
|
||||
* `npm run docs`
|
||||
|
||||
Documentation will be generated in `target/docs`.
|
||||
Documentation will be generated in `target/docs`. Note that diagram
|
||||
generation is dependent on having [Cairo](http://cairographics.org/download/)
|
||||
installed; see
|
||||
[node-canvas](https://github.com/Automattic/node-canvas#installation)'s
|
||||
documentation for help with installation.
|
||||
|
||||
|
||||
# Glossary
|
||||
|
||||
|
@ -1,20 +0,0 @@
|
||||
# API
|
||||
|
||||
This directory is for draft API documentation and design. The API is organized into a few major components, which are documented in their own READMEs. See the following:
|
||||
|
||||
* Domain Objects
|
||||
Capabilities
|
||||
Events
|
||||
Mutation
|
||||
Etc
|
||||
|
||||
* [Object API](object-api/README.md) (encapsulates persistence), should include roots
|
||||
* [Region API](region-api/README.md)
|
||||
* [Telemetry API](telemetry-api/README.md)
|
||||
* [Type API](type-api/README.md)
|
||||
|
||||
Not yet started:
|
||||
|
||||
* [Action API](action-api/README.md)
|
||||
* [Indicators API](indicators-api/README.md) -- potentially compress into regions?
|
||||
* [Plugin API](plugin-api/README.md)
|
@ -1,93 +0,0 @@
|
||||
define([
|
||||
|
||||
], function (
|
||||
|
||||
) {
|
||||
|
||||
|
||||
var PROVIDER_REGISTRY = [];
|
||||
|
||||
function getProvider (object) {
|
||||
return PROVIDER_REGISTRY.filter(function (p) {
|
||||
return p.appliesTo(object);
|
||||
})[0];
|
||||
};
|
||||
|
||||
function composition(object) {
|
||||
var provider = getProvider(object);
|
||||
|
||||
if (!provider) {
|
||||
return;
|
||||
}
|
||||
|
||||
return new CompositionCollection(object, provider);
|
||||
};
|
||||
|
||||
composition.addProvider = function (provider) {
|
||||
PROVIDER_REGISTRY.unshift(provider);
|
||||
};
|
||||
|
||||
window.MCT = window.MCT || {};
|
||||
window.MCT.composition = composition;
|
||||
|
||||
function CompositionCollection(domainObject, provider) {
|
||||
this.domainObject = domainObject;
|
||||
this.provider = provider;
|
||||
};
|
||||
|
||||
CompositionCollection.prototype.add = function (child, skipMutate) {
|
||||
if (!this._children) {
|
||||
throw new Error("Must load composition before you can add!");
|
||||
}
|
||||
// we probably should not add until we have loaded.
|
||||
// todo: should we modify parent?
|
||||
if (!skipMutate) {
|
||||
this.provider.add(this.domainObject, child);
|
||||
}
|
||||
this.children.push(child);
|
||||
this.emit('add', child);
|
||||
};
|
||||
|
||||
CompositionCollection.prototype.load = function () {
|
||||
return this.provider.load(this.domainObject)
|
||||
.then(function (children) {
|
||||
this._children = [];
|
||||
children.map(function (c) {
|
||||
this.add(c, true);
|
||||
}, this);
|
||||
this.emit('load');
|
||||
// Todo: set up listener for changes via provider?
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
CompositionCollection.prototype.remove = function (child) {
|
||||
var index = this.children.indexOf(child);
|
||||
if (index === -1) {
|
||||
throw new Error("Unable to remove child: not found in composition");
|
||||
}
|
||||
this.provider.remove(this.domainObject, child);
|
||||
this.children.splice(index, 1);
|
||||
this.emit('remove', index, child);
|
||||
};
|
||||
|
||||
var DefaultCompositionProvider = {
|
||||
appliesTo: function (domainObject) {
|
||||
return !!domainObject.composition;
|
||||
},
|
||||
load: function (domainObject) {
|
||||
return Promise.all(domainObject.composition.map(MCT.objects.get));
|
||||
},
|
||||
add: function (domainObject, child) {
|
||||
domainObject.composition.push(child.key);
|
||||
}
|
||||
};
|
||||
|
||||
composition.addProvider(DefaultCompositionProvider);
|
||||
|
||||
function Injector() {
|
||||
console.log('composition api injected!');
|
||||
}
|
||||
|
||||
return Injector;
|
||||
|
||||
});
|
@ -1,35 +0,0 @@
|
||||
# Composition API - Overview
|
||||
|
||||
The composition API is straightforward:
|
||||
|
||||
MCT.composition(object) -- returns a `CompositionCollection` if the object has
|
||||
composition, returns undefined if it doesn't.
|
||||
|
||||
## CompositionCollection
|
||||
|
||||
Has three events:
|
||||
* `load`: when the collection has completed loading.
|
||||
* `add`: when a new object has been added to the collection.
|
||||
* `remove` when an object has been removed from the collection.
|
||||
|
||||
Has three methods:
|
||||
|
||||
`Collection.load()` -- returns a promise that is fulfilled when the composition
|
||||
has loaded.
|
||||
`Collection.add(object)` -- add a domain object to the composition.
|
||||
`Collection.remove(object)` -- remove the object from the composition.
|
||||
|
||||
## Composition providers
|
||||
composition providers are anything that meets the following interface:
|
||||
|
||||
* `provider.appliesTo(domainObject)` -> return true if this provider can provide
|
||||
composition for a given domain object.
|
||||
* `provider.add(domainObject, childObject)` -> adds object
|
||||
* `provider.remove(domainObject, childObject)` -> immediately removes objects
|
||||
* `provider.load(domainObject)` -> returns promise for array of children
|
||||
|
||||
There is a default composition provider which handles loading composition for
|
||||
any object with a `composition` property. If you want specialized composition
|
||||
loading behavior, implement your own composition provider and register it with
|
||||
|
||||
`MCT.composition.addProvider(myProvider)`
|
@ -1,47 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'./CompositionAPI',
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
CompositionAPI,
|
||||
legacyRegistry
|
||||
) {
|
||||
legacyRegistry.register('api/composition-api', {
|
||||
name: 'Composition API',
|
||||
description: 'The public Composition API',
|
||||
extensions: {
|
||||
runs: [
|
||||
{
|
||||
key: "CompositionAPI",
|
||||
priority: "mandatory",
|
||||
implementation: CompositionAPI,
|
||||
depends: [
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
});
|
@ -1,200 +0,0 @@
|
||||
define([
|
||||
'lodash'
|
||||
], function (
|
||||
_
|
||||
) {
|
||||
|
||||
/**
|
||||
Object API. Intercepts the existing object API while also exposing
|
||||
A new Object API.
|
||||
|
||||
MCT.objects.get('mine')
|
||||
.then(function (root) {
|
||||
console.log(root);
|
||||
MCT.objects.getComposition(root)
|
||||
.then(function (composition) {
|
||||
console.log(composition)
|
||||
})
|
||||
});
|
||||
*/
|
||||
|
||||
var Objects = {},
|
||||
ROOT_REGISTRY = [],
|
||||
PROVIDER_REGISTRY = {},
|
||||
FALLBACK_PROVIDER;
|
||||
|
||||
window.MCT = window.MCT || {};
|
||||
window.MCT.objects = Objects;
|
||||
|
||||
// take a key string and turn it into a key object
|
||||
// 'scratch:root' ==> {namespace: 'scratch', identifier: 'root'}
|
||||
function parseKeyString(key) {
|
||||
if (typeof key === 'object') {
|
||||
return key;
|
||||
}
|
||||
var namespace = '',
|
||||
identifier = key;
|
||||
for (var i = 0, escaped = false, len=key.length; i < len; i++) {
|
||||
if (key[i] === ":" && !escaped) {
|
||||
namespace = key.slice(0, i);
|
||||
identifier = key.slice(i + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {
|
||||
namespace: namespace,
|
||||
identifier: identifier
|
||||
};
|
||||
};
|
||||
|
||||
// take a key and turn it into a key string
|
||||
// {namespace: 'scratch', identifier: 'root'} ==> 'scratch:root'
|
||||
function makeKeyString(key) {
|
||||
if (typeof key === 'string') {
|
||||
return key;
|
||||
}
|
||||
if (!key.namespace) {
|
||||
return key.identifier;
|
||||
}
|
||||
return [
|
||||
key.namespace.replace(':', '\\:'),
|
||||
key.identifier.replace(':', '\\:')
|
||||
].join(':');
|
||||
};
|
||||
|
||||
// Converts composition to use key strings instead of keys
|
||||
function toOldFormat(model) {
|
||||
delete model.key;
|
||||
if (model.composition) {
|
||||
model.composition = model.composition.map(makeKeyString);
|
||||
}
|
||||
return model;
|
||||
};
|
||||
|
||||
// converts composition to use keys instead of key strings
|
||||
function toNewFormat(model, key) {
|
||||
model.key = key;
|
||||
if (model.composition) {
|
||||
model.composition = model.composition.map(parseKeyString);
|
||||
}
|
||||
return model;
|
||||
};
|
||||
|
||||
// Root provider is hardcoded in; can't be skipped.
|
||||
var RootProvider = {
|
||||
'get': function () {
|
||||
return Promise.resolve({
|
||||
name: 'The root object',
|
||||
type: 'root',
|
||||
composition: ROOT_REGISTRY
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// Retrieve the provider for a given key.
|
||||
function getProvider(key) {
|
||||
if (key.identifier === 'ROOT') {
|
||||
return RootProvider;
|
||||
}
|
||||
return PROVIDER_REGISTRY[key.namespace] || FALLBACK_PROVIDER;
|
||||
};
|
||||
|
||||
Objects.addProvider = function (namespace, provider) {
|
||||
PROVIDER_REGISTRY[namespace] = provider;
|
||||
};
|
||||
|
||||
[
|
||||
'save',
|
||||
'delete',
|
||||
'get'
|
||||
].forEach(function (method) {
|
||||
Objects[method] = function () {
|
||||
var key = arguments[0],
|
||||
provider = getProvider(key);
|
||||
|
||||
if (!provider) {
|
||||
throw new Error('No Provider Matched');
|
||||
}
|
||||
|
||||
if (!provider[method]) {
|
||||
throw new Error('Provider does not support [' + method + '].');
|
||||
}
|
||||
|
||||
return provider[method].apply(provider, arguments);
|
||||
};
|
||||
});
|
||||
|
||||
Objects.addRoot = function (key) {
|
||||
ROOT_REGISTRY.unshift(key);
|
||||
};
|
||||
|
||||
Objects.removeRoot = function (key) {
|
||||
ROOT_REGISTRY = ROOT_REGISTRY.filter(function (k) {
|
||||
return (
|
||||
k.identifier !== key.identifier ||
|
||||
k.namespace !== key.namespace
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
function ObjectServiceProvider(objectService, instantiate) {
|
||||
this.objectService = objectService;
|
||||
this.instantiate = instantiate;
|
||||
}
|
||||
|
||||
ObjectServiceProvider.prototype.save = function (object) {
|
||||
var key = object.key,
|
||||
keyString = makeKeyString(key),
|
||||
newObject = this.instantiate(toOldFormat(object), keyString);
|
||||
|
||||
return object.getCapability('persistence')
|
||||
.persist()
|
||||
.then(function () {
|
||||
return toNewFormat(object, key);
|
||||
});
|
||||
};
|
||||
|
||||
ObjectServiceProvider.prototype.delete = function (object) {
|
||||
// TODO!
|
||||
};
|
||||
|
||||
ObjectServiceProvider.prototype.get = function (key) {
|
||||
var keyString = makeKeyString(key);
|
||||
return this.objectService.getObjects([keyString])
|
||||
.then(function (results) {
|
||||
var model = JSON.parse(JSON.stringify(results[keyString].getModel()));
|
||||
return toNewFormat(model, key);
|
||||
});
|
||||
};
|
||||
|
||||
// Injects new object API as a decorator so that it hijacks all requests.
|
||||
// Object providers implemented on new API should just work, old API should just work, many things may break.
|
||||
function ObjectAPIInjector(ROOTS, instantiate, objectService) {
|
||||
this.getObjects = function (keys) {
|
||||
var results = {},
|
||||
promises = keys.map(function (keyString) {
|
||||
var key = parseKeyString(keyString);
|
||||
return Objects.get(key)
|
||||
.then(function (object) {
|
||||
object = toOldFormat(object)
|
||||
results[keyString] = instantiate(object, keyString);
|
||||
});
|
||||
});
|
||||
|
||||
return Promise.all(promises)
|
||||
.then(function () {
|
||||
return results;
|
||||
});
|
||||
};
|
||||
|
||||
FALLBACK_PROVIDER = new ObjectServiceProvider(objectService, instantiate);
|
||||
|
||||
ROOTS.forEach(function (r) {
|
||||
ROOT_REGISTRY.push(parseKeyString(r.id));
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
return ObjectAPIInjector;
|
||||
});
|
@ -1,101 +0,0 @@
|
||||
# Object API - Overview
|
||||
|
||||
The object API provides methods for fetching domain objects.
|
||||
|
||||
# Keys
|
||||
Keys are a composite identifier that is used to create and persist objects. Ex:
|
||||
```javascript
|
||||
{
|
||||
namespace: 'elastic',
|
||||
identifier: 'myIdentifier'
|
||||
}
|
||||
```
|
||||
|
||||
In old MCT days, we called this an "id", and we encoded it in a single string.
|
||||
The above key would encode into the identifier, `elastic:myIdentifier`.
|
||||
|
||||
When interacting with the API you will be dealing with key objects.
|
||||
|
||||
# Configuring the Object API
|
||||
|
||||
The following methods should be used before calling run. They allow you to
|
||||
configure the persistence space of MCT.
|
||||
|
||||
* `MCT.objects.addRoot(key)` -- add a "ROOT" to Open MCT by specifying it's
|
||||
key.
|
||||
* `MCT.objects.removeRoot(key)` -- Remove a "ROOT" from Open MCT by key.
|
||||
* `MCT.objects.addProvider(namespace, provider)` -- register an object provider
|
||||
for a specific namespace. See below for documentation on the provider
|
||||
interface.
|
||||
|
||||
# Using the object API
|
||||
|
||||
The object API provides methods for getting, saving, and deleting objects.
|
||||
|
||||
* MCT.objects.get(key) -> returns promise for an object
|
||||
* MCT.objects.save(object) -> returns promise that is resolved when object
|
||||
has been saved
|
||||
* MCT.objects.delete(object) -> returns promise that is resolved when object has
|
||||
been deleted
|
||||
|
||||
## Configuration Example: Adding a groot
|
||||
|
||||
The following example adds a new root object for groot and populates it with
|
||||
some pieces of groot.
|
||||
|
||||
```javascript
|
||||
|
||||
var ROOT_KEY = {
|
||||
namespace: 'groot',
|
||||
identifier: 'groot'
|
||||
};
|
||||
|
||||
var GROOT_ROOT = {
|
||||
name: 'I am groot',
|
||||
type: 'folder',
|
||||
composition: [
|
||||
{
|
||||
namespace: 'groot',
|
||||
identifier: 'arms'
|
||||
},
|
||||
{
|
||||
namespace: 'groot',
|
||||
identifier: 'legs'
|
||||
},
|
||||
{
|
||||
namespace: 'groot',
|
||||
identifier: 'torso'
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
var GrootProvider = {
|
||||
get: function (key) {
|
||||
if (key.identifier === 'groot') {
|
||||
return Promise.resolve(GROOT_ROOT);
|
||||
}
|
||||
return Promise.resolve({
|
||||
name: 'Groot\'s ' + key.identifier
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
MCT.objects.addRoot(ROOT_KEY);
|
||||
|
||||
MCT.objects.addProvider('groot', GrootProvider);
|
||||
|
||||
MCT.run();
|
||||
```
|
||||
|
||||
### Making a custom provider:
|
||||
|
||||
All methods on the provider interface are optional, so you do not need
|
||||
to modify them.
|
||||
|
||||
* `provider.get(key)` -> promise for a domain object.
|
||||
* `provider.save(domainObject)` -> returns promise that is fulfilled when object
|
||||
has been saved.
|
||||
* `provider.delete(domainObject)` -> returns promise that is fulfilled when
|
||||
object has been deleted.
|
||||
|
||||
|
@ -1,50 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'./ObjectAPI',
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ObjectAPI,
|
||||
legacyRegistry
|
||||
) {
|
||||
legacyRegistry.register('api/object-api', {
|
||||
name: 'Object API',
|
||||
description: 'The public Objects API',
|
||||
extensions: {
|
||||
components: [
|
||||
{
|
||||
provides: "objectService",
|
||||
type: "decorator",
|
||||
priority: "mandatory",
|
||||
implementation: ObjectAPI,
|
||||
depends: [
|
||||
"roots[]",
|
||||
"instantiate"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
});
|
@ -1,64 +0,0 @@
|
||||
# Region API - Overview
|
||||
|
||||
The region API provides a method for specifying which views should display in a given region for a given domain object. As such, they also define the basic view interface that components must define.
|
||||
|
||||
### MCT.region.Region
|
||||
|
||||
The base region type, all regions implement this interface.
|
||||
|
||||
`register(view)`
|
||||
|
||||
`getViews(domainObject)`
|
||||
|
||||
Additionally, Regions may have subregions for different modes of the application. Specifying a view for a region
|
||||
|
||||
### MCT.region.View
|
||||
|
||||
The basic type for views. You can extend this to implement your own functionality, or you can create your own object so long as it meets the interface.
|
||||
|
||||
`attribute` | `type` | `note`
|
||||
--- | --- | ---
|
||||
`label` | `string` or `Function` | The name of the view. Used in the view selector when more than one view exists for an object.
|
||||
`glyph` | `string` or `Function` | The glyph to associate with this view. Used in the view selector when more than one view exists for an object.
|
||||
`instantiate` | `Function` | constructor for a view. Will be invoked with two arguments, `container` and `domainObject`. It should return an object with a `destroy` method that is called when the view is removed.
|
||||
`appliesTo` | `Function` | Determines if a view applies to a specific domain object. Will be invoked with a domainObject. Should return a number, `priority` if the view applies to a given object. If multiple views return a truthy value for a given object, they will be ordered by priority, and the largest priority value will be the default view for the object. Return `false` if a view should not apply to an object.
|
||||
|
||||
Basic Hello World:
|
||||
|
||||
```javascript
|
||||
|
||||
function HelloWorldView(container, domainObject) {
|
||||
container.innerHTML = 'Hello World!';
|
||||
}
|
||||
|
||||
HelloWorldView.label = 'Hello World';
|
||||
HelloWorldView.glyph = 'whatever';
|
||||
|
||||
HelloWorldView.appliesTo = function (domainObject) {
|
||||
return 10;
|
||||
};
|
||||
|
||||
HelloWorldView.prototype.destroy = function () {
|
||||
// clean up outstanding handlers;
|
||||
};
|
||||
|
||||
MCT.regions.Main.register(HelloWorldView);
|
||||
|
||||
```
|
||||
|
||||
## Region Hierarchy
|
||||
|
||||
Regions are organized in a hierarchy, with the most specific region taking precedence over less specific regions.
|
||||
|
||||
If you specify a view for the Main Region, it will be used for both Edit and View modes. You can override the Main Region view for a specific mode by registering the view with that specific mode.
|
||||
|
||||
### MCT.regions.Tree
|
||||
### MCT.regions.Main
|
||||
### MCT.regions.Main.View
|
||||
### MCT.regions.Main.Edit
|
||||
### MCT.regions.Inspector
|
||||
### MCT.regions.Inspector.View
|
||||
### MCT.regions.Inspector.Edit
|
||||
### MCT.regions.Toolbar
|
||||
### MCT.regions.Toolbar.View
|
||||
### MCT.regions.Toolbar.Edit
|
@ -1,11 +0,0 @@
|
||||
define([
|
||||
|
||||
], function () {
|
||||
|
||||
function RegionAPI() {
|
||||
window.MCT = window.MCT || {};
|
||||
window.MCT.regions = {};
|
||||
}
|
||||
|
||||
return RegionAPI;
|
||||
})
|
@ -1,45 +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([
|
||||
'./RegionAPI',
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
RegionAPI,
|
||||
legacyRegistry
|
||||
) {
|
||||
legacyRegistry.register('api/region-api', {
|
||||
name: 'Region API',
|
||||
description: 'The public Region API',
|
||||
extensions: {
|
||||
runs: [
|
||||
{
|
||||
key: "RegionAPI",
|
||||
implementation: RegionAPI,
|
||||
depends: [
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
});
|
@ -1,71 +0,0 @@
|
||||
# Telemetry API - Overview
|
||||
|
||||
The Telemetry API provides basic methods for retrieving historical and realtime telemetry data, retrieving telemetry metadata, and registering additional telemetry providers.
|
||||
|
||||
The Telemetry API also provides a set of helpers built upon these basics-- TelemetryFormatters help you format telemetry values for display purposes, LimitEvaluators help you display evaluate and display alarm states, while TelemetryCollections provide a method for seamlessly combining historical and realtime data, while supporting more advanced client side filtering and interactivity.
|
||||
|
||||
|
||||
## Getting Telemetry Data
|
||||
|
||||
|
||||
### `MCT.telemetry.request(domainObject, options)`
|
||||
|
||||
Request historical telemetry for a domain object. Options allows you to specify filters (start, end, etc.), sort order, and strategies for retrieving telemetry (aggregation, latest available, etc.).
|
||||
|
||||
Returns a `Promise` for an array of telemetry values.
|
||||
|
||||
### `MCT.telemetry.subscribe(domainObject, callback, options)`
|
||||
|
||||
Subscribe to realtime telemetry for a specific domain object. callback will be called whenever data is received from a realtime provider. Options allows you to specify ???
|
||||
|
||||
## Understanding Telemetry
|
||||
|
||||
### `MCT.telemetry.getMetadata(domainObject)`
|
||||
|
||||
Retrieve telemetry metadata for a domain object. Telemetry metadata helps you understand the sort of telemetry data a domain object can provide-- for instances, the possible enumerations or states, the units, and more.
|
||||
|
||||
### `MCT.telemetry.Formatter`
|
||||
|
||||
Telemetry formatters help you format telemetry values for display. Under the covers, they use telemetry metadata to interpret your telemetry data, and then they use the format API to format that data for display.
|
||||
|
||||
|
||||
### `MCT.telemetry.LimitEvaluator`
|
||||
|
||||
Limit Evaluators help you evaluate limit and alarm status of individual telemetry datums for display purposes without having to interact directly with the Limit API.
|
||||
|
||||
## Adding new telemetry sources
|
||||
|
||||
### `MCT.telemetry.registerProvider(telemetryProvider)`
|
||||
|
||||
Register a telemetry provider with the telemetry service. This allows you to connect alternative telemetry sources to For more information, see the `MCT.telemetry.BaseProvider`
|
||||
|
||||
### `MCT.telemetry.BaseProvider`
|
||||
|
||||
The base provider is a great starting point for developers who would like to implement their own telemetry provider. At the same time, you can implement your own telemetry provider as long as it meets the TelemetryProvider (see other docs).
|
||||
|
||||
## Other tools
|
||||
|
||||
### `MCT.telemetry.TelemetryCollection`
|
||||
|
||||
The TelemetryCollection is a useful tool for building advanced displays. It helps you seamlessly handle both historical and realtime telemetry data, while making it easier to deal with large data sets and interactive displays that need to frequently requery data.
|
||||
|
||||
|
||||
|
||||
# API Reference (TODO)
|
||||
|
||||
* Telemetry Metadata
|
||||
* Request Options
|
||||
-- start
|
||||
-- end
|
||||
-- sort
|
||||
-- ???
|
||||
-- strategies -- specify which strategies you want. an array provides for fallback strategies without needing decoration. Design fallbacks into API.
|
||||
|
||||
### `MCT.telemetry.request(domainObject, options)`
|
||||
### `MCT.telemetry.subscribe(domainObject, callback, options)`
|
||||
### `MCT.telemetry.getMetadata(domainObject)`
|
||||
### `MCT.telemetry.Formatter`
|
||||
### `MCT.telemetry.LimitEvaluator`
|
||||
### `MCT.telemetry.registerProvider(telemetryProvider)`
|
||||
### `MCT.telemetry.BaseProvider`
|
||||
### `MCT.telemetry.TelemetryCollection`
|
@ -1,239 +0,0 @@
|
||||
/*global define,window,console,MCT*/
|
||||
|
||||
/**
|
||||
|
||||
var key = '114ced6c-deb7-4169-ae71-68c571665514';
|
||||
MCT.objects.getObject([key])
|
||||
.then(function (results) {
|
||||
console.log('got results');
|
||||
return results[key];
|
||||
})
|
||||
.then(function (domainObject) {
|
||||
console.log('got object');
|
||||
MCT.telemetry.subscribe(domainObject, function (datum) {
|
||||
console.log('gotData!', datum);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
*/
|
||||
|
||||
define([
|
||||
'lodash',
|
||||
'eventemitter2'
|
||||
], function (
|
||||
_,
|
||||
EventEmitter
|
||||
) {
|
||||
|
||||
// format map is a placeholder until we figure out format service.
|
||||
var FORMAT_MAP = {
|
||||
generic: function (range) {
|
||||
return function (datum) {
|
||||
return datum[range.key];
|
||||
};
|
||||
},
|
||||
enum: function (range) {
|
||||
var enumMap = _.indexBy(range.enumerations, 'value');
|
||||
return function (datum) {
|
||||
try {
|
||||
return enumMap[datum[range.valueKey]].text;
|
||||
} catch (e) {
|
||||
return datum[range.valueKey];
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
FORMAT_MAP.number =
|
||||
FORMAT_MAP.float =
|
||||
FORMAT_MAP.integer =
|
||||
FORMAT_MAP.ascii =
|
||||
FORMAT_MAP.generic;
|
||||
|
||||
|
||||
|
||||
function TelemetryAPI(
|
||||
formatService
|
||||
) {
|
||||
|
||||
var FORMATTER_CACHE = new WeakMap(),
|
||||
EVALUATOR_CACHE = new WeakMap();
|
||||
|
||||
function testAPI() {
|
||||
var key = '114ced6c-deb7-4169-ae71-68c571665514';
|
||||
window.MCT.objects.getObjects([key])
|
||||
.then(function (results) {
|
||||
console.log('got results');
|
||||
return results[key];
|
||||
})
|
||||
.then(function (domainObject) {
|
||||
var formatter = new MCT.telemetry.Formatter(domainObject);
|
||||
console.log('got object');
|
||||
window.MCT.telemetry.subscribe(domainObject, function (datum) {
|
||||
var formattedValues = {};
|
||||
Object.keys(datum).forEach(function (key) {
|
||||
formattedValues[key] = formatter.format(datum, key);
|
||||
});
|
||||
console.log(
|
||||
'datum:',
|
||||
datum,
|
||||
'formatted:',
|
||||
formattedValues
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function getFormatter(range) {
|
||||
if (FORMAT_MAP[range.type]) {
|
||||
return FORMAT_MAP[range.type](range);
|
||||
}
|
||||
try {
|
||||
var format = formatService.getFormat(range.type).format.bind(
|
||||
formatService.getFormat(range.type)
|
||||
),
|
||||
formatter = function (datum) {
|
||||
return format(datum[range.key]);
|
||||
};
|
||||
return formatter;
|
||||
} catch (e) {
|
||||
console.log('could not retrieve format', range, e, e.message);
|
||||
return FORMAT_MAP.generic(range);
|
||||
}
|
||||
}
|
||||
|
||||
function TelemetryFormatter(domainObject) {
|
||||
this.metadata = domainObject.getCapability('telemetry').getMetadata();
|
||||
this.formats = {};
|
||||
var ranges = this.metadata.ranges.concat(this.metadata.domains);
|
||||
|
||||
ranges.forEach(function (range) {
|
||||
this.formats[range.key] = getFormatter(range);
|
||||
}, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the 'key' from the datum and format it accordingly to
|
||||
* telemetry metadata in domain object.
|
||||
*/
|
||||
TelemetryFormatter.prototype.format = function (datum, key) {
|
||||
return this.formats[key](datum);
|
||||
};
|
||||
|
||||
function LimitEvaluator(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.evaluator = domainObject.getCapability('limit');
|
||||
if (!this.evaluator) {
|
||||
this.evalute = function () {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** TODO: Do we need a telemetry parser, or do we assume telemetry
|
||||
is numeric by default? */
|
||||
|
||||
LimitEvaluator.prototype.evaluate = function (datum, key) {
|
||||
return this.evaluator.evaluate(datum, key);
|
||||
};
|
||||
|
||||
/** Basic telemetry collection, needs more magic. **/
|
||||
function TelemetryCollection(domainObject) {
|
||||
this.domainObject = domainObject;
|
||||
this.data = [];
|
||||
}
|
||||
|
||||
_.extend(TelemetryCollection.prototype, EventEmitter.prototype);
|
||||
|
||||
TelemetryCollection.prototype.request = function (options) {
|
||||
request(this.domainObject, options).then(function (data) {
|
||||
data.forEach(function (datum) {
|
||||
this.addDatum(datum);
|
||||
}, this);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
TelemetryCollection.prototype.addDatum = function (datum) {
|
||||
this.data.push(datum);
|
||||
this.emit('add', datum);
|
||||
};
|
||||
|
||||
TelemetryCollection.prototype.subscribe = function (options) {
|
||||
if (this.unsubscribe) {
|
||||
this.unsubscribe();
|
||||
delete this.unsubscribe;
|
||||
}
|
||||
|
||||
this.unsubscribe = subscribe(
|
||||
this.domainObject,
|
||||
function (telemetrySeries) {
|
||||
telemetrySeries.getData().forEach(this.addDatum, this);
|
||||
}.bind(this),
|
||||
options
|
||||
);
|
||||
};
|
||||
|
||||
function registerProvider(provider) {
|
||||
// Not yet implemented.
|
||||
console.log('registering provider', provider);
|
||||
}
|
||||
|
||||
function registerEvaluator(evaluator) {
|
||||
// not yet implemented.
|
||||
console.log('registering evaluator', evaluator);
|
||||
}
|
||||
|
||||
function request(domainObject, options) {
|
||||
return domainObject.getCapability('telemetry')
|
||||
.requestData(options)
|
||||
.then(function (telemetrySeries) {
|
||||
return telemetrySeries.getData();
|
||||
});
|
||||
}
|
||||
|
||||
function subscribe(domainObject, callback, options) {
|
||||
return domainObject.getCapability('telemetry')
|
||||
.subscribe(function (series) {
|
||||
series.getData().forEach(callback);
|
||||
}, options);
|
||||
}
|
||||
|
||||
var Telemetry = {
|
||||
registerProvider: registerProvider,
|
||||
registerEvaluator: registerEvaluator,
|
||||
request: request,
|
||||
subscribe: subscribe,
|
||||
getMetadata: function (domainObject) {
|
||||
return domainObject.getCapability('telemetry').getMetadata();
|
||||
},
|
||||
Formatter: function (domainObject) {
|
||||
if (!FORMATTER_CACHE.has(domainObject)) {
|
||||
FORMATTER_CACHE.set(
|
||||
domainObject,
|
||||
new TelemetryFormatter(domainObject)
|
||||
);
|
||||
}
|
||||
return FORMATTER_CACHE.get(domainObject);
|
||||
},
|
||||
LimitEvaluator: function (domainObject) {
|
||||
if (!EVALUATOR_CACHE.has(domainObject)) {
|
||||
EVALUATOR_CACHE.set(
|
||||
domainObject,
|
||||
new LimitEvaluator(domainObject)
|
||||
);
|
||||
}
|
||||
return EVALUATOR_CACHE.get(domainObject);
|
||||
}
|
||||
};
|
||||
|
||||
window.MCT = window.MCT || {};
|
||||
window.MCT.telemetry = Telemetry;
|
||||
window.testAPI = testAPI;
|
||||
|
||||
return Telemetry;
|
||||
}
|
||||
|
||||
return TelemetryAPI;
|
||||
});
|
@ -1,46 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'./TelemetryAPI',
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
TelemetryAPI,
|
||||
legacyRegistry
|
||||
) {
|
||||
legacyRegistry.register('api/telemetry-api', {
|
||||
name: 'Telemetry API',
|
||||
description: 'The public Telemetry API',
|
||||
extensions: {
|
||||
runs: [
|
||||
{
|
||||
key: "TelemetryAPI",
|
||||
implementation: TelemetryAPI,
|
||||
depends: [
|
||||
'formatService'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
@ -1,31 +0,0 @@
|
||||
# Type API - Overview
|
||||
|
||||
The Type API allows you to register type information for domain objects, and allows you to retrieve type information about a given domain object. Crucially, type information allows you to add new creatible object types.
|
||||
|
||||
### MCT.types.Type
|
||||
|
||||
The basic interface for a type. You can extend this to implement your own type,
|
||||
or you can provide an object that implements the same interface.
|
||||
|
||||
`attribute` | `type` | `note`
|
||||
--- | --- | ---
|
||||
`label` | `String` | The human readible name of the type.
|
||||
`key` | `String` | The unique identifier for this type.
|
||||
`glyph` | `String` | The glyph identifier for the type. Displayed in trees, labels, and other locations.
|
||||
`description` | `String` | A basic description of the type visible in the create menu.
|
||||
`isCreatible` | `Boolean`, `Number`, or `Function` | If truthy, this type will be visible in the create menu. Note that objects not in the create menu can be instantiated via other means.
|
||||
`namespace` | `String` | The object namespace that provides instances of this type. This allows you to implement custom object providers for specific types while still utilizing other namespaces for persistence.
|
||||
`properties` | `Object` | Object defining properties of an instance of this class. Properties are used for automatic form generation and automated metadata display. For more information on the definition of this object, look at (some resource-- jsonschema?)
|
||||
`canContain` | `Function` | determins whether objects of this type can contain other objects. Will be invoked with a domain object. Return true to allow composition, return false to disallow composition.
|
||||
|
||||
### MCT.types.register(type)
|
||||
|
||||
Register a type with the type API. Registering a type with the same key as another type will replace the original type definition.
|
||||
|
||||
### MCT.types.getType(typeKey)
|
||||
|
||||
Returns the type definition for a given typeKey. returns undefined if type does not exist.
|
||||
|
||||
### MCT.types.getType(domainObject)
|
||||
|
||||
Return the type definition for a given domain object.
|
@ -1,10 +0,0 @@
|
||||
define([
|
||||
|
||||
], function () {
|
||||
function TypeAPI() {
|
||||
window.MCT = window.MCT || {};
|
||||
window.MCT.types = {};
|
||||
}
|
||||
|
||||
return TypeAPI;
|
||||
});
|
@ -1,47 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'./TypeAPI',
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
TypeAPI,
|
||||
legacyRegistry
|
||||
) {
|
||||
legacyRegistry.register('api/type-api', {
|
||||
name: 'Type API',
|
||||
description: 'The public Type API',
|
||||
extensions: {
|
||||
runs: [
|
||||
{
|
||||
key: "TypeAPI",
|
||||
implementation: TypeAPI,
|
||||
depends: [
|
||||
'typeService'
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
});
|
19
app.js
@ -14,8 +14,7 @@
|
||||
options = require('minimist')(process.argv.slice(2)),
|
||||
express = require('express'),
|
||||
app = express(),
|
||||
fs = require('fs'),
|
||||
request = require('request');
|
||||
fs = require('fs');
|
||||
|
||||
// Defaults
|
||||
options.port = options.port || options.p || 8080;
|
||||
@ -42,13 +41,7 @@
|
||||
|
||||
// Override bundles.json for HTTP requests
|
||||
app.use('/' + BUNDLE_FILE, function (req, res) {
|
||||
var bundles;
|
||||
|
||||
try {
|
||||
bundles = JSON.parse(fs.readFileSync(BUNDLE_FILE, 'utf8'));
|
||||
} catch (e) {
|
||||
bundles = [];
|
||||
}
|
||||
var bundles = JSON.parse(fs.readFileSync(BUNDLE_FILE, 'utf8'));
|
||||
|
||||
// Handle command line inclusions/exclusions
|
||||
bundles = bundles.concat(options.include);
|
||||
@ -62,14 +55,6 @@
|
||||
res.send(JSON.stringify(bundles));
|
||||
});
|
||||
|
||||
app.use('/proxyUrl', function proxyRequest(req, res, next) {
|
||||
console.log('Proxying request to: ', req.query.url);
|
||||
req.pipe(request({
|
||||
url: req.query.url,
|
||||
strictSSL: false
|
||||
}).on('error', next)).pipe(res);
|
||||
});
|
||||
|
||||
// Expose everything else as static files
|
||||
app.use(express['static']('.'));
|
||||
|
||||
|
25
bower.json
@ -1,25 +0,0 @@
|
||||
{
|
||||
"name": "openmctweb",
|
||||
"description": "The OpenMCTWeb core platform",
|
||||
"main": "",
|
||||
"license": "Apache-2.0",
|
||||
"moduleType": [],
|
||||
"homepage": "http://nasa.github.io/openmctweb/",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"angular": "1.4.4",
|
||||
"angular-route": "1.4.4",
|
||||
"moment": "^2.11.1",
|
||||
"moment-duration-format": "^1.3.0",
|
||||
"requirejs": "~2.1.22",
|
||||
"text": "requirejs-text#^2.0.14",
|
||||
"es6-promise": "^3.0.2",
|
||||
"screenfull": "^3.0.0",
|
||||
"node-uuid": "^1.4.7",
|
||||
"comma-separated-values": "^3.6.4",
|
||||
"FileSaver.js": "^0.0.2",
|
||||
"zepto": "^1.1.6",
|
||||
"eventemitter2": "^1.0.0",
|
||||
"lodash": "3.10.1"
|
||||
}
|
||||
}
|
33
bundles.json
Normal file
@ -0,0 +1,33 @@
|
||||
[
|
||||
"platform/framework",
|
||||
"platform/core",
|
||||
"platform/representation",
|
||||
"platform/commonUI/about",
|
||||
"platform/commonUI/browse",
|
||||
"platform/commonUI/edit",
|
||||
"platform/commonUI/dialog",
|
||||
"platform/commonUI/general",
|
||||
"platform/commonUI/inspect",
|
||||
"platform/commonUI/mobile",
|
||||
"platform/commonUI/themes/espresso",
|
||||
"platform/containment",
|
||||
"platform/execution",
|
||||
"platform/telemetry",
|
||||
"platform/features/imagery",
|
||||
"platform/features/layout",
|
||||
"platform/features/pages",
|
||||
"platform/features/plot",
|
||||
"platform/features/scrolling",
|
||||
"platform/features/events",
|
||||
"platform/forms",
|
||||
"platform/identity",
|
||||
"platform/persistence/local",
|
||||
"platform/persistence/queue",
|
||||
"platform/policy",
|
||||
"platform/entanglement",
|
||||
"platform/search",
|
||||
|
||||
"example/imagery",
|
||||
"example/eventGenerator",
|
||||
"example/generator"
|
||||
]
|
@ -2,17 +2,13 @@ deployment:
|
||||
production:
|
||||
branch: master
|
||||
commands:
|
||||
- npm install canvas nomnoml
|
||||
- ./build-docs.sh
|
||||
- git push git@heroku.com:openmctweb-demo.git $CIRCLE_SHA1:refs/heads/master
|
||||
openmctweb-staging-un:
|
||||
branch: nem_prototype
|
||||
branch: search
|
||||
heroku:
|
||||
appname: openmctweb-staging-un
|
||||
openmctweb-staging-deux:
|
||||
branch: mobile
|
||||
heroku:
|
||||
appname: openmctweb-staging-deux
|
||||
test:
|
||||
post:
|
||||
- npm run jshint --silent
|
||||
|
@ -1,9 +0,0 @@
|
||||
<hr>
|
||||
<cite>
|
||||
This document is styled using
|
||||
<a href="https://github.com/jasonm23/markdown-css-themes">
|
||||
https://github.com/jasonm23/markdown-css-themes
|
||||
</a>.
|
||||
</cite>
|
||||
</body>
|
||||
</html>
|
@ -20,7 +20,7 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/*global require,process,__dirname,GLOBAL*/
|
||||
/*global require,process,GLOBAL*/
|
||||
/*jslint nomen: false */
|
||||
|
||||
|
||||
@ -30,8 +30,7 @@
|
||||
var CONSTANTS = {
|
||||
DIAGRAM_WIDTH: 800,
|
||||
DIAGRAM_HEIGHT: 500
|
||||
},
|
||||
TOC_HEAD = "# Table of Contents";
|
||||
};
|
||||
|
||||
GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be defined
|
||||
(function () {
|
||||
@ -45,10 +44,7 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
split = require("split"),
|
||||
stream = require("stream"),
|
||||
nomnoml = require('nomnoml'),
|
||||
toc = require("markdown-toc"),
|
||||
Canvas = require('canvas'),
|
||||
header = fs.readFileSync(path.resolve(__dirname, 'header.html')),
|
||||
footer = fs.readFileSync(path.resolve(__dirname, 'footer.html')),
|
||||
options = require("minimist")(process.argv.slice(2));
|
||||
|
||||
// Convert from nomnoml source to a target PNG file.
|
||||
@ -106,7 +102,7 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
}
|
||||
|
||||
// Convert from Github-flavored Markdown to HTML
|
||||
function gfmifier(renderTOC) {
|
||||
function gfmifier() {
|
||||
var transform = new stream.Transform({ objectMode: true }),
|
||||
markdown = "";
|
||||
transform._transform = function (chunk, encoding, done) {
|
||||
@ -114,14 +110,9 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
done();
|
||||
};
|
||||
transform._flush = function (done) {
|
||||
if (renderTOC){
|
||||
// Prepend table of contents
|
||||
markdown =
|
||||
[ TOC_HEAD, toc(markdown).content, "", markdown ].join("\n");
|
||||
}
|
||||
this.push(header);
|
||||
this.push("<html><body>\n");
|
||||
this.push(marked(markdown));
|
||||
this.push(footer);
|
||||
this.push("\n</body></html>\n");
|
||||
done();
|
||||
};
|
||||
return transform;
|
||||
@ -142,8 +133,8 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
customRenderer.link = function (href, title, text) {
|
||||
// ...but only if they look like relative paths
|
||||
return (href || "").indexOf(":") === -1 && href[0] !== "/" ?
|
||||
renderer.link(href.replace(/\.md/, ".html"), title, text) :
|
||||
renderer.link.apply(renderer, arguments);
|
||||
renderer.link(href.replace(/\.md/, ".html"), title, text) :
|
||||
renderer.link.apply(renderer, arguments);
|
||||
};
|
||||
return customRenderer;
|
||||
}
|
||||
@ -170,16 +161,13 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
var destination = file.replace(options['in'], options.out)
|
||||
.replace(/md$/, "html"),
|
||||
destPath = path.dirname(destination),
|
||||
prefix = path.basename(destination).replace(/\.html$/, ""),
|
||||
//Determine whether TOC should be rendered for this file based
|
||||
//on regex provided as command line option
|
||||
renderTOC = file.match(options['suppress-toc'] || "") === null;
|
||||
prefix = path.basename(destination).replace(/\.html$/, "");
|
||||
|
||||
mkdirp(destPath, function (err) {
|
||||
fs.createReadStream(file, { encoding: 'utf8' })
|
||||
.pipe(split())
|
||||
.pipe(nomnomlifier(destPath, prefix))
|
||||
.pipe(gfmifier(renderTOC))
|
||||
.pipe(gfmifier())
|
||||
.pipe(fs.createWriteStream(destination, {
|
||||
encoding: 'utf8'
|
||||
}));
|
||||
@ -191,17 +179,13 @@ GLOBAL.window = GLOBAL.window || GLOBAL; // nomnoml expects window to be define
|
||||
glob(options['in'] + "/**/*.@(html|css|png)", {}, function (err, files) {
|
||||
files.forEach(function (file) {
|
||||
var destination = file.replace(options['in'], options.out),
|
||||
destPath = path.dirname(destination),
|
||||
streamOptions = {};
|
||||
if (file.match(/png$/)) {
|
||||
streamOptions.encoding = null;
|
||||
} else {
|
||||
streamOptions.encoding = 'utf8';
|
||||
}
|
||||
destPath = path.dirname(destination);
|
||||
|
||||
mkdirp(destPath, function (err) {
|
||||
fs.createReadStream(file, streamOptions)
|
||||
.pipe(fs.createWriteStream(destination, streamOptions));
|
||||
fs.createReadStream(file, { encoding: 'utf8' })
|
||||
.pipe(fs.createWriteStream(destination, {
|
||||
encoding: 'utf8'
|
||||
}));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,7 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet"
|
||||
href="http://jasonm23.github.io/markdown-css-themes/avenir-white.css">
|
||||
</head>
|
||||
<body>
|
||||
|
@ -35,26 +35,16 @@ in __any of these tiers__.
|
||||
* _DOM_: The rendered HTML document, composed from HTML templates which
|
||||
have been processed by AngularJS and will be updated by AngularJS
|
||||
to reflect changes from the presentation layer. User interactions
|
||||
are initiated from here and invoke behavior in the presentation layer. HTML
|
||||
templates are written in Angular’s template syntax; see the [Angular documentation on templates](https://docs.angularjs.org/guide/templates).
|
||||
These describe the page as actually seen by the user. Conceptually,
|
||||
stylesheets (controlling the lookandfeel of the rendered templates) belong
|
||||
in this grouping as well.
|
||||
are initiated from here and invoke behavior in the presentation layer.
|
||||
* [_Presentation layer_](#presentation-layer): The presentation layer
|
||||
is responsible for updating (and providing information to update)
|
||||
the displayed state of the application. The presentation layer consists
|
||||
primarily of _controllers_ and _directives_. The presentation layer is
|
||||
concerned with inspecting the information model and preparing it for
|
||||
display.
|
||||
* [_Information model_](#information-model): Provides a common (within Open MCT
|
||||
Web) set of interfaces for dealing with “things” domain objects within the
|
||||
system. Userfacing concerns in a Open MCT Web application are expressed as
|
||||
domain objects; examples include folders (used to organize other domain
|
||||
objects), layouts (used to build displays), or telemetry points (used as
|
||||
handles for streams of remote measurements.) These domain objects expose a
|
||||
common set of interfaces to allow reusable user interfaces to be built in the
|
||||
presentation and template tiers; the specifics of these behaviors are then
|
||||
mapped to interactions with underlying services.
|
||||
* [_Information model_](#information-model): The information model
|
||||
describes the state and behavior of the objects with which the user
|
||||
interacts.
|
||||
* [_Service infrastructure_](#service-infrastructure): The service
|
||||
infrastructure is responsible for providing the underlying general
|
||||
functionality needed to support the information model. This includes
|
||||
@ -62,9 +52,7 @@ in __any of these tiers__.
|
||||
back-end.
|
||||
* _Back-end_: The back-end is out of the scope of Open MCT Web, except
|
||||
for the interfaces which are utilized by adapters participating in the
|
||||
service infrastructure. Includes the underlying persistence stores, telemetry
|
||||
streams, and so forth which the Open MCT Web client is being used to interact
|
||||
with.
|
||||
service infrastructure.
|
||||
|
||||
## Application Start-up
|
||||
|
@ -58,13 +58,13 @@ of the software.
|
||||
|
||||
These layers are:
|
||||
|
||||
* [_Framework_](framework.md): The framework layer is responsible for
|
||||
* [_Framework_](Framework.md): The framework layer is responsible for
|
||||
managing the interactions between application components. It has no
|
||||
application-specific knowledge; at this layer, we have only
|
||||
established an abstraction by which different software components
|
||||
may communicate and/or interact.
|
||||
* [_Platform_](platform.md): The platform layer defines the general look,
|
||||
feel, and behavior of Open MCT Web. This includes user-facing components like
|
||||
* [_Platform_](Platform.md): The platform layer defines the general look, feel, and
|
||||
behavior of Open MCT Web. This includes user-facing components like
|
||||
Browse mode and Edit mode, as well as underlying elements of the
|
||||
information model and the general service infrastructure.
|
||||
* _Application_: The application layer defines specific features of
|
||||
|
@ -1,3 +0,0 @@
|
||||
Design proposals:
|
||||
|
||||
* [API Redesign](proposals/APIRedesign.md)
|
@ -1,338 +0,0 @@
|
||||
# API Refactoring
|
||||
|
||||
This document summarizes a path toward implementing API changes
|
||||
from the [API Redesign](../proposals/APIRedesign.md) for Open MCT Web
|
||||
v1.0.0.
|
||||
|
||||
# Goals
|
||||
|
||||
These plans are intended to minimize:
|
||||
|
||||
* Waste; avoid allocating effort to temporary changes.
|
||||
* Downtime; avoid making changes in large increments that blocks
|
||||
delivery of new features for substantial periods of time.
|
||||
* Risk; ensure that changes can be validated quickly, avoid putting
|
||||
large effort into changes that have not been validated.
|
||||
|
||||
# Plan
|
||||
|
||||
```nomnoml
|
||||
#comment: This diagram is in nomnoml syntax and should be rendered.
|
||||
#comment: See https://github.com/nasa/openmctweb/issues/264#issuecomment-167166471
|
||||
|
||||
|
||||
[<start> Start]->[<state> Imperative bundle registration]
|
||||
|
||||
[<state> Imperative bundle registration]->[<state> Build and packaging]
|
||||
[<state> Imperative bundle registration]->[<state> Refactor API]
|
||||
|
||||
[<state> Build and packaging |
|
||||
[<start> Start]->[<state> Incorporate a build step]
|
||||
[<state> Incorporate a build step |
|
||||
[<start> Start]->[<state> Choose package manager]
|
||||
[<start> Start]->[<state> Choose build system]
|
||||
[<state> Choose build system]<->[<state> Choose package manager]
|
||||
[<state> Choose package manager]->[<state> Implement]
|
||||
[<state> Choose build system]->[<state> Implement]
|
||||
[<state> Implement]->[<end> End]
|
||||
]->[<state> Separate repositories]
|
||||
[<state> Separate repositories]->[<end> End]
|
||||
]->[<state> Release candidacy]
|
||||
|
||||
|
||||
[<start> Start]->[<state> Design registration API]
|
||||
|
||||
[<state> Design registration API |
|
||||
[<start> Start]->[<state> Decide on role of Angular]
|
||||
[<state> Decide on role of Angular]->[<state> Design API]
|
||||
[<state> Design API]->[<choice> Passes review?]
|
||||
[<choice> Passes review?] no ->[<state> Design API]
|
||||
[<choice> Passes review?]-> yes [<end> End]
|
||||
]->[<state> Refactor API]
|
||||
|
||||
[<state> Refactor API |
|
||||
[<start> Start]->[<state> Imperative extension registration]
|
||||
[<state> Imperative extension registration]->[<state> Refactor individual extensions]
|
||||
|
||||
[<state> Refactor individual extensions |
|
||||
[<start> Start]->[<state> Prioritize]
|
||||
[<state> Prioritize]->[<choice> Sufficient value added?]
|
||||
[<choice> Sufficient value added?] no ->[<end> End]
|
||||
[<choice> Sufficient value added?] yes ->[<state> Design]
|
||||
[<state> Design]->[<choice> Passes review?]
|
||||
[<choice> Passes review?] no ->[<state> Design]
|
||||
[<choice> Passes review?]-> yes [<state> Implement]
|
||||
[<state> Implement]->[<end> End]
|
||||
]->[<state> Remove legacy bundle support]
|
||||
|
||||
[<state> Remove legacy bundle support]->[<end> End]
|
||||
]->[<state> Release candidacy]
|
||||
|
||||
[<state> Release candidacy |
|
||||
[<start> Start]->[<state> Verify |
|
||||
[<start> Start]->[<choice> API well-documented?]
|
||||
[<start> Start]->[<choice> API well-tested?]
|
||||
[<choice> API well-documented?]-> no [<state> Write documentation]
|
||||
[<choice> API well-documented?] yes ->[<end> End]
|
||||
[<state> Write documentation]->[<choice> API well-documented?]
|
||||
[<choice> API well-tested?]-> no [<state> Write test cases]
|
||||
[<choice> API well-tested?]-> yes [<end> End]
|
||||
[<state> Write test cases]->[<choice> API well-tested?]
|
||||
]
|
||||
[<start> Start]->[<state> Validate |
|
||||
[<start> Start]->[<choice> Passes review?]
|
||||
[<start> Start]->[<state> Use internally]
|
||||
[<state> Use internally]->[<choice> Proves useful?]
|
||||
[<choice> Passes review?]-> no [<state> Address feedback]
|
||||
[<state> Address feedback]->[<choice> Passes review?]
|
||||
[<choice> Passes review?] yes -> [<end> End]
|
||||
[<choice> Proves useful?] yes -> [<end> End]
|
||||
[<choice> Proves useful?] no -> [<state> Fix problems]
|
||||
[<state> Fix problems]->[<state> Use internally]
|
||||
]
|
||||
[<state> Validate]->[<end> End]
|
||||
[<state> Verify]->[<end> End]
|
||||
]->[<state> Release]
|
||||
|
||||
[<state> Release]->[<end> End]
|
||||
```
|
||||
|
||||
## Step 1. Imperative bundle registration
|
||||
|
||||
Register whole bundles imperatively, using their current format.
|
||||
|
||||
For example, in each bundle add a `bundle.js` file:
|
||||
|
||||
```js
|
||||
define([
|
||||
'mctRegistry',
|
||||
'json!bundle.json'
|
||||
], function (mctRegistry, bundle) {
|
||||
mctRegistry.install(bundle, "path/to/bundle");
|
||||
});
|
||||
```
|
||||
|
||||
Where `mctRegistry.install` is placeholder API that wires into the
|
||||
existing bundle registration mechanisms. The main point of entry
|
||||
would need to be adapted to clearly depend on these bundles
|
||||
(in the require sense of a dependency), and the framework layer
|
||||
would need to implement and integrate with this transitional
|
||||
API.
|
||||
|
||||
Benefits:
|
||||
|
||||
* Achieves an API Redesign goal with minimal immediate effort.
|
||||
* Conversion to an imperative syntax may be trivially automated.
|
||||
* Minimal change; reuse existing bundle definitions, primarily.
|
||||
* Allows early validation of switch to imperative; unforeseen
|
||||
consequences of the change may be detected at this point.
|
||||
* Allows implementation effort to progress in parallel with decisions
|
||||
about API changes, including fundamental ones such as the role of
|
||||
Angular. May act in some sense as a prototype to inform those
|
||||
decisions.
|
||||
* Creates a location (framework layer) where subsequent changes to
|
||||
the manner in which extensions are registered may be centralized.
|
||||
When there is a one-to-one correspondence between the existing
|
||||
form of an extension and its post-refactor form, adapters can be
|
||||
written here to defer the task of making changes ubiquitously
|
||||
throughout bundles, allowing for earlier validation and
|
||||
verification of those changes, and avoiding ubiquitous changes
|
||||
which might require us to go dark. (Mitigates
|
||||
["greenfield paradox"](http://stepaheadsoftware.blogspot.com/2012/09/greenfield-or-refactor-legacy-code-base.html);
|
||||
want to add value with new API but don't want to discard value
|
||||
of tested/proven legacy codebase.)
|
||||
|
||||
Detriments:
|
||||
|
||||
* Requires transitional API to be implemented/supported; this is
|
||||
waste. May mitigate this by time-bounding the effort put into
|
||||
this step to ensure that waste is minimal.
|
||||
|
||||
Note that API changes at this point do not meaningfully reflect
|
||||
the desired 1.0.0 API, so no API reviews are necessary.
|
||||
|
||||
## Step 2. Incorporate a build step
|
||||
|
||||
After the previous step is completed, there should be a
|
||||
straightforward dependency graph among AMD modules, and an
|
||||
imperative (albeit transitional) API allowing for other plugins
|
||||
to register themselves. This should allow for a build step to
|
||||
be included in a straightforward fashion.
|
||||
|
||||
Some goals for this build step:
|
||||
|
||||
* Compile (and, preferably, optimize/minify) Open MCT Web
|
||||
sources into a single `.js` file.
|
||||
* It is desirable to do the same for HTML sources, but
|
||||
may wish to defer this until a subsequent refactoring
|
||||
step if appropriate.
|
||||
* Provide non-code assets in a format that can be reused by
|
||||
derivative projects in a straightforward fashion.
|
||||
|
||||
Should also consider which dependency/packaging manager should
|
||||
be used by dependent projects to obtain Open MCT Web. Approaches
|
||||
include:
|
||||
|
||||
1. Plain `npm`. Dependents then declare their dependency with
|
||||
`npm` and utilize built sources and assets in a documented
|
||||
fashion. (Note that there are
|
||||
[documented challenges](http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging)
|
||||
in using `npm` in this fashion.)
|
||||
2. Build with `npm`, but recommend dependents install using
|
||||
`bower`, as this is intended for front-end development. This may
|
||||
require checking in built products, however, which
|
||||
we wish to avoid (this could be solved by maintaining
|
||||
a separate repository for built products.)
|
||||
|
||||
In all cases, there is a related question of which build system
|
||||
to use for asset generation/management and compilation/minification/etc.
|
||||
|
||||
1. [`webpack`](https://webpack.github.io/)
|
||||
is well-suited in principle, as it is specifically
|
||||
designed for modules with non-JS dependencies. However,
|
||||
there may be limitations and/or undesired behavior here
|
||||
(for instance, CSS dependencies get in-lined as style tags,
|
||||
removing our ability to control ordering) so it may
|
||||
2. `gulp` or `grunt`. Commonplace, but both still require
|
||||
non-trivial coding and/or configuration in order to produce
|
||||
appropriate build artifacts.
|
||||
3. [Just `npm`](http://blog.keithcirkel.co.uk/how-to-use-npm-as-a-build-tool/).
|
||||
Reduces the amount of tooling being used, but may introduce
|
||||
some complexity (e.g. custom scripts) to the build process,
|
||||
and may reduce portability.
|
||||
|
||||
## Step 3. Separate repositories
|
||||
|
||||
Refactor existing applications built on Open MCT Web such that they
|
||||
are no longer forks, but instead separate projects with a dependency
|
||||
on the built artifacts from Step 2.
|
||||
|
||||
Note that this is achievable already using `bower` (see `warp-bower`
|
||||
branch at http://developer.nasa.gov/mct/warp for an example.)
|
||||
However, changes involved in switching to an imperative API and
|
||||
introducing a build process may change (and should simplify) the
|
||||
approach used to utilize Open MCT Web as a dependency, so these
|
||||
changes should be introduced first.
|
||||
|
||||
## Step 4. Design registration API
|
||||
|
||||
Design the registration API that will replace declarative extension
|
||||
categories and extensions (including Angular built-ins and composite
|
||||
services.)
|
||||
|
||||
This may occur in parallel with implementation steps.
|
||||
|
||||
It will be necessary
|
||||
to have a decision about the role of Angular at this point; are extensions
|
||||
registered via provider configuration (Angular), or directly in some
|
||||
exposed registry?
|
||||
|
||||
Success criteria here should be based on peer review. Scope of peer
|
||||
review should be based on perceived risk/uncertainty surrounding
|
||||
proposed changes, to avoid waste; may wish to limit this review to
|
||||
the internal team. (The extent to which external
|
||||
feedback is available is limited, but there is an inherent timeliness
|
||||
to external review; need to balance this.)
|
||||
|
||||
Benefits:
|
||||
|
||||
* Solves the "general case" early, allowing for early validation.
|
||||
|
||||
Note that in specific cases, it may be desirable to refactor some
|
||||
current "extension category" in a manner that will not appear as
|
||||
registries, _or_ to locate these in different
|
||||
namespaces, _or_ to remove/replace certain categories entirely.
|
||||
This work is deferred intentionally to allow for a solution of the
|
||||
general case.
|
||||
|
||||
## Step 5. Imperative extension registration
|
||||
|
||||
Register individual extensions imperatively, implementing API changes
|
||||
from the previous step. At this stage, _usage_ of the API may be confined
|
||||
to a transitional adapter in the framework layer; bundles may continue
|
||||
to utilize the transitional API for registering extensions in the
|
||||
legacy format.
|
||||
|
||||
An important, ongoing sub-task here will be to discover and define dependencies
|
||||
among bundles. Composite services and extension categories are presently
|
||||
"implicit"; after the API redesign, these will become "explicit", insofar
|
||||
as some specific component will be responsible for creating any registries.
|
||||
As such, "bundles" which _use_ specific registries will need to have an
|
||||
enforceable dependency (e.g. require) upon those "bundles" which
|
||||
_declare_ those registries.
|
||||
|
||||
## Step 6. Refactor individual extensions
|
||||
|
||||
Refactor individual extension categories and/or services that have
|
||||
been identified as needing changes. This includes, but is not
|
||||
necessarily limited to:
|
||||
|
||||
* Views/Representations/Templates (refactored into "components.")
|
||||
* Capabilities (refactored into "roles", potentially.)
|
||||
* Telemetry (from `TelemetrySeries` to `TelemetryService`.)
|
||||
|
||||
Changes should be made one category at a time (either serially
|
||||
or separately in parallel) and should involve a tight cycle of:
|
||||
|
||||
1. Prioritization/reprioritization; highest-value API improvements
|
||||
should be done first.
|
||||
2. Design.
|
||||
3. Review. Refactoring individual extensions will require significant
|
||||
effort (likely the most significant effort in the process) so changes
|
||||
should be validated early to minimize risk/waste.
|
||||
4. Implementation. These changes will not have a one-to-one relationship
|
||||
with existing extensions, so changes cannot be centralized; usages
|
||||
will need to be updated across all "bundles" instead of centralized
|
||||
in a legacy adapter. If changes are of sufficient complexity, some
|
||||
planning should be done to spread out the changes incrementally.
|
||||
|
||||
By necessity, these changes may break functionality in applications
|
||||
built using Open MCT Web. On a case-by-case basis, should consider
|
||||
providing temporary "legacy support" to allow downstream updates
|
||||
to occur as a separate task; the relevant trade here is between
|
||||
waste/effort required to maintain legacy support, versus the
|
||||
downtime which may be introduced by making these changes simultaneously
|
||||
across several repositories.
|
||||
|
||||
|
||||
## Step 7. Remove legacy bundle support
|
||||
|
||||
Update bundles to remove any usages of legacy support for bundles
|
||||
(including that used by dependent projects.) Then, remove legacy
|
||||
support from Open MCT Web.
|
||||
|
||||
## Step 8. Release candidacy
|
||||
|
||||
Once API changes are complete, Open MCT Web should enter a release
|
||||
candidacy cycle. Important things to look at here:
|
||||
|
||||
* Are changes really complete?
|
||||
* Are they sufficiently documented?
|
||||
* Are they sufficiently tested?
|
||||
* Are changes really sufficient?
|
||||
* Do reviewers think they are usable?
|
||||
* Does the development team find them useful in practice? This
|
||||
will require calendar time to ascertain; should allocate time
|
||||
for this, particularly in alignment with the sprint/release
|
||||
cycle.
|
||||
* Has learning curve been measurably decreased? Comparing a to-do
|
||||
list tutorial to [other examples(http://todomvc.com/) could
|
||||
provide an empirical basis to this. How much code is required?
|
||||
How much explanation is required? How many dependencies must
|
||||
be installed before initial setup?
|
||||
* Does the API offer sufficient power to implement the extensions we
|
||||
anticipate?
|
||||
* Any open API-related issues which should block a 1.0.0 release?
|
||||
|
||||
Any problems identified during release candidacy will require
|
||||
subsequent design changes and planning.
|
||||
|
||||
## Step 9. Release
|
||||
|
||||
Once API changes have been verified and validated, proceed
|
||||
with release, including:
|
||||
|
||||
* Tagging as version 1.0.0 (at an appropriate time in the
|
||||
sprint/release cycle.)
|
||||
* Close any open issues which have been resolved (or made obsolete)
|
||||
by API changes.
|
@ -1,251 +0,0 @@
|
||||
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
|
||||
|
||||
- [Reducing interface depth (the bundle.json version)](#reducing-interface-depth-the-bundlejson-version)
|
||||
- [Imperitive component registries](#imperitive-component-registries)
|
||||
- [Get rid of "extension category" concept.](#get-rid-of-extension-category-concept)
|
||||
- [Reduce number and depth of extension points](#reduce-number-and-depth-of-extension-points)
|
||||
- [Composite services should not be the default](#composite-services-should-not-be-the-default)
|
||||
- [Get rid of views, representations, and templates.](#get-rid-of-views-representations-and-templates)
|
||||
- [Reducing interface depth (The angular discussion)](#reducing-interface-depth-the-angular-discussion)
|
||||
- [More angular: for all services](#more-angular-for-all-services)
|
||||
- [Less angular: only for views](#less-angular-only-for-views)
|
||||
- [Standard packaging and build system](#standard-packaging-and-build-system)
|
||||
- [Use systemjs for module loading](#use-systemjs-for-module-loading)
|
||||
- [Use gulp or grunt for standard tooling](#use-gulp-or-grunt-for-standard-tooling)
|
||||
- [Package openmctweb as single versioned file.](#package-openmctweb-as-single-versioned-file)
|
||||
- [Misc Improvements](#misc-improvements)
|
||||
- [Refresh on navigation](#refresh-on-navigation)
|
||||
- [Move persistence adapter to promise rejection.](#move-persistence-adapter-to-promise-rejection)
|
||||
- [Remove bulk requests from providers](#remove-bulk-requests-from-providers)
|
||||
- [Notes on current API proposals:](#notes-on-current-api-proposals)
|
||||
- [[1] Footnote: The angular debacle](#1-footnote-the-angular-debacle)
|
||||
- ["Do or do not, there is no try"](#do-or-do-not-there-is-no-try)
|
||||
- [A lack of commitment](#a-lack-of-commitment)
|
||||
- [Commitment is good!](#commitment-is-good)
|
||||
|
||||
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||
|
||||
|
||||
# Reducing interface depth (the bundle.json version)
|
||||
|
||||
## Imperitive component registries
|
||||
|
||||
Transition component registries to javascript, get rid of bundle.json and bundles.json. Prescribe a method for application configuration, but allow flexibility in how application configuration is defined.
|
||||
|
||||
Register components in an imperitive fashion, see angularApp.factory, angularApp.controller, etc. Alternatively, implement our own application object with new registries and it's own form of registering objects.
|
||||
|
||||
## Get rid of "extension category" concept.
|
||||
|
||||
The concept of an "extension category" is itself an extraneous concept-- an extra layer of interface depth, an extra thing to learn before you can say "hello world". Extension points should be clearly supported and documented with whatever interfaces make sense. Developers who wish to add something that is conceptually equivalent to an extension category can do so directly, in the manner that suites their needs, without us forcing a common method on them.
|
||||
|
||||
## Reduce number and depth of extension points
|
||||
|
||||
Clearly specify supported extension points (e.g. persistence, model providers, telemetry providers, routes, time systems), but don't claim that the system has a clear and perfect repeatable solution for unknown extension types. New extension categories can be implemented in whatever way makes sense, without prescribing "the one and only system for managing extensions".
|
||||
|
||||
The underlying problem here is we are predicting needs for extension points where none exist-- if we try and design the extension system before we know how it is used, we design the wrong thing and have to rewrite it later.
|
||||
|
||||
## Composite services should not be the default
|
||||
|
||||
Understanding composite services, and describing services as composite services can confuse developers. Aggregators are implemented once and forgotten, while decorators tend to be hacky, brittle solutions that are generally needed to avoid circular imports. While composite services are a useful construct, it reduces interface depth to implement them as registries + typed providers.
|
||||
|
||||
You can write a provider (provides "thing x" for "inputs y") with a simple interface. A provider has two or more methods:
|
||||
* a method which takes "inputs y" and returns True if it knows how to provide "thing x", false otherwise.
|
||||
* one or more methods which provide "thing x" for objects of "inputs y".
|
||||
|
||||
Actually checking whether a provider can respond to a request before asking it to do work allows for faster failure and clearer errors when no providers match the request.
|
||||
|
||||
## Get rid of views, representations, and templates.
|
||||
|
||||
Templates are an implementation detail that should be handled by module loaders. Views and representations become "components," and a new concept, "routes", is used to exposing specific views to end users.
|
||||
|
||||
`components` - building blocks for views, have clear inputs and outputs, and can be coupled to other components when it makes sense. (e.g. parent-child components such as menu and menu item), but should have ZERO knowledge of our data models or telemetry apis. They should define data models that enable them to do their job well while still being easy to test.
|
||||
|
||||
`routes` - a view type for a given domain object, e.g. a plot, table, display layout, etc. Can be described as "whatever shows in the main screen when you are viewing an object." Handle loading of data from a domain object and passing that data to the view components. Routes should support editing as it makes sense in their own context.
|
||||
|
||||
To facilitate testing:
|
||||
|
||||
* routes should be testable without having to test the actual view.
|
||||
* components should be independently testable with zero knowledge of our data models or telemetry APIs.
|
||||
|
||||
Component code should be organized side by side, such as:
|
||||
|
||||
```
|
||||
app
|
||||
|- components
|
||||
|- productDetail
|
||||
| |- productDetail.js
|
||||
| |- productDetail.css
|
||||
| |- productDetail.html
|
||||
| |- productDetailSpec.js
|
||||
|- productList
|
||||
|- checkout
|
||||
|- wishlist
|
||||
```
|
||||
|
||||
Components are not always reusable, and we shouldn't be overly concerned with making them so. If components are heavily reused, they should either be moved to a platform feature (e.g. notifications, indicators), or broken off as an external dependency (e.g. publish mct-plot as mct-plot.js).
|
||||
|
||||
|
||||
# Reducing interface depth (The angular discussion)
|
||||
|
||||
Two options here: use more angular, use less angular. Wrapping angular methods does not reduce interface depth and must be avoided.
|
||||
|
||||
The primary issue with angular is duplications of concerns-- both angular and the openmctweb platform implement the same tools side by side and it can be hard to comprehend-- it increases interface depth. For other concerns, see footnotes[1].
|
||||
|
||||
Wrapping angular methods for non-view related code is confusing to developers because of the random constraints angular places on these items-- developers ultimately have to understand both angular DI and our framework. For example, it's not possible to name the topic service "topicService" because angular expects Services to be implemented by Providers, which is different than our expectation.
|
||||
|
||||
To reduce interface depth, we can replace our own provider and registry patterns with angular patterns, or we can only utilize angular view logic, and only use our own DI patterns.
|
||||
|
||||
## More angular: for all services
|
||||
|
||||
Increasing our commitment to angular would mean using more of the angular factorys, services, etc, and less of our home grown tools. We'd implement our services and extension points as angular providers, and make them configurable via app.config.
|
||||
|
||||
As an example, registering a specific type of model provider in angular would look like:
|
||||
|
||||
```javascript
|
||||
mct.provider('model', modelProvider() { /* implementation */});
|
||||
|
||||
mct.config(['modelProvider', function (modelProvider) {
|
||||
modelProvider.providers.push(RootModelProvider);
|
||||
}]);
|
||||
```
|
||||
|
||||
## Less angular: only for views
|
||||
|
||||
If we wish to use less angular, I would recommend discontinuing use of all angular components that are not view related-- services, factories, $http, etc, and implementing them in our own paradigm. Otherwise, we end up with layered interfaces-- one of the goals we would like to avoid.
|
||||
|
||||
|
||||
# Standard packaging and build system
|
||||
|
||||
Standardize the packaging and build system, and completely separate the core platform from deployments. Prescribe a starting point for deployments, but allow flexibility.
|
||||
|
||||
## Use systemjs for module loading
|
||||
|
||||
Allow developers to use whatever module loading system they'd like to use, while still supporting all standard cases. We should also use this system for loading assets (css, scss, html templates), which makes it easier to implement a single file deployment using standard build tooling.
|
||||
|
||||
## Use gulp or grunt for standard tooling
|
||||
|
||||
Using gulp or grunt as a task runner would bring us in line with standard web developer workflows and help standardize rendering, deployment, and packaging. Additional tools can be added to the workflow at low cost, simplifying the set up of developer environments.
|
||||
|
||||
Gulp and grunt provide useful developer tooling such as live reload, automatic scss/less/etc compiliation, and ease of extensibility for standard production build processes. They're key in decoupling code.
|
||||
|
||||
## Package openmctweb as single versioned file.
|
||||
|
||||
Deployments should depend on a specific version of openmctweb, but otherwise be allowed to have their own deployment and development toolsets.
|
||||
|
||||
Customizations and deployments of openmctweb should not use the same build tooling as the core platform; instead they should be free to use their own build tools as they wish. (We would provide a template for an application, based on our experience with warp-for-rp and vista)
|
||||
|
||||
Installation and utilization of openmctweb should be as simple as downloading the js file, including it in your own html page, and then initializing an app and running it. If a developer would prefer, they could use bower or npm to handle installation.
|
||||
|
||||
Then, if we're using imperative methods for extending the application we can use the following for basic customization:
|
||||
|
||||
```html
|
||||
<script src="//localhost/openmctweb.js"></script>
|
||||
<script>
|
||||
// can configure from object
|
||||
var myApp = new OpenMCTWeb({
|
||||
persitence: {
|
||||
providers: [
|
||||
{
|
||||
type: 'elastic',
|
||||
uri: 'http://someElasticHost/'
|
||||
} // ...
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
// alternative configurations
|
||||
myApp.persistence.addProvider(MyPersistenceAdapter);
|
||||
myApp.model.addProvider(someProviderObject);
|
||||
|
||||
// Removing via method
|
||||
myApp.persistence.removeProvider('some method for removing functionality');
|
||||
// directly mutating providers
|
||||
myApp.persistence.providers = [ThisProviderStandsAlone];
|
||||
//
|
||||
myApp.run();
|
||||
</script>
|
||||
```
|
||||
|
||||
This packaging reduces the complexity of managing multiple deployed versions, and also allows us to provide users with incredibly simple tutorials-- they can use whatever tooling they like. For instance, a hello world tutorial may take the option of "exposing a new object in the tree".
|
||||
|
||||
```javascript
|
||||
var myApp = new OpenMCTWeb();
|
||||
myApp.roots.addRoot({
|
||||
id: 'myRoot',
|
||||
name: 'Hello World!',
|
||||
});
|
||||
myApp.routes.setDefault('myRoot');
|
||||
myApp.run();
|
||||
```
|
||||
|
||||
# Misc Improvements
|
||||
|
||||
## Refresh on navigation
|
||||
In cases where navigation events change the entire screen, we should be using routes and location changes to navigate between objects. We should be using href for all navigation events.
|
||||
|
||||
At the same time, navigating should refresh state of every visible object. A properly configured persistence store will handle caching with standard cache headers and 304 not modified responses, which will provide good performance of object reloads, while helping us ensure that objects are always in sync between clients.
|
||||
|
||||
View state (say, the expanded tree nodes) should not be tied to caching of data-- it should be something we intentionally persist and restore with each navigation. Data (such as object definitions) should be reloaded from server as necessary to restore state.
|
||||
|
||||
## Move persistence adapter to promise rejection.
|
||||
Simple: reject on fail, resolve on success.
|
||||
|
||||
## Remove bulk requests from providers
|
||||
|
||||
Aggregators can request multiple things at once, but individual providers should only have to implement handling at the level of a single request. Each provider can implement it's own internal batching, but it should support making requests at a finer level of detail.
|
||||
|
||||
Excessive wrapping of code with $q.all causes additional digest cycles and decreased performance.
|
||||
|
||||
For example, instead of every telemetry provider responding to a given telemetry request, aggregators should route each request to the first provider that can fulfill that request.
|
||||
|
||||
|
||||
# Notes on current API proposals:
|
||||
|
||||
* [RequireJS for Dependency Injection](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#requirejs-as-dependency-injector): requires other topics to be discussed first.
|
||||
* [Arbitrary HTML Views](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#arbitrary-html-views): think there is a place for it, requires other topics to be discussed first.
|
||||
* [Wrap Angular Services](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#wrap-angular-services): No, this is bad.
|
||||
* [Bundle definitions in Javascript](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#bundle-declarations-in-javascript): Points to a solution, but ultimately requires more discussion.
|
||||
* [pass around a dependency injector](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#pass-around-a-dependency-injector): No.
|
||||
* [remove partial constructors](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#remove-partial-constructors): Yes, this should be superseded by another proposal though. The entire concept was a messy solution to dependency injection issues caused by declarative syntax.
|
||||
* [Rename views to applications](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#rename-views-to-applications): Points to a problem that needs to be solved but I think the name is bad.
|
||||
* [Provide classes for extensions](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#provide-classes-for-extensions): Yes, in specific places
|
||||
* [Normalize naming conventions](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#normalize-naming-conventions): Yes.
|
||||
* [Expose no third-party APIs](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#expose-no-third-party-apis): Completely disagree, points to a real problem with poor angular integration.
|
||||
* [Register Extensions as Instances instead of Constructors](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#register-extensions-as-instances-instead-of-constructors): Superseded by the fact that we should not hope to implement a generic construct.
|
||||
* [Remove capability delegation](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#remove-capability-delegation): Yes.
|
||||
* [Nomenclature Change](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#nomenclature-change): Yes, hope to discuss the implications of this more clearly in other proposals.
|
||||
* [Capabilities as mixins](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#capabilities-as-mixins): Yes.
|
||||
* [Remove appliesTo methods](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#remove-applies-to-methods): No-- I think some level of this is necessary. I think a more holistic approach to policy is needed. it's a rather complicated system.
|
||||
* [Revise telemetry API](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#revise-telemetry-api): If we can rough out and agree to the specifics, then Yes. Needs discussion.
|
||||
* [Allow composite services to fail gracefully](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#allow-composite-services-to-fail-gracefully): No. As mentioned above, I think composite services themselves should be eliminated for a more purpose bound tool.
|
||||
* [Plugins as angular modules](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#plugins-as-angular-modules): Should we decide to embrace Angular completely, I would support this. Otherwise, no.
|
||||
* [Contextual Injection](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#contextual-injection): No, don't see a need.
|
||||
* [Add New Abstractions for Actions](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#add-new-abstractions-for-actions): Worth a discussion.
|
||||
* [Add gesture handlers](https://github.com/nasa/openmctweb/blob/api-redesign/docs/src/design/proposals/APIRedesign.md#add-gesture-handlers): Yes if we can agree on details. We need a platform implementation that is easy to use, but we should not reinvent the wheel.
|
||||
|
||||
|
||||
|
||||
# [1] Footnote: The angular debacle
|
||||
|
||||
## "Do or do not, there is no try"
|
||||
|
||||
A commonly voiced concern of embracing angular is the possibility of becoming dependent on a third party framework. This concern is itself detrimental-- if we're afraid of becoming dependent on a third party framework, then we will do a bad job of using the framework, and inevitably will want to stop using it.
|
||||
|
||||
If we're using a framework, we need to use it fully, or not use it at all.
|
||||
|
||||
## A lack of commitment
|
||||
|
||||
A number of the concerns we heard from developers and interns can be attributed to the tenuous relationship between the OpenMCTWeb platform and angular. We claimed to be angular, but we weren't really angular. Instead, we are caught between our incomplete framework paradigm and the angular paradigm. In many cases we reinvented the wheel or worked around functionality that angular provides, and ended up in a more confusing state.
|
||||
|
||||
## Commitment is good!
|
||||
|
||||
We could just be an application that is built with angular.
|
||||
|
||||
An application that is modular and extensible not because it reinvents tools for providing modularity and extensibility, but because it reuses existing tools for modularity and extensibility.
|
||||
|
||||
There are benefits to buying into the angular paradigm: shift documentation burden to external project, engage a larger talent pool available both as voluntary open source contributors and as experienced developers for hire, and gain access to an ecosystem of tools that we can use to increase the speed of development.
|
||||
|
||||
There are negatives too: Angular is a monolith, it has performance concerns, and an unclear future. If we can't live with it, we should look at alternatives.
|
||||
|
@ -1,164 +0,0 @@
|
||||
# Imperative Plugins
|
||||
|
||||
This is a design proposal for handling
|
||||
[bundle declarations in JavaScript](
|
||||
APIRedesign.md#bundle-declarations-in-javascript).
|
||||
|
||||
## Developer Use Cases
|
||||
|
||||
Developers will want to use bundles/plugins to (in rough order
|
||||
of occurrence):
|
||||
|
||||
1. Add new extension instances.
|
||||
2. Use existing services
|
||||
3. Add new service implementations.
|
||||
4. Decorate service implementations.
|
||||
5. Decorate extension instances.
|
||||
6. Add new types of services.
|
||||
7. Add new extension categories.
|
||||
|
||||
Notably, bullets 4 and 5 above are currently handled implicitly,
|
||||
which has been cited as a source of confusion.
|
||||
|
||||
## Interfaces
|
||||
|
||||
Two base classes may be used to satisfy these use cases:
|
||||
|
||||
* The `CompositeServiceFactory` provides composite service instances.
|
||||
Decorators may be added; the approach used for compositing may be
|
||||
modified; and individual services may be registered to support compositing.
|
||||
* The `ExtensionRegistry` allows for the simpler case where what is desired
|
||||
is an array of all instances of some kind of thing within the system.
|
||||
|
||||
Note that additional developer use cases may be supported by using the
|
||||
more general-purpose `Registry`
|
||||
|
||||
```nomnoml
|
||||
[Factory.<T, V>
|
||||
|
|
||||
- factoryFn : function (V) : T
|
||||
|
|
||||
+ decorate(decoratorFn : function (T, V) : T, options? : RegistrationOptions)
|
||||
]-:>[function (V) : T]
|
||||
|
||||
[RegistrationOptions |
|
||||
+ priority : number or string
|
||||
]
|
||||
|
||||
[Registry.<T, V>
|
||||
|
|
||||
- compositorFn : function (Array.<T>) : V
|
||||
|
|
||||
+ register(item : T, options? : RegistrationOptions)
|
||||
+ composite(compositorFn : function (Array.<T>) : V, options? : RegistrationOptions)
|
||||
]-:>[Factory.<V, Void>]
|
||||
[Factory.<V, Void>]-:>[Factory.<T, V>]
|
||||
|
||||
[ExtensionRegistry.<T>]-:>[Registry.<T, Array.<T>>]
|
||||
[Registry.<T, Array.<T>>]-:>[Registry.<T, V>]
|
||||
|
||||
[CompositeServiceFactory.<T>]-:>[Registry.<T, T>]
|
||||
[Registry.<T, T>]-:>[Registry.<T, V>]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### 1. Add new extension instances.
|
||||
|
||||
```js
|
||||
// Instance-style registration
|
||||
mct.types.register(new mct.Type({
|
||||
key: "timeline",
|
||||
name: "Timeline",
|
||||
description: "A container for activities ordered in time."
|
||||
});
|
||||
|
||||
// Factory-style registration
|
||||
mct.actions.register(function (domainObject) {
|
||||
return new RemoveAction(domainObject);
|
||||
}, { priority: 200 });
|
||||
```
|
||||
|
||||
### 2. Use existing services
|
||||
|
||||
```js
|
||||
mct.actions.register(function (domainObject) {
|
||||
var dialogService = mct.ui.dialogServiceFactory();
|
||||
return new PropertiesAction(dialogService, domainObject);
|
||||
});
|
||||
```
|
||||
|
||||
### 3. Add new service implementations
|
||||
|
||||
```js
|
||||
// Instance-style registration
|
||||
mct.persistenceServiceFactory.register(new LocalPersistenceService());
|
||||
|
||||
// Factory-style registration
|
||||
mct.persistenceServiceFactory.register(function () {
|
||||
var $http = angular.injector(['ng']).get('$http');
|
||||
return new LocalPersistenceService($http);
|
||||
});
|
||||
```
|
||||
|
||||
### 4. Decorate service implementations
|
||||
|
||||
```js
|
||||
mct.modelServiceFactory.decorate(function (modelService) {
|
||||
return new CachingModelDecorator(modelService);
|
||||
}, { priority: 100 });
|
||||
```
|
||||
|
||||
### 5. Decorate extension instances
|
||||
|
||||
```js
|
||||
mct.capabilities.decorate(function (capabilities) {
|
||||
return capabilities.map(decorateIfApplicable);
|
||||
});
|
||||
```
|
||||
|
||||
This use case is not well-supported by these API changes. The most
|
||||
common case for decoration is capabilities, which are under reconsideration;
|
||||
should consider handling decoration of capabilities in a different way.
|
||||
|
||||
### 6. Add new types of services
|
||||
|
||||
```js
|
||||
myModule.myServiceFactory = new mct.CompositeServiceFactory();
|
||||
|
||||
// In cases where a custom composition strategy is desired
|
||||
myModule.myServiceFactory.composite(function (services) {
|
||||
return new MyServiceCompositor(services);
|
||||
});
|
||||
```
|
||||
|
||||
### 7. Add new extension categories.
|
||||
|
||||
```js
|
||||
myModule.hamburgers = new mct.ExtensionRegistry();
|
||||
```
|
||||
|
||||
## Evaluation
|
||||
|
||||
### Benefits
|
||||
|
||||
* Encourages separation of registration from declaration (individual
|
||||
components are decoupled from the manner in which they are added
|
||||
to the architecture.)
|
||||
* Minimizes "magic." Dependencies are acquired, managed, and exposed
|
||||
using plain-old-JavaScript without any dependency injector present
|
||||
to obfuscate what is happening.
|
||||
* Offers comparable expressive power to existing APIs; can still
|
||||
extend the behavior of platform components in a variety of ways.
|
||||
* Does not force or limit formalisms to use;
|
||||
|
||||
### Detriments
|
||||
|
||||
* Does not encourage separation of dependency acquisition from
|
||||
declaration; that is, it would be quite natural using this API
|
||||
to acquire references to services during the constructor call
|
||||
to an extension or service. But, passing these in as constructor
|
||||
arguments is preferred (to separate implementation from architecture.)
|
||||
* Adds (negligible?) boilerplate relative to declarative syntax.
|
||||
* Relies on factories, increasing number of interfaces to be concerned
|
||||
with.
|
@ -1,138 +0,0 @@
|
||||
# Roles
|
||||
|
||||
Roles are presented as an alternative formulation to capabilities
|
||||
(dynamic behavior associated with individual domain objects.)
|
||||
|
||||
Specific goals here:
|
||||
|
||||
* Dependencies of individual scripts should be clear.
|
||||
* Domain objects should be able to selectively exhibit a wide
|
||||
variety of behaviors.
|
||||
|
||||
## Developer Use Cases
|
||||
|
||||
1. Checking for the existence of behavior.
|
||||
2. Using behavior.
|
||||
3. Augmenting existing behaviors.
|
||||
4. Overriding existing behaviors.
|
||||
5. Adding new behaviors.
|
||||
|
||||
## Overview of Proposed Solution
|
||||
|
||||
Remove `getCapability` from domain objects; add roles as external
|
||||
services which can be applied to domain objects.
|
||||
|
||||
## Interfaces
|
||||
|
||||
```nomnoml
|
||||
[Factory.<T, V>
|
||||
|
|
||||
- factoryFn : function (V) : T
|
||||
|
|
||||
+ decorate(decoratorFn : function (T, V) : T, options? : RegistrationOptions)
|
||||
]-:>[function (V) : T]
|
||||
|
||||
[RegistrationOptions |
|
||||
+ priority : number or string
|
||||
]<:-[RoleOptions |
|
||||
+ validate : function (DomainObject) : boolean
|
||||
]
|
||||
|
||||
[Role.<T> |
|
||||
+ validate(domainObject : DomainObject) : boolean
|
||||
+ decorate(decoratorFn : function (T, V) : T, options? : RoleOptions)
|
||||
]-:>[Factory.<T, DomainObject>]
|
||||
[Factory.<T, DomainObject>]-:>[Factory.<T, V>]
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### 1. Checking for the existence of behavior
|
||||
|
||||
```js
|
||||
function PlotViewPolicy(telemetryRole) {
|
||||
this.telemetryRole = telemetryRole;
|
||||
}
|
||||
PlotViewPolicy.prototype.allow = function (view, domainObject) {
|
||||
return this.telemetryRole.validate(domainObject);
|
||||
};
|
||||
```
|
||||
|
||||
### 2. Using behavior
|
||||
|
||||
```js
|
||||
PropertiesAction.prototype.perform = function () {
|
||||
var mutation = this.mutationRole(this.domainObject);
|
||||
return this.showDialog.then(function (newModel) {
|
||||
return mutation.mutate(function () {
|
||||
return newModel;
|
||||
});
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
### 3. Augmenting existing behaviors
|
||||
|
||||
```js
|
||||
// Non-Angular style
|
||||
mct.roles.persistenceRole.decorate(function (persistence) {
|
||||
return new DecoratedPersistence(persistence);
|
||||
});
|
||||
|
||||
// Angular style
|
||||
myModule.decorate('persistenceRole', ['$delegate', function ($delegate) {
|
||||
return new DecoratedPersistence(persistence);
|
||||
}]);
|
||||
```
|
||||
|
||||
### 4. Overriding existing behaviors
|
||||
|
||||
```js
|
||||
// Non-Angular style
|
||||
mct.roles.persistenceRole.decorate(function (persistence, domainObject) {
|
||||
return domainObject.getModel().type === 'someType' ?
|
||||
new DifferentPersistence(domainObject) :
|
||||
persistence;
|
||||
}, {
|
||||
validate: function (domainObject, next) {
|
||||
return domainObject.getModel().type === 'someType' || next();
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### 5. Adding new behaviors
|
||||
|
||||
```js
|
||||
function FooRole() {
|
||||
mct.Role.apply(this, [function (domainObject) {
|
||||
return new Foo(domainObject);
|
||||
}]);
|
||||
}
|
||||
|
||||
FooRole.prototype = Object.create(mct.Role.prototype);
|
||||
|
||||
FooRole.prototype.validate = function (domainObject) {
|
||||
return domainObject.getModel().type === 'some-type';
|
||||
};
|
||||
|
||||
//
|
||||
myModule.roles.fooRole = new FooRole();
|
||||
```
|
||||
|
||||
|
||||
## Evaluation
|
||||
|
||||
### Benefits
|
||||
|
||||
* Simplifies/standardizes augmentation or replacement of behavior associated
|
||||
with specific domain objects.
|
||||
* Minimizes number of abstractions; roles are just factories.
|
||||
* Clarifies dependencies; roles used must be declared/acquired in the
|
||||
same manner as services.
|
||||
|
||||
### Detriments
|
||||
|
||||
* Externalizes functionality which is conceptually associated with a
|
||||
domain object.
|
||||
* Relies on factories, increasing number of interfaces to be concerned
|
||||
with.
|
36
docs/src/index.html
Normal file
@ -0,0 +1,36 @@
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head lang="en">
|
||||
<meta charset="UTF-8">
|
||||
<title>Open MCT Web Documentation</title>
|
||||
</head>
|
||||
<body class="user-environ" ng-view>
|
||||
Sections:
|
||||
<ul>
|
||||
<li><a href="api/">API</a></li>
|
||||
<li><a href="guide/">Developer Guide</a></li>
|
||||
<li><a href="architecture/">Architecture Overview</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
@ -1,35 +0,0 @@
|
||||
# Open MCT Web Documentation
|
||||
|
||||
## Overview
|
||||
|
||||
Documentation is provided to support the use and development of
|
||||
Open MCT Web. It's recommended that before doing
|
||||
any development with Open MCT Web you take some time to familiarize yourself
|
||||
with the documentation below.
|
||||
|
||||
Open MCT Web provides functionality out of the box, but it's also a platform for
|
||||
building rich mission operations applications based on modern web technology.
|
||||
The platform is configured declaratively, and defines conventions for
|
||||
building on the provided capabilities by creating modular 'bundles' that
|
||||
extend the platform at a variety of extension points. The details of how to
|
||||
extend the platform are provided in the following documentation.
|
||||
|
||||
## Sections
|
||||
|
||||
* The [Architecture Overview](architecture/) describes the concepts used
|
||||
throughout Open MCT Web, and gives a high level overview of the platform's design.
|
||||
|
||||
* The [Developer's Guide](guide/) goes into more detail about how to use the
|
||||
platform and the functionality that it provides.
|
||||
|
||||
* The [Tutorials](tutorials/) give examples of extending the platform to add
|
||||
functionality,
|
||||
and integrate with data sources.
|
||||
|
||||
* The [API](api/) document is generated from inline documentation
|
||||
using [JSDoc](http://usejsdoc.org/), and describes the JavaScript objects and
|
||||
functions that make up the software platform.
|
||||
|
||||
* Finally, the [Development Process](process/) document describes the
|
||||
Open MCT Web software development cycle.
|
||||
|
@ -1,159 +0,0 @@
|
||||
# Development Cycle
|
||||
|
||||
Development of Open MCT Web occurs on an iterative cycle of
|
||||
sprints and releases.
|
||||
|
||||
* A _sprint_ is three weeks in duration, and represents a
|
||||
set of improvements that can be completed and tested by the
|
||||
development team. Software at the end of the sprint is
|
||||
"semi-stable"; it will have undergone reduced testing and may carry
|
||||
defects or usability issues of lower severity, particularly if
|
||||
there are workarounds.
|
||||
* A _release_ occurs every four sprints. Releases are stable, and
|
||||
will have undergone full acceptance testing to ensure that the
|
||||
software behaves correctly and usably.
|
||||
|
||||
## Roles
|
||||
|
||||
The sprint process assumes the presence of a __project manager.__
|
||||
The project manager is responsible for
|
||||
making tactical decisions about what development work will be
|
||||
performed, and for coordinating with stakeholders to arrive at
|
||||
higher-level strategic decisions about desired functionality
|
||||
and characteristics of the software, major external milestones,
|
||||
and so forth.
|
||||
|
||||
In the absence of a dedicated project manager, this role may be rotated
|
||||
among members of the development team on a per-sprint basis.
|
||||
|
||||
Responsibilities of the project manager including:
|
||||
|
||||
* Maintaining (with agreement of stakeholders) a "road map" of work
|
||||
planned for future releases/sprints; this should be higher-level,
|
||||
usually expressed as "themes",
|
||||
with just enough specificity to gauge feasibility of plans,
|
||||
relate work back to milestones, and identify longer-term
|
||||
dependencies.
|
||||
* Determining (with assistance from the rest of the team) which
|
||||
issues to work on in a given sprint and how they shall be
|
||||
assigned.
|
||||
* Pre-planning subsequent sprints to ensure that all members of the
|
||||
team always have a clear direction.
|
||||
* Scheduling and/or ensuring adherence to
|
||||
[process points](#process-points).
|
||||
* Responding to changes within the sprint (shifting priorities,
|
||||
new issues) and re-allocating work for the sprint as needed.
|
||||
|
||||
## Sprint Calendar
|
||||
|
||||
Certain [process points](#process-points) are regularly scheduled in
|
||||
the sprint cycle.
|
||||
|
||||
### Sprints by Release
|
||||
|
||||
Allocation of work among sprints should be planned relative to release
|
||||
goals and milestones. As a general guideline, higher-risk work (large
|
||||
new features which may carry new defects, major refactoring, design
|
||||
changes with uncertain effects on usability) should be allocated to
|
||||
earlier sprints, allowing for time in later sprints to ensure stability.
|
||||
|
||||
| Sprint | Focus |
|
||||
|:------:|:--------------------------------------------------------|
|
||||
| __1__ | Prototyping, design, experimentation. |
|
||||
| __2__ | New features, refinements, enhancements. |
|
||||
| __3__ | Feature completion, low-risk enhancements, bug fixing. |
|
||||
| __4__ | Stability & quality assurance. |
|
||||
|
||||
### Sprints 1-3
|
||||
|
||||
The first three sprints of a release are primarily centered around
|
||||
development work, with regular acceptance testing in the third
|
||||
week. During this third week, the top priority should be passing
|
||||
acceptance testing (e.g. by resolving any blockers found); any
|
||||
resources not needed for this effort should be used to begin work
|
||||
for the subsequent sprint.
|
||||
|
||||
| Week | Mon | Tue | Wed | Thu | Fri |
|
||||
|:-----:|:-------------------------:|:------:|:---:|:----------------------------:|:-----------:|
|
||||
| __1__ | Sprint plan | Tag-up | | | |
|
||||
| __2__ | | Tag-up | | | Code freeze |
|
||||
| __3__ | Per-sprint testing | Triage | | _Per-sprint testing*_ | Ship |
|
||||
|
||||
* If necessary.
|
||||
|
||||
### Sprint 4
|
||||
|
||||
The software must be stable at the end of the fourth sprint; because of
|
||||
this, the fourth sprint is scheduled differently, with a heightened
|
||||
emphasis on testing.
|
||||
|
||||
| Week | Mon | Tue | Wed | Thu | Fri |
|
||||
|-------:|:-------------------------:|:------:|:---:|:----------------------------:|:-----------:|
|
||||
| __1__ | Sprint plan | Tag-up | | | Code freeze |
|
||||
| __2__ | Per-release testing | Triage | | | |
|
||||
| __3__ | _Per-release testing*_ | Triage | | _Per-release testing*_ | Ship |
|
||||
|
||||
* If necessary.
|
||||
|
||||
## Process Points
|
||||
|
||||
* __Sprint plan.__ Project manager allocates issues based on
|
||||
theme(s) for sprint, then reviews with team. Each team member
|
||||
should have roughly two weeks of work allocated (to allow time
|
||||
in the third week for testing of work completed.)
|
||||
* Project manager should also sketch out subsequent sprint so
|
||||
that team may begin work for that sprint during the
|
||||
third week, since testing and blocker resolution is unlikely
|
||||
to require all available resources.
|
||||
* __Tag-up.__ Check in and status update among development team.
|
||||
May amend plan for sprint as-needed.
|
||||
* __Code freeze.__ Any new work from this sprint
|
||||
(features, bug fixes, enhancements) must be integrated by the
|
||||
end of the second week of the sprint. After code freeze
|
||||
(and until the end of the sprint) the only changes that should be
|
||||
merged into the master branch should directly address issues
|
||||
needed to pass acceptance testing.
|
||||
* [__Per-release Testing.__](testing/plan.md#per-release-testing)
|
||||
Structured testing with predefined
|
||||
success criteria. No release should ship without passing
|
||||
acceptance tests. Time is allocated in each sprint for subsequent
|
||||
rounds of acceptance testing if issues are identified during a
|
||||
prior round. Specific details of acceptance testing need to be
|
||||
agreed-upon with relevant stakeholders and delivery recipients,
|
||||
and should be flexible enough to allow changes to plans
|
||||
(e.g. deferring delivery of some feature in order to ensure
|
||||
stability of other features.) Baseline testing includes:
|
||||
* [__Testathon.__](testing/plan.md#user-testing)
|
||||
Multi-user testing, involving as many users as
|
||||
is feasible, plus development team. Open-ended; should verify
|
||||
completed work from this sprint, test exploratorily for
|
||||
regressions, et cetera.
|
||||
* [__Long-Duration Test.__](testing/plan.md#long-duration-testing) A
|
||||
test to verify that the software remains
|
||||
stable after running for longer durations. May include some
|
||||
combination of automated testing and user verification (e.g.
|
||||
checking to verify that software remains subjectively
|
||||
responsive at conclusion of test.)
|
||||
* [__Unit Testing.__](testing/plan.md#unit-testing)
|
||||
Automated testing integrated into the
|
||||
build. (These tests are verified to pass more often than once
|
||||
per sprint, as they run before any merge to master, but still
|
||||
play an important role in per-release testing.)
|
||||
* [__Per-sprint Testing.__](testing/plan.md#per-sprint-testing)
|
||||
Subset of Pre-release Testing
|
||||
which should be performed before shipping at the end of any
|
||||
sprint. Time is allocated for a second round of
|
||||
Pre-release Testing if the first round is not passed.
|
||||
* __Triage.__ Team reviews issues from acceptance testing and uses
|
||||
success criteria to determine whether or not they should block
|
||||
release, then formulates a plan to address these issues before
|
||||
the next round of acceptance testing. Focus here should be on
|
||||
ensuring software passes that testing in order to ship on time;
|
||||
may prefer to disable malfunctioning components and fix them
|
||||
in a subsequent sprint, for example.
|
||||
* [__Ship.__](version.md) Tag a code snapshot that has passed release/sprint
|
||||
testing and deploy that version. (Only true if relevant
|
||||
testing has passed by this point; if testing has not
|
||||
been passed, will need to make ad hoc decisions with stakeholders,
|
||||
e.g. "extend the sprint" or "defer shipment until end of next
|
||||
sprint.")
|
@ -1,15 +0,0 @@
|
||||
# Development Process
|
||||
|
||||
The process used to develop Open MCT Web is described in the following
|
||||
documents:
|
||||
|
||||
* The [Development Cycle](cycle.md) describes how and when specific
|
||||
process points are repeated during development.
|
||||
* The [Version Guide](version.md) describes version numbering for
|
||||
Open MCT (both semantics and process.)
|
||||
* Testing is described in two documents:
|
||||
* The [Test Plan](testing/plan.md) summarizes the approaches used
|
||||
to test Open MCT Web.
|
||||
* The [Test Procedures](testing/procedures.md) document what
|
||||
specific tests are performed to verify correctness, and how
|
||||
they should be carried out.
|
@ -1,127 +0,0 @@
|
||||
# Test Plan
|
||||
|
||||
## Test Levels
|
||||
|
||||
Testing for Open MCT Web includes:
|
||||
|
||||
* _Smoke testing_: Brief, informal testing to verify that no major issues
|
||||
or regressions are present in the software, or in specific features of
|
||||
the software.
|
||||
* _Unit testing_: Automated verification of the performance of individual
|
||||
software components.
|
||||
* _User testing_: Testing with a representative user base to verify
|
||||
that application behaves usably and as specified.
|
||||
* _Long-duration testing_: Testing which takes place over a long period
|
||||
of time to detect issues which are not readily noticeable during
|
||||
shorter test periods.
|
||||
|
||||
### Smoke Testing
|
||||
|
||||
Manual, non-rigorous testing of the software and/or specific features
|
||||
of interest. Verifies that the software runs and that basic functionality
|
||||
is present.
|
||||
|
||||
### Unit Testing
|
||||
|
||||
Unit tests are automated tests which exercise individual software
|
||||
components. Tests are subject to code review along with the actual
|
||||
implementation, to ensure that tests are applicable and useful.
|
||||
|
||||
Unit tests should meet
|
||||
[test standards](https://github.com/nasa/openmctweb/blob/master/CONTRIBUTING.md#test-standards)
|
||||
as described in the contributing guide.
|
||||
|
||||
### User Testing
|
||||
|
||||
User testing is performed at scheduled times involving target users
|
||||
of the software or reasonable representatives, along with members of
|
||||
the development team exercising known use cases. Users test the
|
||||
software directly; the software should be configured as similarly to
|
||||
its planned production configuration as is feasible without introducing
|
||||
other risks (e.g. damage to data in a production instance.)
|
||||
|
||||
User testing will focus on the following activities:
|
||||
|
||||
* Verifying issues resolved since the last test session.
|
||||
* Checking for regressions in areas related to recent changes.
|
||||
* Using major or important features of the software,
|
||||
as determined by the user.
|
||||
* General "trying to break things."
|
||||
|
||||
During user testing, users will
|
||||
[report issues](https://github.com/nasa/openmctweb/blob/master/CONTRIBUTING.md#issue-reporting)
|
||||
as they are encountered.
|
||||
|
||||
Desired outcomes of user testing are:
|
||||
|
||||
* Identified software defects.
|
||||
* Areas for usability improvement.
|
||||
* Feature requests (particularly missed requirements.)
|
||||
* Recorded issue verification.
|
||||
|
||||
### Long-duration Testing
|
||||
|
||||
Long-duration testing occurs over a twenty-four hour period. The
|
||||
software is run in one or more stressing cases representative of expected
|
||||
usage. After twenty-four hours, the software is evaluated for:
|
||||
|
||||
* Performance metrics: Have memory usage or CPU utilization increased
|
||||
during this time period in unexpected or undesirable ways?
|
||||
* Subjective usability: Does the software behave in the same way it did
|
||||
at the start of the test? Is it as responsive?
|
||||
|
||||
Any defects or unexpected behavior identified during testing should be
|
||||
[reported as issues](https://github.com/nasa/openmctweb/blob/master/CONTRIBUTING.md#issue-reporting)
|
||||
and reviewed for severity.
|
||||
|
||||
## Test Performance
|
||||
|
||||
Tests are performed at various levels of frequency.
|
||||
|
||||
* _Per-merge_: Performed before any new changes are integrated into
|
||||
the software.
|
||||
* _Per-sprint_: Performed at the end of every [sprint](../cycle.md).
|
||||
* _Per-release_: Performed at the end of every [release](../cycle.md).
|
||||
|
||||
### Per-merge Testing
|
||||
|
||||
Before changes are merged, the author of the changes must perform:
|
||||
|
||||
* _Smoke testing_ (both generally, and for areas which interact with
|
||||
the new changes.)
|
||||
* _Unit testing_ (as part of the automated build step.)
|
||||
|
||||
Changes are not merged until the author has affirmed that both
|
||||
forms of testing have been performed successfully; this is documented
|
||||
by the [Author Checklist](https://github.com/nasa/openmctweb/blob/master/CONTRIBUTING.md#author-checklist).
|
||||
|
||||
### Per-sprint Testing
|
||||
|
||||
Before a sprint is closed, the development team must additionally
|
||||
perform:
|
||||
|
||||
* A relevant subset of [_user testing_](procedures.md#user-test-procedures)
|
||||
identified by the acting [project manager](../cycle.md#roles).
|
||||
* [_Long-duration testing_](procedures.md#long-duration-testng)
|
||||
(specifically, for 24 hours.)
|
||||
|
||||
Issues are reported as a product of both forms of testing.
|
||||
|
||||
A sprint is not closed until both categories have been performed on
|
||||
the latest snapshot of the software, _and_ no issues labelled as
|
||||
["blocker"](https://github.com/nasa/openmctweb/blob/master/CONTRIBUTING.md#issue-reporting)
|
||||
remain open.
|
||||
|
||||
### Per-release Testing
|
||||
|
||||
As [per-sprint testing](#per-sprint-testing), except that _user testing_
|
||||
should cover all test cases, with less focus on changes from the specific
|
||||
sprint or release.
|
||||
|
||||
Per-release testing should also include any acceptance testing steps
|
||||
agreed upon with recipients of the software.
|
||||
|
||||
A release is not closed until both categories have been performed on
|
||||
the latest snapshot of the software, _and_ no issues labelled as
|
||||
["blocker" or "critical"](https://github.com/nasa/openmctweb/blob/master/CONTRIBUTING.md#issue-reporting)
|
||||
remain open.
|
@ -1,169 +0,0 @@
|
||||
# Test Procedures
|
||||
|
||||
## Introduction
|
||||
|
||||
This document is intended to be used:
|
||||
|
||||
* By testers, to verify that Open MCT Web behaves as specified.
|
||||
* By the development team, to document new test cases and to provide
|
||||
guidance on how to author these.
|
||||
|
||||
## Writing Procedures
|
||||
|
||||
### Template
|
||||
|
||||
Procedures for individual tests should use the following template,
|
||||
adapted from [https://swehb.nasa.gov/display/7150/SWE-114]().
|
||||
|
||||
Property | Value
|
||||
---------------|---------------------------------------------------------------
|
||||
Test ID |
|
||||
Relevant reqs. |
|
||||
Prerequisites |
|
||||
Test input |
|
||||
Instructions |
|
||||
Expectation |
|
||||
Eval. criteria |
|
||||
|
||||
For multi-line descriptions, use an asterisk or similar indicator to refer
|
||||
to a longer-form description below.
|
||||
|
||||
#### Example Procedure - Edit a Layout
|
||||
|
||||
Property | Value
|
||||
---------------|---------------------------------------------------------------
|
||||
Test ID | MCT-TEST-000X - Edit a layout
|
||||
Relevant reqs. | MCT-EDIT-000Y
|
||||
Prerequisites | Create a layout, as in MCT-TEST-000Z
|
||||
Test input | Domain object database XYZ
|
||||
Instructions | See below *
|
||||
Expectation | Change to editing context †
|
||||
Eval. criteria | Visual inspection
|
||||
|
||||
* Follow the following steps:
|
||||
|
||||
1. Verify that the created layout is currently navigated-to,
|
||||
as in MCT-TEST-00ZZ.
|
||||
2. Click the Edit button, identified by a pencil icon and the text "Edit"
|
||||
displayed on hover.
|
||||
|
||||
† Right-hand viewing area should be surrounded by a dashed
|
||||
blue border when a domain object is being edited.
|
||||
|
||||
### Guidelines
|
||||
|
||||
Test procedures should be written assuming minimal prior knowledge of the
|
||||
application: Non-standard terms should only be used when they are documented
|
||||
in [the glossary](#glossary), and shorthands used for user actions should
|
||||
be accompanied by useful references to test procedures describing those
|
||||
actions (when available) or descriptions in user documentation.
|
||||
|
||||
Test cases should be narrow in scope; if a list of steps is excessively
|
||||
long (or must be written vaguely to be kept short) it should be broken
|
||||
down into multiple tests which reference one another.
|
||||
|
||||
All requirements satisfied by Open MCT Web should be verifiable using
|
||||
one or more test procedures.
|
||||
|
||||
## Glossary
|
||||
|
||||
This section will contain terms used in test procedures. This may link to
|
||||
a common glossary, to avoid replication of content.
|
||||
|
||||
## Procedures
|
||||
|
||||
This section will contain specific test procedures. Presently, procedures
|
||||
are placeholders describing general patterns for setting up and conducting
|
||||
testing.
|
||||
|
||||
### User Testing Setup
|
||||
|
||||
These procedures describes a general pattern for setting up for user
|
||||
testing. Specific deployments should customize this pattern with
|
||||
relevant data and any additional steps necessary.
|
||||
|
||||
Property | Value
|
||||
---------------|---------------------------------------------------------------
|
||||
Test ID | MCT-TEST-SETUP0 - User Testing Setup
|
||||
Relevant reqs. | TBD
|
||||
Prerequisites | Build of relevant components
|
||||
Test input | Exemplary database; exemplary telemetry data set
|
||||
Instructions | See below
|
||||
Expectation | Able to load application in a web browser (Google Chrome)
|
||||
Eval. criteria | Visual inspection
|
||||
|
||||
Instructions:
|
||||
|
||||
1. Start telemetry server.
|
||||
2. Start ElasticSearch.
|
||||
3. Restore database snapshot to ElasticSearch.
|
||||
4. Start telemetry playback.
|
||||
5. Start HTTP server for client sources.
|
||||
|
||||
### User Test Procedures
|
||||
|
||||
Specific user test cases have not yet been authored. In their absence,
|
||||
user testing is conducted by:
|
||||
|
||||
* Reviewing the text of issues from the issue tracker to understand the
|
||||
desired behavior, and exercising this behavior in the running application.
|
||||
(For instance, by following steps to reproduce from the original issue.)
|
||||
* Issues which appear to be resolved should be marked as such with comments
|
||||
on the original issue (e.g. "verified during user testing MM/DD/YYYY".)
|
||||
* Issues which appear not to have been resolved should be reopened with an
|
||||
explanation of what unexpected behavior has been observed.
|
||||
* In cases where an issue appears resolved as-worded but other related
|
||||
undesirable behavior is observed during testing, a new issue should be
|
||||
opened, and linked to from a comment in the original issues.
|
||||
* General usage of new features and/or existing features which have undergone
|
||||
recent changes. Defects or problems with usability should be documented
|
||||
by filing issues in the issue tracker.
|
||||
* Open-ended testing to discover defects, identify usability issues, and
|
||||
generate feature requests.
|
||||
|
||||
### Long-Duration Testing
|
||||
|
||||
The purpose of long-duration testing is to identify performance issues
|
||||
and/or other defects which are sensitive to the amount of time the
|
||||
application is kept running. (Memory leaks, for instance.)
|
||||
|
||||
Property | Value
|
||||
---------------|---------------------------------------------------------------
|
||||
Test ID | MCT-TEST-LDT0 - Long-duration Testing
|
||||
Relevant reqs. | TBD
|
||||
Prerequisites | MCT-TEST-SETUP0
|
||||
Test input | (As for test setup.)
|
||||
Instructions | See "Instructions" below *
|
||||
Expectation | See "Expectations" below †
|
||||
Eval. criteria | Visual inspection
|
||||
|
||||
* Instructions:
|
||||
|
||||
1. Start `top` or a similar tool to measure CPU usage and memory utilization.
|
||||
2. Open several user-created displays (as many as would be realistically
|
||||
opened during actual usage in a stressing case) in some combination of
|
||||
separate tabs and windows (approximately as many tabs-per-window as
|
||||
total windows.)
|
||||
3. Ensure that playback data is set to run continuously for at least 24 hours
|
||||
(e.g. on a loop.)
|
||||
4. Record CPU usage and memory utilization.
|
||||
5. In at least one tab, try some general user interface gestures and make
|
||||
notes about the subjective experience of using the application. (Particularly,
|
||||
the degree of responsiveness.)
|
||||
6. Leave client displays open for 24 hours.
|
||||
7. Record CPU usage and memory utilization again.
|
||||
8. Make additional notes about the subjective experience of using the
|
||||
application (again, particularly responsiveness.)
|
||||
9. Check logs for any unexpected warnings or errors.
|
||||
|
||||
† Expectations:
|
||||
|
||||
* At the end of the test, CPU usage and memory usage should both be similar
|
||||
to their levels at the start of the test.
|
||||
* At the end of the test, subjective usage of the application should not
|
||||
be observably different from the way it was at the start of the test.
|
||||
(In particular, responsiveness should not decrease.)
|
||||
* Logs should not contain any unexpected warnings or errors ("expected"
|
||||
warnings or errors are those that have been documented and prioritized
|
||||
as known issues, or those that are explained by transient conditions
|
||||
external to the software, such as network outages.)
|
@ -1,142 +0,0 @@
|
||||
# Version Guide
|
||||
|
||||
This document describes semantics and processes for providing version
|
||||
numbers for Open MCT, and additionally provides guidelines for dependent
|
||||
projects developed by the same team.
|
||||
|
||||
Versions are incremented at specific points in Open MCT's
|
||||
[Development Cycle](cycle.md); see that document for a description of
|
||||
sprints and releases.
|
||||
|
||||
## Audience
|
||||
|
||||
Individuals interested in consuming version numbers can be categorized as
|
||||
follows:
|
||||
|
||||
* _Users_: Generally disinterested, occasionally wish to identify version
|
||||
to cross-reference against documentation, or to report issues.
|
||||
* _Testers_: Want to identify which version of the software they are
|
||||
testing, e.g. to file issues for defects.
|
||||
* _Internal developers_: Often, inverse of testers; want to identify which
|
||||
version of software was/is in use when certain behavior is observed. Want
|
||||
to be able to correlate versions in use with “streams” of development
|
||||
(e.g. dev vs. prod), when possible.
|
||||
* _External developers_: Need to understand which version of software is
|
||||
in use when developing/maintaining plug-ins, in order to ensure
|
||||
compatibility of their software.
|
||||
|
||||
## Version Reporting
|
||||
|
||||
Software versions should be reflected in the user interface of the
|
||||
application in three ways:
|
||||
|
||||
* _Version number_: A semantic version (see below) which serves both to
|
||||
uniquely identify releases, as well as to inform plug-in developers
|
||||
about compatibility with previous releases.
|
||||
* _Revision identifier_: While using git, the commit hash. Supports
|
||||
internal developers and testers by uniquely identifying client
|
||||
software snapshots.
|
||||
* _Branding_: Identifies which variant is in use. (Typically, Open MCT
|
||||
is re-branded when deployed for a specific mission or center.)
|
||||
|
||||
## Version Numbering
|
||||
|
||||
Open MCT shall provide version numbers consistent with
|
||||
[Semantic Versioning 2.0.0](http://semver.org/). In summary, versions
|
||||
are expressed in a "major.minor.patch" form, and incremented based on
|
||||
nature of changes to external API. Breaking changes require a "major"
|
||||
version increment; backwards-compatible changes require a "minor"
|
||||
version increment; neutral changes (such as bug fixes) require a "patch"
|
||||
version increment. A hyphen-separated suffix indicates a pre-release
|
||||
version, which may be unstable or may not fully meet compatibility
|
||||
requirements.
|
||||
|
||||
Additionally, the following project-specific standards will be used:
|
||||
|
||||
* During development, a "-SNAPSHOT" suffix shall be appended to the
|
||||
version number. The version number before the suffix shall reflect
|
||||
the next expected version number for release.
|
||||
* Prior to a 1.0.0 release, the _minor_ version will be incremented
|
||||
on a per-release basis; the _patch_ version will be incremented on a
|
||||
per-sprint basis.
|
||||
* Starting at version 1.0.0, version numbers will be updated with each
|
||||
completed sprint. The version number for the sprint shall be
|
||||
determined relative to the previous released version; the decision
|
||||
to increment the _major_, _minor_, or _patch_ version should be
|
||||
made based on the nature of changes during that release. (It is
|
||||
recommended that these numbers are incremented as changes are
|
||||
introduced, such that at end of release the version number may
|
||||
be chosen by simply removing the suffix.)
|
||||
* The first three sprints in a release may be unstable; in these cases, a
|
||||
unique version identifier should still be generated, but a suffix
|
||||
should be included to indicate that the version is not necessarily
|
||||
production-ready. Recommended suffixes are:
|
||||
|
||||
Sprint | Suffix
|
||||
:------:|:--------:
|
||||
1 | `-alpha`
|
||||
2 | `-beta`
|
||||
3 | `-rc`
|
||||
|
||||
### Scope of External API
|
||||
|
||||
"External API" refers to the API exposed to, documented for, and used by
|
||||
plug-in developers. Changes to interfaces used internally by Open MCT
|
||||
(or otherwise not documented for use externally) require only a _patch_
|
||||
version bump.
|
||||
|
||||
## Incrementing Versions
|
||||
|
||||
At the end of a sprint, the [project manager](cycle.md#roles)
|
||||
should update (or delegate the task of updating) Open MCT version
|
||||
numbers by the following process:
|
||||
|
||||
1. Update version number in `package.json`
|
||||
1. Remove `-SNAPSHOT` suffix.
|
||||
2. Verify that resulting version number meets semantic versioning
|
||||
requirements relative to previous stable version. Increment if
|
||||
necessary.
|
||||
3. If version is considered unstable (which may be the case during
|
||||
the first three sprints of a release), apply a new suffix per
|
||||
[Version Numbering](#version-numbering) guidance above.
|
||||
2. Tag the release.
|
||||
1. Commit changes to `package.json` on the `master` branch.
|
||||
The commit message should reference the sprint being closed,
|
||||
preferably by a URL reference to the associated Milestone in
|
||||
GitHub.
|
||||
2. Verify that build still completes, that application passes
|
||||
smoke-testing, and that only differences from tested versions
|
||||
are the changes to version number above.
|
||||
3. Push the `master` branch.
|
||||
4. Tag this commit with the version number, prepending the letter "v".
|
||||
(e.g. `git tag v0.9.3-alpha`)
|
||||
5. Push the tag to GitHub. (e.g. `git push origin v0.9.3-alpha`).
|
||||
3. Upload a release archive.
|
||||
1. Run `npm pack` to generate the archive.
|
||||
2. Use the [GitHub release interface](https://github.com/nasa/openmct/releases)
|
||||
to draft a new release.
|
||||
3. Choose the existing tag for the new version (created and pushed above.)
|
||||
Enter the tag name as the release name as well; see existing releases
|
||||
for examples.
|
||||
4. Attach the release archive.
|
||||
5. Designate the release as a "pre-release" as appropriate (for instance,
|
||||
when the version number has been suffixed as unstable, or when
|
||||
the version number is below 1.0.0.)
|
||||
4. Restore snapshot status in `package.json`
|
||||
1. Remove any suffix from the version number, or increment the
|
||||
_patch_ version if there is no suffix.
|
||||
2. Append a `-SNAPSHOT` suffix.
|
||||
3. Commit changes to `package.json` on the `master` branch.
|
||||
The commit message should reference the sprint being opened,
|
||||
preferably by a URL reference to the associated Milestone in
|
||||
GitHub.
|
||||
4. Verify that build still completes, that application passes
|
||||
smoke-testing.
|
||||
5. Push the `master` branch.
|
||||
|
||||
Projects dependent on Open MCT being co-developed by the Open MCT
|
||||
team should follow a similar process, except that they should
|
||||
additionally update their dependency on Open MCT to point to the
|
||||
latest archive when removing their `-SNAPSHOT` status, and
|
||||
that they should be pointed back to the `master` branch after
|
||||
this has completed.
|
Before Width: | Height: | Size: 23 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 140 KiB |
Before Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 43 KiB |
@ -1,74 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/ExampleController",
|
||||
"./src/ExampleDirective",
|
||||
"./src/ExampleService",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ExampleController,
|
||||
ExampleDirective,
|
||||
ExampleService,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/builtins", {
|
||||
"name": "Angular Built-ins Example",
|
||||
"description": "Example showing how to declare extensions with built-in support from Angular.",
|
||||
"sources": "src",
|
||||
"extensions": {
|
||||
"controllers": [
|
||||
{
|
||||
"key": "ExampleController",
|
||||
"implementation": ExampleController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"exampleService"
|
||||
]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "exampleDirective",
|
||||
"implementation": ExampleDirective,
|
||||
"depends": [
|
||||
"examples[]"
|
||||
]
|
||||
}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"templateUrl": "templates/example.html"
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
{
|
||||
"key": "exampleService",
|
||||
"implementation": ExampleService
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
32
example/builtins/bundle.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "Angular Built-ins Example",
|
||||
"description": "Example showing how to declare extensions with built-in support from Angular.",
|
||||
"sources": "src",
|
||||
"extensions": {
|
||||
"controllers": [
|
||||
{
|
||||
"key": "ExampleController",
|
||||
"implementation": "ExampleController.js",
|
||||
"depends": [ "$scope", "exampleService" ]
|
||||
}
|
||||
],
|
||||
"directives": [
|
||||
{
|
||||
"key": "exampleDirective",
|
||||
"implementation": "ExampleDirective.js",
|
||||
"depends": [ "examples[]" ]
|
||||
}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"templateUrl": "templates/example.html"
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
{
|
||||
"key": "exampleService",
|
||||
"implementation": "ExampleService.js"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,82 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/SomeProvider",
|
||||
"./src/SomeOtherProvider",
|
||||
"./src/SomeDecorator",
|
||||
"./src/SomeOtherDecorator",
|
||||
"./src/SomeAggregator",
|
||||
"./src/SomeOtherExample",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
SomeProvider,
|
||||
SomeOtherProvider,
|
||||
SomeDecorator,
|
||||
SomeOtherDecorator,
|
||||
SomeAggregator,
|
||||
SomeOtherExample,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/composite", {
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": SomeProvider,
|
||||
"provides": "someService",
|
||||
"type": "provider"
|
||||
},
|
||||
{
|
||||
"implementation": SomeOtherProvider,
|
||||
"provides": "someService",
|
||||
"type": "provider"
|
||||
},
|
||||
{
|
||||
"implementation": SomeDecorator,
|
||||
"provides": "someService",
|
||||
"type": "decorator"
|
||||
},
|
||||
{
|
||||
"implementation": SomeOtherDecorator,
|
||||
"provides": "someService",
|
||||
"type": "decorator"
|
||||
},
|
||||
{
|
||||
"implementation": SomeAggregator,
|
||||
"provides": "someService",
|
||||
"type": "aggregator"
|
||||
}
|
||||
],
|
||||
"examples": [
|
||||
{
|
||||
"implementation": SomeOtherExample,
|
||||
"depends": [
|
||||
"someService"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
37
example/composite/bundle.json
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": "SomeProvider.js",
|
||||
"provides": "someService",
|
||||
"type": "provider"
|
||||
},
|
||||
{
|
||||
"implementation": "SomeOtherProvider.js",
|
||||
"provides": "someService",
|
||||
"type": "provider"
|
||||
},
|
||||
{
|
||||
"implementation": "SomeDecorator.js",
|
||||
"provides": "someService",
|
||||
"type": "decorator"
|
||||
},
|
||||
{
|
||||
"implementation": "SomeOtherDecorator.js",
|
||||
"provides": "someService",
|
||||
"type": "decorator"
|
||||
},
|
||||
{
|
||||
"implementation": "SomeAggregator.js",
|
||||
"provides": "someService",
|
||||
"type": "aggregator"
|
||||
}
|
||||
],
|
||||
"examples": [
|
||||
{
|
||||
"implementation": "SomeOtherExample.js",
|
||||
"depends": [ "someService" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,80 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/EventTelemetryProvider",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
EventTelemetryProvider,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/eventGenerator", {
|
||||
"name": "Event Message Generator",
|
||||
"description": "For development use. Creates sample event message data that mimics a live data stream.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": EventTelemetryProvider,
|
||||
"type": "provider",
|
||||
"provides": "telemetryService",
|
||||
"depends": [
|
||||
"$q",
|
||||
"$timeout"
|
||||
]
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "eventGenerator",
|
||||
"name": "Event Message Generator",
|
||||
"glyph": "\u0066",
|
||||
"description": "For development use. Creates sample event message data that mimics a live data stream.",
|
||||
"priority": 10,
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "eventGenerator",
|
||||
"domains": [
|
||||
{
|
||||
"key": "time",
|
||||
"name": "Time",
|
||||
"format": "utc"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
{
|
||||
"key": "message",
|
||||
"name": "Message",
|
||||
"format": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
32
example/eventGenerator/bundle.json
Normal file
@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "Event Message Generator",
|
||||
"description": "Example of a component that produces event data.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": "EventTelemetryProvider.js",
|
||||
"type": "provider",
|
||||
"provides": "telemetryService",
|
||||
"depends": [ "$q", "$timeout" ]
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "eventGenerator",
|
||||
"name": "Event Message Generator",
|
||||
"glyph": "f",
|
||||
"description": "An event message generator",
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "eventGenerator",
|
||||
"ranges": [
|
||||
{ "format": "string" }
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -37,8 +37,7 @@ define(
|
||||
var
|
||||
subscriptions = [],
|
||||
genInterval = 1000,
|
||||
generating = false,
|
||||
id = Math.random() * 100000;
|
||||
startTime = Date.now();
|
||||
|
||||
//
|
||||
function matchesSource(request) {
|
||||
@ -80,13 +79,11 @@ define(
|
||||
}
|
||||
|
||||
function startGenerating() {
|
||||
generating = true;
|
||||
$timeout(function () {
|
||||
//console.log("startGenerating... " + Date.now());
|
||||
handleSubscriptions();
|
||||
if (generating && subscriptions.length > 0) {
|
||||
if (subscriptions.length > 0) {
|
||||
startGenerating();
|
||||
} else {
|
||||
generating = false;
|
||||
}
|
||||
}, genInterval);
|
||||
}
|
||||
@ -96,6 +93,7 @@ define(
|
||||
callback: callback,
|
||||
requests: requests
|
||||
};
|
||||
|
||||
function unsubscribe() {
|
||||
subscriptions = subscriptions.filter(function (s) {
|
||||
return s !== subscription;
|
||||
@ -103,7 +101,8 @@ define(
|
||||
}
|
||||
|
||||
subscriptions.push(subscription);
|
||||
if (!generating) {
|
||||
|
||||
if (subscriptions.length === 1) {
|
||||
startGenerating();
|
||||
}
|
||||
|
||||
|
@ -1,89 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([], function () {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* An example of using the `exportService`; queries for telemetry
|
||||
* and provides the results as a CSV file.
|
||||
* @param {platform/exporters.ExportService} exportService the
|
||||
* service which will handle the CSV export
|
||||
* @param {ActionContext} context the action's context
|
||||
* @constructor
|
||||
* @memberof example/export
|
||||
* @implements {Action}
|
||||
*/
|
||||
function ExportTelemetryAsCSVAction(exportService, context) {
|
||||
this.exportService = exportService;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
ExportTelemetryAsCSVAction.prototype.perform = function () {
|
||||
var context = this.context,
|
||||
domainObject = context.domainObject,
|
||||
telemetry = domainObject.getCapability("telemetry"),
|
||||
metadata = telemetry.getMetadata(),
|
||||
domains = metadata.domains,
|
||||
ranges = metadata.ranges,
|
||||
exportService = this.exportService;
|
||||
|
||||
function getName(domainOrRange) {
|
||||
return domainOrRange.name;
|
||||
}
|
||||
|
||||
telemetry.requestData({}).then(function (series) {
|
||||
var headers = domains.map(getName).concat(ranges.map(getName)),
|
||||
rows = [],
|
||||
row,
|
||||
i;
|
||||
|
||||
function copyDomainsToRow(row, index) {
|
||||
domains.forEach(function (domain) {
|
||||
row[domain.name] = series.getDomainValue(index, domain.key);
|
||||
});
|
||||
}
|
||||
|
||||
function copyRangesToRow(row, index) {
|
||||
ranges.forEach(function (range) {
|
||||
row[range.name] = series.getRangeValue(index, range.key);
|
||||
});
|
||||
}
|
||||
|
||||
for (i = 0; i < series.getPointCount(); i += 1) {
|
||||
row = {};
|
||||
copyDomainsToRow(row, i);
|
||||
copyRangesToRow(row, i);
|
||||
rows.push(row);
|
||||
}
|
||||
exportService.exportCSV(rows, { headers: headers });
|
||||
});
|
||||
};
|
||||
|
||||
ExportTelemetryAsCSVAction.appliesTo = function (context) {
|
||||
return context.domainObject &&
|
||||
context.domainObject.hasCapability("telemetry");
|
||||
};
|
||||
|
||||
return ExportTelemetryAsCSVAction;
|
||||
});
|
@ -1,45 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'legacyRegistry',
|
||||
'./ExportTelemetryAsCSVAction'
|
||||
], function (legacyRegistry, ExportTelemetryAsCSVAction) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/export", {
|
||||
"name": "Example of using CSV Export",
|
||||
"extensions": {
|
||||
"actions": [
|
||||
{
|
||||
"key": "example.export",
|
||||
"name": "Export Telemetry as CSV",
|
||||
"implementation": ExportTelemetryAsCSVAction,
|
||||
"category": "contextual",
|
||||
"glyph": "\u0033",
|
||||
"depends": [ "exportService" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
@ -1,51 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/SomeExample",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
SomeExample,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/extensions", {
|
||||
"name": "Custom Extensions Examples",
|
||||
"description": "Example showing how to declare custom extensions.",
|
||||
"sources": "src",
|
||||
"extensions": {
|
||||
"examples": [
|
||||
{
|
||||
"text": "I came from example/extensions"
|
||||
},
|
||||
{
|
||||
"implementation": SomeExample,
|
||||
"depends": [
|
||||
"exampleService"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
16
example/extensions/bundle.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "Custom Extensions Examples",
|
||||
"description": "Example showing how to declare custom extensions.",
|
||||
"sources": "src",
|
||||
"extensions": {
|
||||
"examples": [
|
||||
{
|
||||
"text": "I came from example/extensions"
|
||||
},
|
||||
{
|
||||
"implementation": "SomeExample.js",
|
||||
"depends": [ "exampleService" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,53 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/ExampleFormController",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ExampleFormController,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/forms", {
|
||||
"name": "Declarative Forms example",
|
||||
"sources": "src",
|
||||
"extensions": {
|
||||
"controllers": [
|
||||
{
|
||||
"key": "ExampleFormController",
|
||||
"implementation": ExampleFormController,
|
||||
"depends": [
|
||||
"$scope"
|
||||
]
|
||||
}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"templateUrl": "templates/exampleForm.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
18
example/forms/bundle.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "Declarative Forms example",
|
||||
"sources": "src",
|
||||
"extensions": {
|
||||
"controllers": [
|
||||
{
|
||||
"key": "ExampleFormController",
|
||||
"implementation": "ExampleFormController.js",
|
||||
"depends": [ "$scope" ]
|
||||
}
|
||||
],
|
||||
"routes": [
|
||||
{
|
||||
"templateUrl": "templates/exampleForm.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,164 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/SinewaveTelemetryProvider",
|
||||
"./src/SinewaveLimitCapability",
|
||||
"./src/SinewaveDeltaFormat",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
SinewaveTelemetryProvider,
|
||||
SinewaveLimitCapability,
|
||||
SinewaveDeltaFormat,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/generator", {
|
||||
"name": "Sine Wave Generator",
|
||||
"description": "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": SinewaveTelemetryProvider,
|
||||
"type": "provider",
|
||||
"provides": "telemetryService",
|
||||
"depends": [
|
||||
"$q",
|
||||
"$timeout"
|
||||
]
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
{
|
||||
"key": "limit",
|
||||
"implementation": SinewaveLimitCapability
|
||||
}
|
||||
],
|
||||
"formats": [
|
||||
{
|
||||
"key": "example.delta",
|
||||
"implementation": SinewaveDeltaFormat
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
{
|
||||
"key": "TIME_CONDUCTOR_DOMAINS",
|
||||
"value": [
|
||||
{
|
||||
"key": "time",
|
||||
"name": "Time"
|
||||
},
|
||||
{
|
||||
"key": "yesterday",
|
||||
"name": "Yesterday"
|
||||
},
|
||||
{
|
||||
"key": "delta",
|
||||
"name": "Delta",
|
||||
"format": "example.delta"
|
||||
}
|
||||
],
|
||||
"priority": -1
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "generator",
|
||||
"name": "Sine Wave Generator",
|
||||
"glyph": "\u0054",
|
||||
"description": "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
|
||||
"priority": 10,
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {
|
||||
"period": 10
|
||||
}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "generator",
|
||||
"domains": [
|
||||
{
|
||||
"key": "time",
|
||||
"name": "Time",
|
||||
"type": "utc"
|
||||
},
|
||||
{
|
||||
"key": "yesterday",
|
||||
"name": "Yesterday",
|
||||
"type": "utc"
|
||||
},
|
||||
{
|
||||
"key": "delta",
|
||||
"name": "Delta",
|
||||
"type": "example.delta"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
{
|
||||
"key": "sin",
|
||||
"name": "Sine",
|
||||
"type": "generic"
|
||||
},
|
||||
{
|
||||
"key": "cos",
|
||||
"name": "Cosine",
|
||||
"type": "generic"
|
||||
},
|
||||
{
|
||||
"key": "positive",
|
||||
"name": "Positive Sine?",
|
||||
"type": "enum",
|
||||
"valueKey": "positive",
|
||||
"enumerations": [
|
||||
{
|
||||
"value": 0,
|
||||
"text": "FALSE"
|
||||
},
|
||||
{
|
||||
"value": 1,
|
||||
"text": "TRUE"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"name": "Period",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-input-sm l-numeric",
|
||||
"key": "period",
|
||||
"required": true,
|
||||
"property": [
|
||||
"telemetry",
|
||||
"period"
|
||||
],
|
||||
"pattern": "^\\d*(\\.\\d*)?$"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
68
example/generator/bundle.json
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "Sine Wave Generator",
|
||||
"description": "Example of a component that produces dataa.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": "SinewaveTelemetryProvider.js",
|
||||
"type": "provider",
|
||||
"provides": "telemetryService",
|
||||
"depends": [ "$q", "$timeout" ]
|
||||
}
|
||||
],
|
||||
"capabilities": [
|
||||
{
|
||||
"key": "limit",
|
||||
"implementation": "SinewaveLimitCapability.js"
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "generator",
|
||||
"name": "Sine Wave Generator",
|
||||
"glyph": "T",
|
||||
"description": "A sine wave generator",
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {
|
||||
"period": 10
|
||||
}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "generator",
|
||||
"domains": [
|
||||
{
|
||||
"key": "time",
|
||||
"name": "Time"
|
||||
},
|
||||
{
|
||||
"key": "yesterday",
|
||||
"name": "Yesterday"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
{
|
||||
"key": "sin",
|
||||
"name": "Sine"
|
||||
},
|
||||
{
|
||||
"key": "cos",
|
||||
"name": "Cosine"
|
||||
}
|
||||
]
|
||||
},
|
||||
"properties": [
|
||||
{
|
||||
"name": "Period",
|
||||
"control": "textfield",
|
||||
"cssclass": "l-small l-numeric",
|
||||
"key": "period",
|
||||
"required": true,
|
||||
"property": [ "telemetry", "period" ],
|
||||
"pattern": "^\\d*(\\.\\d*)?$"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,26 +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.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
|
||||
define({
|
||||
START_TIME: Date.now() - 24 * 60 * 60 * 1000 // Now minus a day.
|
||||
});
|
@ -1,68 +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.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
|
||||
define(
|
||||
['./SinewaveConstants', 'moment'],
|
||||
function (SinewaveConstants, moment) {
|
||||
"use strict";
|
||||
|
||||
var START_TIME = SinewaveConstants.START_TIME,
|
||||
FORMAT_REGEX = /^-?\d+:\d+:\d+$/,
|
||||
SECOND = 1000,
|
||||
MINUTE = SECOND * 60,
|
||||
HOUR = MINUTE * 60;
|
||||
|
||||
function SinewaveDeltaFormat() {
|
||||
}
|
||||
|
||||
function twoDigit(v) {
|
||||
return v >= 10 ? String(v) : ('0' + v);
|
||||
}
|
||||
|
||||
SinewaveDeltaFormat.prototype.format = function (value) {
|
||||
var delta = Math.abs(value - START_TIME),
|
||||
negative = value < START_TIME,
|
||||
seconds = Math.floor(delta / SECOND) % 60,
|
||||
minutes = Math.floor(delta / MINUTE) % 60,
|
||||
hours = Math.floor(delta / HOUR);
|
||||
return (negative ? "-" : "") +
|
||||
[ hours, minutes, seconds ].map(twoDigit).join(":");
|
||||
};
|
||||
|
||||
SinewaveDeltaFormat.prototype.validate = function (text) {
|
||||
return FORMAT_REGEX.test(text);
|
||||
};
|
||||
|
||||
SinewaveDeltaFormat.prototype.parse = function (text) {
|
||||
var negative = text[0] === "-",
|
||||
parts = text.replace("-", "").split(":");
|
||||
return [ HOUR, MINUTE, SECOND ].map(function (sz, i) {
|
||||
return parseInt(parts[i], 10) * sz;
|
||||
}).reduce(function (a, b) {
|
||||
return a + b;
|
||||
}, 0) * (negative ? -1 : 1) + START_TIME;
|
||||
};
|
||||
|
||||
return SinewaveDeltaFormat;
|
||||
}
|
||||
);
|
@ -30,25 +30,25 @@ define(
|
||||
YELLOW = 0.5,
|
||||
LIMITS = {
|
||||
rh: {
|
||||
cssClass: "s-limit-upr s-limit-red",
|
||||
cssClass: "s-limit-upr-red",
|
||||
low: RED,
|
||||
high: Number.POSITIVE_INFINITY,
|
||||
name: "Red High"
|
||||
},
|
||||
rl: {
|
||||
cssClass: "s-limit-lwr s-limit-red",
|
||||
cssClass: "s-limit-lwr-red",
|
||||
high: -RED,
|
||||
low: Number.NEGATIVE_INFINITY,
|
||||
name: "Red Low"
|
||||
},
|
||||
yh: {
|
||||
cssClass: "s-limit-upr s-limit-yellow",
|
||||
cssClass: "s-limit-upr-yellow",
|
||||
low: YELLOW,
|
||||
high: RED,
|
||||
name: "Yellow High"
|
||||
},
|
||||
yl: {
|
||||
cssClass: "s-limit-lwr s-limit-yellow",
|
||||
cssClass: "s-limit-lwr-yellow",
|
||||
low: -RED,
|
||||
high: -YELLOW,
|
||||
name: "Yellow Low"
|
||||
@ -62,9 +62,6 @@ define(
|
||||
},
|
||||
evaluate: function (datum, range) {
|
||||
range = range || 'sin';
|
||||
if (['sin', 'cos'].indexOf(range) === -1) {
|
||||
return '';
|
||||
}
|
||||
if (datum[range] > RED) {
|
||||
return LIMITS.rh;
|
||||
}
|
||||
@ -87,4 +84,4 @@ define(
|
||||
|
||||
return SinewaveLimitCapability;
|
||||
}
|
||||
);
|
||||
);
|
@ -19,11 +19,10 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,setInterval,clearInterval*/
|
||||
/*global define,Promise*/
|
||||
|
||||
/**
|
||||
* Module defining SinewaveTelemetryProvider. Created by vwoeltje on 11/12/14.
|
||||
* Rewritten by larkin on 05/06/2016.
|
||||
*/
|
||||
define(
|
||||
["./SinewaveTelemetrySeries"],
|
||||
@ -35,108 +34,81 @@ define(
|
||||
* @constructor
|
||||
*/
|
||||
function SinewaveTelemetryProvider($q, $timeout) {
|
||||
this.$q = $q;
|
||||
this.$timeout = $timeout;
|
||||
}
|
||||
var subscriptions = [];
|
||||
|
||||
SinewaveTelemetryProvider.prototype.canHandleRequest = function (request) {
|
||||
return request.source === 'generator';
|
||||
};
|
||||
//
|
||||
function matchesSource(request) {
|
||||
return request.source === "generator";
|
||||
}
|
||||
|
||||
SinewaveTelemetryProvider.prototype.requestTelemetry = function (requests) {
|
||||
var sinewaveRequests = requests.filter(this.canHandleRequest, this),
|
||||
response = {
|
||||
generator: {}
|
||||
// Used internally; this will be repacked by doPackage
|
||||
function generateData(request) {
|
||||
return {
|
||||
key: request.key,
|
||||
telemetry: new SinewaveTelemetrySeries(request)
|
||||
};
|
||||
}
|
||||
|
||||
sinewaveRequests.forEach(function (request) {
|
||||
response.generator[request.key] = this.singleRequest(request);
|
||||
}, this);
|
||||
|
||||
return response;
|
||||
};
|
||||
|
||||
SinewaveTelemetryProvider.prototype.subscribe = function (callback, requests) {
|
||||
var sinewaveRequests = requests.filter(this.canHandleRequest, this),
|
||||
unsubscribers = sinewaveRequests.map(function (request) {
|
||||
return this.singleSubscribe(
|
||||
function (series) {
|
||||
var response = {
|
||||
generator: {}
|
||||
};
|
||||
response.generator[request.key] = series;
|
||||
callback(response);
|
||||
},
|
||||
request
|
||||
);
|
||||
}, this);
|
||||
|
||||
return function () {
|
||||
unsubscribers.forEach(function (unsubscribe) {
|
||||
unsubscribe();
|
||||
//
|
||||
function doPackage(results) {
|
||||
var packaged = {};
|
||||
results.forEach(function (result) {
|
||||
packaged[result.key] = result.telemetry;
|
||||
});
|
||||
};
|
||||
};
|
||||
// Format as expected (sources -> keys -> telemetry)
|
||||
return { generator: packaged };
|
||||
}
|
||||
|
||||
SinewaveTelemetryProvider.prototype.singleRequest = function (request) {
|
||||
var start = Math.floor(request.start / 1000) * 1000,
|
||||
end = Math.floor(request.end / 1000) * 1000,
|
||||
period = request.period || 30,
|
||||
data = [],
|
||||
current,
|
||||
i;
|
||||
function requestTelemetry(requests) {
|
||||
return $timeout(function () {
|
||||
return doPackage(requests.filter(matchesSource).map(generateData));
|
||||
}, 0);
|
||||
}
|
||||
|
||||
for (current = start; current <= end; current += 2000) {
|
||||
i = Math.floor((current - start) / 1000);
|
||||
data.push({
|
||||
sin: Math.sin(i * Math.PI * 2 / period),
|
||||
cos: Math.cos(i * Math.PI * 2 / period),
|
||||
positive: Math.sin(i * Math.PI * 2 / period) >= 0,
|
||||
time: current,
|
||||
yesterday: current - (60 * 60 * 24 * 1000),
|
||||
delta: current
|
||||
function handleSubscriptions() {
|
||||
subscriptions.forEach(function (subscription) {
|
||||
var requests = subscription.requests;
|
||||
subscription.callback(doPackage(
|
||||
requests.filter(matchesSource).map(generateData)
|
||||
));
|
||||
});
|
||||
}
|
||||
return new SinewaveTelemetrySeries(data);
|
||||
};
|
||||
|
||||
function startGenerating() {
|
||||
$timeout(function () {
|
||||
handleSubscriptions();
|
||||
if (subscriptions.length > 0) {
|
||||
startGenerating();
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
SinewaveTelemetryProvider.prototype.singleSubscribe = function (callback, options) {
|
||||
// calculate interval position based on start - end; such that this data will line up with data generated by singleRequest.
|
||||
var start = Math.floor((options.start || Date.now()) / 1000) * 1000,
|
||||
currentTime = Math.floor((options.end || Date.now()) / 1000) * 1000,
|
||||
period = options.period || 30,
|
||||
unsubscribe,
|
||||
generatePoint,
|
||||
interval;
|
||||
function subscribe(callback, requests) {
|
||||
var subscription = {
|
||||
callback: callback,
|
||||
requests: requests
|
||||
};
|
||||
|
||||
generatePoint = function () {
|
||||
var i = Math.floor((currentTime - start) / 1000),
|
||||
point = {
|
||||
sin: Math.sin(i * Math.PI * 2 / period),
|
||||
cos: Math.cos(i * Math.PI * 2 / period),
|
||||
positive: Math.sin(i * Math.PI * 2 / period) >= 0,
|
||||
time: currentTime,
|
||||
yesterday: currentTime - (60 * 60 * 24 * 1000),
|
||||
delta: currentTime
|
||||
};
|
||||
currentTime += 1000;
|
||||
return point;
|
||||
function unsubscribe() {
|
||||
subscriptions = subscriptions.filter(function (s) {
|
||||
return s !== subscription;
|
||||
});
|
||||
}
|
||||
|
||||
subscriptions.push(subscription);
|
||||
|
||||
if (subscriptions.length === 1) {
|
||||
startGenerating();
|
||||
}
|
||||
|
||||
return unsubscribe;
|
||||
}
|
||||
|
||||
return {
|
||||
requestTelemetry: requestTelemetry,
|
||||
subscribe: subscribe
|
||||
};
|
||||
|
||||
interval = setInterval(function () {
|
||||
var series = new SinewaveTelemetrySeries(generatePoint());
|
||||
callback(series);
|
||||
}, 1000);
|
||||
|
||||
unsubscribe = function () {
|
||||
clearInterval(interval);
|
||||
};
|
||||
|
||||
return unsubscribe;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
return SinewaveTelemetryProvider;
|
||||
}
|
||||
|
@ -25,44 +25,51 @@
|
||||
* Module defining SinewaveTelemetry. Created by vwoeltje on 11/12/14.
|
||||
*/
|
||||
define(
|
||||
['./SinewaveConstants'],
|
||||
function (SinewaveConstants) {
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
var ONE_DAY = 60 * 60 * 24,
|
||||
firstObservedTime = Math.floor(SinewaveConstants.START_TIME / 1000);
|
||||
firstObservedTime = Math.floor(Date.now() / 1000) - ONE_DAY;
|
||||
|
||||
function SinewaveTelemetrySeries(data) {
|
||||
if (!Array.isArray(data)) {
|
||||
data = [data];
|
||||
/**
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function SinewaveTelemetrySeries(request) {
|
||||
var timeOffset = (request.domain === 'yesterday') ? ONE_DAY : 0,
|
||||
latestTime = Math.floor(Date.now() / 1000) - timeOffset,
|
||||
firstTime = firstObservedTime - timeOffset,
|
||||
endTime = (request.end !== undefined) ?
|
||||
Math.floor(request.end / 1000) : latestTime,
|
||||
count = Math.min(endTime, latestTime) - firstTime,
|
||||
period = +request.period || 30,
|
||||
generatorData = {},
|
||||
requestStart = (request.start === undefined) ? firstTime :
|
||||
Math.max(Math.floor(request.start / 1000), firstTime),
|
||||
offset = requestStart - firstTime;
|
||||
|
||||
if (request.size !== undefined) {
|
||||
offset = Math.max(offset, count - request.size);
|
||||
}
|
||||
this.data = data;
|
||||
|
||||
generatorData.getPointCount = function () {
|
||||
return count - offset;
|
||||
};
|
||||
|
||||
generatorData.getDomainValue = function (i, domain) {
|
||||
return (i + offset) * 1000 + firstTime * 1000 -
|
||||
(domain === 'yesterday' ? ONE_DAY : 0);
|
||||
};
|
||||
|
||||
generatorData.getRangeValue = function (i, range) {
|
||||
range = range || "sin";
|
||||
return Math[range]((i + offset) * Math.PI * 2 / period);
|
||||
};
|
||||
|
||||
return generatorData;
|
||||
}
|
||||
|
||||
SinewaveTelemetrySeries.prototype.getPointCount = function () {
|
||||
return this.data.length;
|
||||
};
|
||||
|
||||
SinewaveTelemetrySeries.prototype.getDomainValue = function (i, domain) {
|
||||
return this.getDatum(i)[domain];
|
||||
};
|
||||
|
||||
SinewaveTelemetrySeries.prototype.getRangeValue = function (i, range) {
|
||||
return this.getDatum(i)[range];
|
||||
};
|
||||
|
||||
SinewaveTelemetrySeries.prototype.getDatum = function (i) {
|
||||
if (i >= this.data.length || i < 0) {
|
||||
throw new Error('IndexOutOfRange: index not available in series.');
|
||||
}
|
||||
return this.data[i];
|
||||
};
|
||||
|
||||
SinewaveTelemetrySeries.prototype.getData = function () {
|
||||
return this.data;
|
||||
};
|
||||
|
||||
return SinewaveTelemetrySeries;
|
||||
|
||||
}
|
||||
);
|
||||
|
@ -1,47 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/ExampleIdentityService",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ExampleIdentityService,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/identity", {
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": ExampleIdentityService,
|
||||
"provides": "identityService",
|
||||
"type": "provider",
|
||||
"depends": [
|
||||
"dialogService"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
12
example/identity/bundle.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": "ExampleIdentityService.js",
|
||||
"provides": "identityService",
|
||||
"type": "provider",
|
||||
"depends": [ "dialogService" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,80 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/ImageTelemetryProvider",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
ImageTelemetryProvider,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/imagery", {
|
||||
"name": "Imagery",
|
||||
"description": "Example of a component that produces image telemetry.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": ImageTelemetryProvider,
|
||||
"type": "provider",
|
||||
"provides": "telemetryService",
|
||||
"depends": [
|
||||
"$q",
|
||||
"$timeout"
|
||||
]
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "imagery",
|
||||
"name": "Example Imagery",
|
||||
"glyph": "\u00e3",
|
||||
"features": "creation",
|
||||
"description": "For development use. Creates example imagery data that mimics a live imagery stream.",
|
||||
"priority": 10,
|
||||
"model": {
|
||||
"telemetry": {}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "imagery",
|
||||
"domains": [
|
||||
{
|
||||
"name": "Time",
|
||||
"key": "time",
|
||||
"format": "utc"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
{
|
||||
"name": "Image",
|
||||
"key": "url",
|
||||
"format": "imageUrl"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
42
example/imagery/bundle.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"name": "Imagery",
|
||||
"description": "Example of a component that produces image telemetry.",
|
||||
"extensions": {
|
||||
"components": [
|
||||
{
|
||||
"implementation": "ImageTelemetryProvider.js",
|
||||
"type": "provider",
|
||||
"provides": "telemetryService",
|
||||
"depends": [ "$q", "$timeout" ]
|
||||
}
|
||||
],
|
||||
"types": [
|
||||
{
|
||||
"key": "imagery",
|
||||
"name": "Example Imagery",
|
||||
"glyph": "T",
|
||||
"features": "creation",
|
||||
"model": {
|
||||
"telemetry": {}
|
||||
},
|
||||
"telemetry": {
|
||||
"source": "imagery",
|
||||
"domains": [
|
||||
{
|
||||
"name": "Time",
|
||||
"key": "time",
|
||||
"format": "timestamp"
|
||||
}
|
||||
],
|
||||
"ranges": [
|
||||
{
|
||||
"name": "Image",
|
||||
"key": "url",
|
||||
"format": "imageUrl"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,45 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/mobile", {
|
||||
"name": "Mobile",
|
||||
"description": "Allows elements with pertinence to mobile usage and development",
|
||||
"extensions": {
|
||||
"stylesheets": [
|
||||
{
|
||||
"stylesheetUrl": "css/mobile-example.css",
|
||||
"priority": "mandatory"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
@ -1,31 +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.
|
||||
*****************************************************************************/
|
||||
@import "../../../../platform/commonUI/general/res/sass/constants";
|
||||
@import "../../../../platform/commonUI/general/res/sass/mobile/constants";
|
||||
@import "../../../../platform/commonUI/general/res/sass/mobile/mixins";
|
||||
|
||||
@include phoneandtablet {
|
||||
// Show the Create button
|
||||
.create-btn-holder {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
To use this bundle, add the following paths to /main.js -
|
||||
'./platform/features/conductor/bundle',
|
||||
'./example/msl/bundle',
|
||||
|
||||
An example plugin that integrates with public data from the Curiosity rover.
|
||||
The data shown used by this plugin is published by the Centro de
|
||||
Astrobiología (CSIC-INTA) at http://cab.inta-csic.es/rems/
|
||||
|
||||
Fetching data from this source requires a cross-origin request which will
|
||||
fail on most modern browsers due to restrictions on such requests. As such,
|
||||
it is proxied through a local proxy defined in app.js. In order to use this
|
||||
example you will need to run app.js locally.
|
||||
|
||||
This example shows integration with an historical telemetry source, as
|
||||
opposed to a real-time data source that is streaming back current information
|
||||
about the state of a system. This example is atypical of a historical data
|
||||
source in that it fetches all data in one request. The server infrastructure
|
||||
of an historical telemetry source should ideally allow queries bounded by
|
||||
time and other data attributes.
|
||||
|
@ -1,118 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/RemsTelemetryServerAdapter",
|
||||
"./src/RemsTelemetryInitializer",
|
||||
"./src/RemsTelemetryModelProvider",
|
||||
"./src/RemsTelemetryProvider",
|
||||
'legacyRegistry',
|
||||
"module"
|
||||
], function (
|
||||
RemsTelemetryServerAdapter,
|
||||
RemsTelemetryInitializer,
|
||||
RemsTelemetryModelProvider,
|
||||
RemsTelemetryProvider,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
legacyRegistry.register("example/notifications", {
|
||||
"name" : "Mars Science Laboratory Data Adapter",
|
||||
"extensions" : {
|
||||
"types": [
|
||||
{
|
||||
"name":"Mars Science Laboratory",
|
||||
"key": "msl.curiosity",
|
||||
"glyph": "o"
|
||||
},
|
||||
{
|
||||
"name": "Instrument",
|
||||
"key": "msl.instrument",
|
||||
"glyph": "o",
|
||||
"model": {"composition": []}
|
||||
},
|
||||
{
|
||||
"name": "Measurement",
|
||||
"key": "msl.measurement",
|
||||
"glyph": "\u0054",
|
||||
"model": {"telemetry": {}},
|
||||
"telemetry": {
|
||||
"source": "rems.source",
|
||||
"domains": [
|
||||
{
|
||||
"name": "Time",
|
||||
"key": "timestamp",
|
||||
"format": "utc"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"constants": [
|
||||
{
|
||||
"key": "REMS_WS_URL",
|
||||
"value": "/proxyUrl?url=http://cab.inta-csic.es/rems/wp-content/plugins/marsweather-widget/api.php"
|
||||
}
|
||||
],
|
||||
"roots": [
|
||||
{
|
||||
"id": "msl:curiosity",
|
||||
"priority" : "preferred",
|
||||
"model": {
|
||||
"type": "msl.curiosity",
|
||||
"name": "Mars Science Laboratory",
|
||||
"composition": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"services": [
|
||||
{
|
||||
"key":"rems.adapter",
|
||||
"implementation": RemsTelemetryServerAdapter,
|
||||
"depends": ["$q", "$http", "$log", "REMS_WS_URL"]
|
||||
}
|
||||
],
|
||||
"runs": [
|
||||
{
|
||||
"implementation": RemsTelemetryInitializer,
|
||||
"depends": ["rems.adapter", "objectService"]
|
||||
}
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"provides": "modelService",
|
||||
"type": "provider",
|
||||
"implementation": RemsTelemetryModelProvider,
|
||||
"depends": ["rems.adapter"]
|
||||
},
|
||||
{
|
||||
"provides": "telemetryService",
|
||||
"type": "provider",
|
||||
"implementation": RemsTelemetryProvider,
|
||||
"depends": ["rems.adapter", "$q"]
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|
||||
|
@ -1,79 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
/**
|
||||
* A data dictionary describes the telemetry available from a data
|
||||
* source and its data types. The data dictionary will be parsed by a custom
|
||||
* server provider for this data source (in this case
|
||||
* {@link RemsTelemetryServerAdapter}).
|
||||
*
|
||||
* Typically a data dictionary would be made available alongside the
|
||||
* telemetry data source itself.
|
||||
*/
|
||||
function () {
|
||||
return {
|
||||
"name": "Mars Science Laboratory",
|
||||
"identifier": "msl",
|
||||
"instruments": [
|
||||
{
|
||||
"name":"rems",
|
||||
"identifier": "rems",
|
||||
"measurements": [
|
||||
{
|
||||
"name": "Min. Air Temperature",
|
||||
"identifier": "min_temp",
|
||||
"units": "degrees",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "Max. Air Temperature",
|
||||
"identifier": "max_temp",
|
||||
"units": "degrees",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "Atmospheric Pressure",
|
||||
"identifier": "pressure",
|
||||
"units": "pascals",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "Min. Ground Temperature",
|
||||
"identifier": "min_gts_temp",
|
||||
"units": "degrees",
|
||||
"type": "float"
|
||||
},
|
||||
{
|
||||
"name": "Max. Ground Temperature",
|
||||
"identifier": "max_gts_temp",
|
||||
"units": "degrees",
|
||||
"type": "float"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
);
|
@ -1,71 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
function (){
|
||||
"use strict";
|
||||
|
||||
var TAXONOMY_ID = "msl:curiosity",
|
||||
PREFIX = "msl_tlm:";
|
||||
|
||||
/**
|
||||
* Function that is executed on application startup and populates
|
||||
* the navigation tree with objects representing the MSL REMS
|
||||
* telemetry points. The tree is populated based on the data
|
||||
* dictionary on the provider.
|
||||
*
|
||||
* @param {RemsTelemetryServerAdapter} adapter The server adapter
|
||||
* (necessary in order to retrieve data dictionary)
|
||||
* @param objectService the ObjectService which allows for lookup of
|
||||
* objects by ID
|
||||
* @constructor
|
||||
*/
|
||||
function RemsTelemetryInitializer(adapter, objectService) {
|
||||
function makeId(element) {
|
||||
return PREFIX + element.identifier;
|
||||
}
|
||||
|
||||
function initializeTaxonomy(dictionary) {
|
||||
function getTaxonomyObject(domainObjects) {
|
||||
return domainObjects[TAXONOMY_ID];
|
||||
}
|
||||
|
||||
function populateModel (taxonomyObject) {
|
||||
return taxonomyObject.useCapability(
|
||||
"mutation",
|
||||
function (model) {
|
||||
model.name = dictionary.name;
|
||||
model.composition = dictionary.instruments.map(makeId);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
objectService.getObjects([TAXONOMY_ID])
|
||||
.then(getTaxonomyObject)
|
||||
.then(populateModel);
|
||||
}
|
||||
initializeTaxonomy(adapter.dictionary);
|
||||
}
|
||||
return RemsTelemetryInitializer;
|
||||
}
|
||||
);
|
@ -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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
function (){
|
||||
"use strict";
|
||||
|
||||
var PREFIX = "msl_tlm:",
|
||||
FORMAT_MAPPINGS = {
|
||||
float: "number",
|
||||
integer: "number",
|
||||
string: "string"
|
||||
};
|
||||
|
||||
function RemsTelemetryModelProvider(adapter){
|
||||
|
||||
function isRelevant(id) {
|
||||
return id.indexOf(PREFIX) === 0;
|
||||
}
|
||||
|
||||
function makeId(element){
|
||||
return PREFIX + element.identifier;
|
||||
}
|
||||
|
||||
function buildTaxonomy(dictionary){
|
||||
var models = {};
|
||||
|
||||
function addMeasurement(measurement){
|
||||
var format = FORMAT_MAPPINGS[measurement.type];
|
||||
models[makeId(measurement)] = {
|
||||
type: "msl.measurement",
|
||||
name: measurement.name,
|
||||
telemetry: {
|
||||
key: measurement.identifier,
|
||||
ranges: [{
|
||||
key: "value",
|
||||
name: measurement.units,
|
||||
units: measurement.units,
|
||||
format: format
|
||||
}]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function addInstrument(subsystem) {
|
||||
var measurements = (subsystem.measurements || []);
|
||||
models[makeId(subsystem)] = {
|
||||
type: "msl.instrument",
|
||||
name: subsystem.name,
|
||||
composition: measurements.map(makeId)
|
||||
};
|
||||
measurements.forEach(addMeasurement);
|
||||
}
|
||||
|
||||
(dictionary.instruments || []).forEach(addInstrument);
|
||||
return models;
|
||||
}
|
||||
|
||||
return {
|
||||
getModels: function (ids) {
|
||||
return ids.some(isRelevant) ? buildTaxonomy(adapter.dictionary) : {};
|
||||
}
|
||||
};
|
||||
}
|
||||
return RemsTelemetryModelProvider;
|
||||
}
|
||||
);
|
@ -1,83 +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.
|
||||
*****************************************************************************/
|
||||
/*global define */
|
||||
define (
|
||||
['./RemsTelemetrySeries'],
|
||||
function (RemsTelemetrySeries) {
|
||||
"use strict";
|
||||
|
||||
var SOURCE = "rems.source";
|
||||
|
||||
function RemsTelemetryProvider(adapter, $q) {
|
||||
this.adapter = adapter;
|
||||
this.$q = $q;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve telemetry from this telemetry source.
|
||||
* @memberOf example/msl
|
||||
* @param {Array<TelemetryRequest>} requests An array of all request
|
||||
* objects (which needs to be filtered to only those relevant to this
|
||||
* source)
|
||||
* @returns {Promise} A {@link Promise} resolved with a {@link RemsTelemetrySeries}
|
||||
* object that wraps the telemetry returned from the telemetry source.
|
||||
*/
|
||||
RemsTelemetryProvider.prototype.requestTelemetry = function (requests) {
|
||||
var packaged = {},
|
||||
relevantReqs,
|
||||
adapter = this.adapter;
|
||||
|
||||
function matchesSource(request) {
|
||||
return (request.source === SOURCE);
|
||||
}
|
||||
|
||||
function addToPackage(history) {
|
||||
packaged[SOURCE][history.id] =
|
||||
new RemsTelemetrySeries(history.values);
|
||||
}
|
||||
|
||||
function handleRequest(request) {
|
||||
return adapter.history(request).then(addToPackage);
|
||||
}
|
||||
|
||||
relevantReqs = requests.filter(matchesSource);
|
||||
packaged[SOURCE] = {};
|
||||
|
||||
return this.$q.all(relevantReqs.map(handleRequest))
|
||||
.then(function () {
|
||||
return packaged;
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* This data source does not support real-time subscriptions
|
||||
*/
|
||||
RemsTelemetryProvider.prototype.subscribe = function (callback, requests) {
|
||||
return function() {};
|
||||
};
|
||||
RemsTelemetryProvider.prototype.unsubscribe = function (callback, requests) {
|
||||
return function() {};
|
||||
};
|
||||
|
||||
return RemsTelemetryProvider;
|
||||
}
|
||||
);
|
@ -1,84 +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.
|
||||
*****************************************************************************/
|
||||
/*global define */
|
||||
define(
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* @typedef {Object} RemsTelemetryValue
|
||||
* @memberOf example/msl
|
||||
* @property {number} date The date/time of the telemetry value. Constitutes the domain value of this value pair
|
||||
* @property {number} value The value of this telemetry datum.
|
||||
* A floating point value representing some observable quantity (eg.
|
||||
* temperature, air pressure, etc.)
|
||||
*/
|
||||
|
||||
/**
|
||||
* A representation of a collection of telemetry data. The REMS
|
||||
* telemetry data is time ordered, with the 'domain' value
|
||||
* constituting the time stamp of each data value and the
|
||||
* 'range' being the value itself.
|
||||
*
|
||||
* TelemetrySeries will typically wrap an array of telemetry data,
|
||||
* and provide an interface for retrieving individual an telemetry
|
||||
* value.
|
||||
* @memberOf example/msl
|
||||
* @param {Array<RemsTelemetryValue>} data An array of telemetry values
|
||||
* @constructor
|
||||
*/
|
||||
function RemsTelemetrySeries(data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number} A count of the number of data values available in
|
||||
* this series
|
||||
*/
|
||||
RemsTelemetrySeries.prototype.getPointCount = function() {
|
||||
return this.data.length;
|
||||
};
|
||||
/**
|
||||
* The domain value at the given index. The Rems telemetry data is
|
||||
* time ordered, so the domain value is the time stamp of each data
|
||||
* value.
|
||||
* @param index
|
||||
* @returns {number} the time value in ms since 1 January 1970
|
||||
*/
|
||||
RemsTelemetrySeries.prototype.getDomainValue = function(index) {
|
||||
return this.data[index].date;
|
||||
};
|
||||
|
||||
/**
|
||||
* The range value of the REMS data set is the value of the thing
|
||||
* being measured, be it temperature, air pressure, etc.
|
||||
* @param index The datum in the data series to return the range
|
||||
* value of.
|
||||
* @returns {number} A floating point number
|
||||
*/
|
||||
RemsTelemetrySeries.prototype.getRangeValue = function(index) {
|
||||
return this.data[index].value;
|
||||
};
|
||||
|
||||
return RemsTelemetrySeries;
|
||||
}
|
||||
);
|
@ -1,142 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
/*jslint es5: true */
|
||||
|
||||
define(
|
||||
[
|
||||
"./MSLDataDictionary",
|
||||
"module"
|
||||
],
|
||||
function (MSLDataDictionary, module) {
|
||||
"use strict";
|
||||
|
||||
var TERRESTRIAL_DATE = "terrestrial_date",
|
||||
LOCAL_DATA = "../data/rems.json";
|
||||
|
||||
/**
|
||||
* Fetches historical data from the REMS instrument on the Curiosity
|
||||
* Rover.
|
||||
* @memberOf example/msl
|
||||
* @param $q
|
||||
* @param $http
|
||||
* @param REMS_WS_URL The location of the REMS telemetry data.
|
||||
* @constructor
|
||||
*/
|
||||
function RemsTelemetryServerAdapter($q, $http, $log, REMS_WS_URL) {
|
||||
this.localDataURI = module.uri.substring(0, module.uri.lastIndexOf('/') + 1) + LOCAL_DATA;
|
||||
this.deferreds = {};
|
||||
this.REMS_WS_URL = REMS_WS_URL;
|
||||
this.$q = $q;
|
||||
this.$http = $http;
|
||||
this.$log = $log;
|
||||
this.cache = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* The data dictionary for this data source.
|
||||
* @type {MSLDataDictionary}
|
||||
*/
|
||||
RemsTelemetryServerAdapter.prototype.dictionary = MSLDataDictionary;
|
||||
|
||||
/**
|
||||
* Fetches historical data from source, and associates it with the
|
||||
* given request ID.
|
||||
* @private
|
||||
*/
|
||||
RemsTelemetryServerAdapter.prototype.requestHistory = function(request) {
|
||||
var self = this,
|
||||
id = request.key,
|
||||
deferred = this.$q.defer();
|
||||
|
||||
function processResponse(response){
|
||||
var data = [];
|
||||
/*
|
||||
* Currently all data is returned for entire history of the mission. Cache response to avoid unnecessary re-queries.
|
||||
*/
|
||||
self.cache = response;
|
||||
/*
|
||||
* History data is organised by Sol. Iterate over sols...
|
||||
*/
|
||||
response.data.soles.forEach(function(solData){
|
||||
/*
|
||||
* Check that valid data exists
|
||||
*/
|
||||
if (!isNaN(solData[id])) {
|
||||
/*
|
||||
* Append each data point to the array of values
|
||||
* for this data point property (min. temp, etc).
|
||||
*/
|
||||
data.unshift({
|
||||
date: Date.parse(solData[TERRESTRIAL_DATE]),
|
||||
value: solData[id]
|
||||
});
|
||||
}
|
||||
});
|
||||
return data;
|
||||
}
|
||||
|
||||
function fallbackToLocal() {
|
||||
self.$log.warn("Loading REMS data failed, probably due to" +
|
||||
" cross origin policy. Falling back to local data");
|
||||
return self.$http.get(self.localDataURI);
|
||||
}
|
||||
|
||||
//Filter results to match request parameters
|
||||
function filterResults(results) {
|
||||
return results.filter(function(result){
|
||||
return result.date >= (request.start || Number.MIN_VALUE) &&
|
||||
result.date <= (request.end || Number.MAX_VALUE);
|
||||
});
|
||||
}
|
||||
|
||||
function packageAndResolve(results){
|
||||
deferred.resolve({id: id, values: results});
|
||||
}
|
||||
|
||||
|
||||
this.$q.when(this.cache || this.$http.get(this.REMS_WS_URL))
|
||||
.catch(fallbackToLocal)
|
||||
.then(processResponse)
|
||||
.then(filterResults)
|
||||
.then(packageAndResolve);
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/**
|
||||
* Requests historical telemetry for the named data attribute. In
|
||||
* the case of REMS, this data source exposes multiple different
|
||||
* data variables from the REMS instrument, including temperature
|
||||
* and others
|
||||
* @param id The telemetry data point key to be queried.
|
||||
* @returns {Promise | Array<RemsTelemetryValue>} that resolves with an Array of {@link RemsTelemetryValue} objects for the request data key.
|
||||
*/
|
||||
RemsTelemetryServerAdapter.prototype.history = function(request) {
|
||||
var id = request.key;
|
||||
return this.requestHistory(request);
|
||||
};
|
||||
|
||||
return RemsTelemetryServerAdapter;
|
||||
}
|
||||
);
|
||||
|
@ -1,86 +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.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/DialogLaunchController",
|
||||
"./src/NotificationLaunchController",
|
||||
"./src/DialogLaunchIndicator",
|
||||
"./src/NotificationLaunchIndicator",
|
||||
'legacyRegistry'
|
||||
], function (
|
||||
DialogLaunchController,
|
||||
NotificationLaunchController,
|
||||
DialogLaunchIndicator,
|
||||
NotificationLaunchIndicator,
|
||||
legacyRegistry
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
legacyRegistry.register("example/notifications", {
|
||||
"extensions": {
|
||||
"templates": [
|
||||
{
|
||||
"key": "dialogLaunchTemplate",
|
||||
"templateUrl": "dialog-launch.html"
|
||||
},
|
||||
{
|
||||
"key": "notificationLaunchTemplate",
|
||||
"templateUrl": "notification-launch.html"
|
||||
}
|
||||
],
|
||||
"controllers": [
|
||||
{
|
||||
"key": "DialogLaunchController",
|
||||
"implementation": DialogLaunchController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"$timeout",
|
||||
"$log",
|
||||
"dialogService",
|
||||
"notificationService"
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "NotificationLaunchController",
|
||||
"implementation": NotificationLaunchController,
|
||||
"depends": [
|
||||
"$scope",
|
||||
"$timeout",
|
||||
"$log",
|
||||
"notificationService"
|
||||
]
|
||||
}
|
||||
],
|
||||
"indicators": [
|
||||
{
|
||||
"implementation": DialogLaunchIndicator,
|
||||
"priority": "fallback"
|
||||
},
|
||||
{
|
||||
"implementation": NotificationLaunchIndicator,
|
||||
"priority": "fallback"
|
||||
}
|
||||
]
|
||||
}
|
||||
});
|
||||
});
|