Compare commits

..

1 Commits

Author SHA1 Message Date
Andrew Henry
92e57c94e0 Updated README for changes introduced in topiccore_refactor 2019-12-10 19:22:59 -08:00
995 changed files with 46077 additions and 54855 deletions

View File

@@ -2,7 +2,7 @@ version: 2
jobs:
build:
docker:
- image: circleci/node:13-browsers
- image: circleci/node:8-browsers
environment:
CHROME_BIN: "/usr/bin/google-chrome"
steps:
@@ -11,20 +11,24 @@ jobs:
name: Update npm
command: 'sudo npm install -g npm@latest'
- restore_cache:
key: dependency-cache-13-{{ checksum "package.json" }}
key: dependency-cache-{{ checksum "package.json" }}-{{ checksum "bower.json" }}
- run:
name: Installing dependencies (npm install)
command: npm install
- save_cache:
key: dependency-cache-13-{{ checksum "package.json" }}
key: dependency-cache-{{ checksum "package.json" }}-{{ checksum "bower.json" }}
paths:
- node_modules
- bower_components
- run:
name: npm run test:coverage
command: npm run test:coverage
name: npm run test
command: npm run test
- run:
name: npm run lint
command: npm run lint
- run:
name: npm run checkstyle
command: npm run checkstyle
- store_artifacts:
path: dist
prefix: dist

View File

@@ -1,179 +0,0 @@
const LEGACY_FILES = ["platform/**", "example/**"];
module.exports = {
"env": {
"browser": true,
"es6": true,
"jasmine": true,
"amd": true
},
"globals": {
"_": "readonly"
},
"extends": [
"eslint:recommended",
"plugin:vue/recommended",
"plugin:you-dont-need-lodash-underscore/compatible"
],
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "babel-eslint",
"allowImportExportEverywhere": true,
"ecmaVersion": 2015,
"ecmaFeatures": {
"impliedStrict": true
}
},
"rules": {
"you-dont-need-lodash-underscore/omit": "off",
"you-dont-need-lodash-underscore/throttle": "off",
"you-dont-need-lodash-underscore/flatten": "off",
"no-bitwise": "error",
"curly": "error",
"eqeqeq": "error",
"guard-for-in": "error",
"no-extend-native": "error",
"no-inner-declarations": "off",
"no-use-before-define": ["error", "nofunc"],
"no-caller": "error",
"no-sequences": "error",
"no-irregular-whitespace": "error",
"no-new": "error",
"no-shadow": "error",
"no-undef": "error",
"no-unused-vars": [
"error",
{
"vars": "all",
"args": "none"
}
],
"no-console": "off",
"no-trailing-spaces": "error",
"space-before-function-paren": [
"error",
{
"anonymous": "always",
"asyncArrow": "always",
"named": "never",
}
],
"array-bracket-spacing": "error",
"space-in-parens": "error",
"space-before-blocks": "error",
"comma-dangle": "error",
"eol-last": "error",
"new-cap": [
"error",
{
"capIsNew": false,
"properties": false
}
],
"dot-notation": "error",
"indent": ["error", 4],
// https://eslint.org/docs/rules/no-case-declarations
"no-case-declarations": "error",
// https://eslint.org/docs/rules/max-classes-per-file
"max-classes-per-file": ["error", 1],
// https://eslint.org/docs/rules/no-eq-null
"no-eq-null": "error",
// https://eslint.org/docs/rules/no-eval
"no-eval": "error",
// https://eslint.org/docs/rules/no-floating-decimal
"no-floating-decimal": "error",
// https://eslint.org/docs/rules/no-implicit-globals
"no-implicit-globals": "error",
// https://eslint.org/docs/rules/no-implied-eval
"no-implied-eval": "error",
// https://eslint.org/docs/rules/no-lone-blocks
"no-lone-blocks": "error",
// https://eslint.org/docs/rules/no-loop-func
"no-loop-func": "error",
// https://eslint.org/docs/rules/no-new-func
"no-new-func": "error",
// https://eslint.org/docs/rules/no-new-wrappers
"no-new-wrappers": "error",
// https://eslint.org/docs/rules/no-octal-escape
"no-octal-escape": "error",
// https://eslint.org/docs/rules/no-proto
"no-proto": "error",
// https://eslint.org/docs/rules/no-return-await
"no-return-await": "error",
// https://eslint.org/docs/rules/no-script-url
"no-script-url": "error",
// https://eslint.org/docs/rules/no-self-compare
"no-self-compare": "error",
// https://eslint.org/docs/rules/no-sequences
"no-sequences": "error",
// https://eslint.org/docs/rules/no-unmodified-loop-condition
"no-unmodified-loop-condition": "error",
// https://eslint.org/docs/rules/no-useless-call
"no-useless-call": "error",
// https://eslint.org/docs/rules/wrap-iife
"wrap-iife": "error",
// https://eslint.org/docs/rules/no-nested-ternary
"no-nested-ternary": "error",
// https://eslint.org/docs/rules/switch-colon-spacing
"switch-colon-spacing": "error",
// https://eslint.org/docs/rules/no-useless-computed-key
"no-useless-computed-key": "error",
// https://eslint.org/docs/rules/rest-spread-spacing
"rest-spread-spacing": ["error"],
"vue/html-indent": [
"error",
4,
{
"attribute": 1,
"baseIndent": 0,
"closeBracket": 0,
"alignAttributesVertically": true,
"ignores": []
}
],
"vue/html-self-closing": ["error",
{
"html": {
"void": "never",
"normal": "never",
"component": "always"
},
"svg": "always",
"math": "always"
}
],
"vue/max-attributes-per-line": ["error", {
"singleline": 1,
"multiline": {
"max": 1,
"allowFirstLine": true
}
}],
"vue/multiline-html-element-content-newline": "off",
"vue/singleline-html-element-content-newline": "off"
},
"overrides": [
{
"files": ["*Spec.js"],
"rules": {
"no-unused-vars": [
"warn",
{
"vars": "all",
"args": "none",
"varsIgnorePattern": "controller",
}
]
}
}, {
"files": LEGACY_FILES,
"rules": {
// https://eslint.org/docs/rules/no-nested-ternary
"no-nested-ternary": "off",
"no-var": "off"
}
}
]
};

3
.gitignore vendored
View File

@@ -37,7 +37,4 @@ protractor/logs
# npm-debug log
npm-debug.log
# karma reports
report.*.json
package-lock.json

5
.jscsrc Normal file
View File

@@ -0,0 +1,5 @@
{
"preset": "crockford",
"requireMultipleVarDecl": false,
"requireVarDeclFirst": false
}

26
.jshintrc Normal file
View File

@@ -0,0 +1,26 @@
{
"bitwise": true,
"browser": true,
"curly": true,
"eqeqeq": true,
"forin": true,
"freeze": true,
"funcscope": false,
"futurehostile": true,
"latedef": true,
"noarg": true,
"nocomma": true,
"nonbsp": true,
"nonew": true,
"predef": [
"define",
"Promise",
"WeakMap",
"Map"
],
"shadow": "outer",
"strict": "implied",
"undef": true,
"unused": "vars",
"latedef": "nofunc"
}

13
API.md
View File

@@ -108,13 +108,15 @@ script loaders are also supported.
<html>
<head>
<title>Open MCT</title>
<script src="dist/openmct.js"></script>
<script src="openmct.js"></script>
</head>
<body>
<script>
openmct.setAssetPath('openmct/dist');
openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.UTCTimeSystem());
openmct.install(openmct.plugins.Espresso());
openmct.start();
</script>
</body>
@@ -125,6 +127,9 @@ The Open MCT library included above requires certain assets such as html
templates, images, and css. If you installed Open MCT from GitHub as described
in the section on [Building from Source](#building-from-source) then these
assets will have been downloaded along with the Open MCT javascript library.
You can specify the location of these assets by calling `openmct.setAssetPath()`.
Typically this will be the same location as the `openmct.js` library is
included from.
There are some plugins bundled with the application that provide UI,
persistence, and other default configuration which are necessary to be able to
@@ -231,7 +236,7 @@ attributes
of this object. This is used for specifying an icon to appear next to each
object of this type.
The [Open MCT Tutorials](https://github.com/nasa/openmct-tutorial) provide a
The [Open MCT Tutorials](https://github.com/openmct/openmct-tutorial) provide a
step-by-step examples of writing code for Open MCT that includes a [section on
defining a new object type](https://github.com/nasa/openmct-tutorial#step-3---providing-objects).
@@ -427,8 +432,8 @@ Each telemetry value description has an object defining hints. Keys in this thi
Known hints:
* `domain`: Values with a `domain` hint will be used for the x-axis of a plot, and tables will render columns for these values first.
* `range`: Values with a `range` hint will be used as the y-axis on a plot, and tables will render columns for these values after the `domain` values.
* `domain`: Indicates that the value represents the "input" of a datum. Values with a `domain` hint will be used for the x-axis of a plot, and tables will render columns for these values first.
* `range`: Indicates that the value is the "output" of a datum. Values with a `range` hint will be used as the y-axis on a plot, and tables will render columns for these values after the `domain` values.
* `image`: Indicates that the value may be interpreted as the URL to an image file, in which case appropriate views will be made available.
##### The Time Conductor and Telemetry

View File

@@ -103,7 +103,7 @@ the name chosen could not be mistaken for a topic or master branch.
### Merging
When development is complete on an issue, the first step toward merging it
back into the master branch is to file a Pull Request (PR). The contributions
back into the master branch is to file a Pull Request. The contributions
should meet code, test, and commit message standards as described below,
and the pull request should include a completed author checklist, also
as described below. Pull requests may be assigned to specific team
@@ -114,15 +114,6 @@ request. When the reviewer is satisfied, they should add a comment to
the pull request containing the reviewer checklist (from below) and complete
the merge back to the master branch.
Additionally:
* Every pull request must link to the issue that it addresses. Eg. “Addresses #1234” or “Closes #1234”. This is the responsibility of the pull requests __author__. If no issue exists, create one.
* Every __author__ must include testing instructions. These instructions should identify the areas of code affected, and some minimal test steps. If addressing a bug, reproduction steps should be included, if they were not included in the original issue. If reproduction steps were included on the original issue, and are sufficient, refer to them.
* A pull request that closes an issue should say so in the description. Including the text “Closes #1234” will cause the linked issue to be automatically closed when the pull request is merged. This is the responsibility of the pull requests __author__.
* When a pull request is merged, and the corresponding issue closed, the __reviewer__ must add the tag “unverified” to the original issue. This will indicate that although the issue is closed, it has not been tested yet.
* Every PR must have two reviewers assigned, though only one approval is necessary for merge.
* Changes to API require approval by a senior developer.
* When creating a PR, it is the author's responsibility to apply any priority label from the issue to the PR as well. This helps with prioritization.
## Standards
Contributions to Open MCT are expected to meet the following standards.
@@ -131,104 +122,97 @@ changes.
### Code Standards
JavaScript sources in Open MCT must satisfy the ESLint rules defined in
this repository. This is verified by the command line build.
JavaScript sources in Open MCT must satisfy JSLint under its default
settings. This is verified by the command line build.
#### Code Guidelines
The following guidelines are provided for anyone contributing source code to the Open MCT project:
JavaScript sources in Open MCT should:
* Use four spaces for indentation. Tabs should not be used.
* Include JSDoc for any exposed API (e.g. public methods, constructors).
* Include non-JSDoc comments as-needed for explaining private variables,
methods, or algorithms when they are non-obvious.
* Define one public class per script, expressed as a constructor function
returned from an AMD-style module.
* Follow “Java-like” naming conventions. These includes:
* Classes should use camel case, first letter capitalized
(e.g. SomeClassName).
* Methods, variables, fields, and function names should use camel case,
first letter lower-case (e.g. someVariableName).
* Constants (variables or fields which are meant to be declared and
initialized statically, and never changed) should use only capital
letters, with underscores between words (e.g. SOME_CONSTANT).
* File names should be the name of the exported class, plus a .js extension
(e.g. SomeClassName.js).
* Avoid anonymous functions, except when functions are short (a few lines)
and/or their inclusion makes sense within the flow of the code
(e.g. as arguments to a forEach call).
* Avoid deep nesting (especially of functions), except where necessary
(e.g. due to closure scope).
* End with a single new-line character.
* Expose public methods by declaring them on the class's prototype.
* Within a given function's scope, do not mix declarations and imperative
code, and present these in the following order:
* First, variable declarations and initialization.
* Second, function declarations.
* Third, imperative statements.
* Finally, the returned value.
1. Write clean code. Heres a good summary - https://github.com/ryanmcdermott/clean-code-javascript.
1. Include JSDoc for any exposed API (e.g. public methods, classes).
1. Include non-JSDoc comments as-needed for explaining private variables,
methods, or algorithms when they are non-obvious. Otherwise code
should be self-documenting.
1. Classes and Vue components should use camel case, first letter capitalized
(e.g. SomeClassName).
1. Methods, variables, fields, events, and function names should use camelCase,
first letter lower-case (e.g. someVariableName).
1. Source files that export functions should use camelCase, first letter lower-case (eg. testTools.js)
1. Constants (variables or fields which are meant to be declared and
initialized statically, and never changed) should use only capital
letters, with underscores between words (e.g. SOME_CONSTANT). They should always be declared as `const`s
1. File names should be the name of the exported class, plus a .js extension
(e.g. SomeClassName.js).
1. Avoid anonymous functions, except when functions are short (one or two lines)
and their inclusion makes sense within the flow of the code
(e.g. as arguments to a forEach call). Anonymous functions should always be arrow functions.
1. Named functions are preferred over functions assigned to variables.
eg.
```JavaScript
function renameObject(object, newName) {
Object.name = newName;
}
```
is preferable to
```JavaScript
const rename = (object, newName) => {
Object.name = newName;
}
```
1. Avoid deep nesting (especially of functions), except where necessary
(e.g. due to closure scope).
1. End with a single new-line character.
1. Always use ES6 `Class`es and inheritence rather than the pre-ES6 prototypal
pattern.
1. Within a given function's scope, do not mix declarations and imperative
code, and present these in the following order:
* First, variable declarations and initialization.
* Secondly, imperative statements.
* Finally, the returned value. A single return statement at the end of the function should be used, except where an early return would improve code clarity.
1. Avoid the use of "magic" values.
eg.
```JavaScript
Const UNAUTHORIZED = 401
if (responseCode === UNAUTHORIZED)
```
is preferable to
```JavaScript
if (responseCode === 401)
```
1. Use the ternary operator only for simple cases such as variable assignment. Nested ternaries should be avoided in all cases.
1. Test specs should reside alongside the source code they test, not in a separate directory.
1. Organize code by feature, not by type.
eg.
```
- telemetryTable
- row
TableRow.js
TableRowCollection.js
TableRow.vue
- column
TableColumn.js
TableColumn.vue
plugin.js
pluginSpec.js
```
is preferable to
```
- telemetryTable
- components
TableRow.vue
TableColumn.vue
- collections
TableRowCollection.js
TableColumn.js
TableRow.js
plugin.js
pluginSpec.js
```
Deviations from Open MCT code style guidelines require two-party agreement,
typically from the author of the change and its reviewer.
#### Code Example
```js
/*global define*/
/**
* Bundles should declare themselves as namespaces in whichever source
* file is most like the "main point of entry" to the bundle.
* @namespace some/bundle
*/
define(
['./OtherClass'],
function (OtherClass) {
"use strict";
/**
* A summary of how to use this class goes here.
*
* @constructor
* @memberof some/bundle
*/
function ExampleClass() {
}
// Methods which are not intended for external use should
// not have JSDoc (or should be marked @private)
ExampleClass.prototype.privateMethod = function () {
};
/**
* A summary of this method goes here.
* @param {number} n a parameter
* @returns {number} a return value
*/
ExampleClass.prototype.publicMethod = function (n) {
return n * 2;
}
return ExampleClass;
}
);
```
### Test Standards
Automated testing shall occur whenever changes are merged into the main
development branch and must be confirmed alongside any pull request.
Automated tests are tests which exercise plugins, API, and utility classes.
Tests are subject to code review along with the actual implementation, to
ensure that tests are applicable and useful.
Automated tests are typically unit 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.
Examples of useful tests:
* Tests which replicate bugs (or their root causes) to verify their
@@ -238,26 +222,8 @@ Examples of useful tests:
* Tests which verify expected interactions with other components in the
system.
#### Guidelines
* 100% statement coverage is achievable and desirable.
* Do blackbox testing. Test external behaviors, not internal details. Write tests that describe what your plugin is supposed to do. How it does this doesn't matter, so don't test it.
* Unit test specs for plugins should be defined at the plugin level. Start with one test spec per plugin named pluginSpec.js, and as this test spec grows too big, break it up into multiple test specs that logically group related tests.
* Unit tests for API or for utility functions and classes may be defined at a per-source file level.
* Wherever possible only use and mock public API, builtin functions, and UI in your test specs. Do not directly invoke any private functions. ie. only call or mock functions and objects exposed by openmct.* (eg. openmct.telemetry, openmct.objectView, etc.), and builtin browser functions (fetch, requestAnimationFrame, setTimeout, etc.).
* Where builtin functions have been mocked, be sure to clear them between tests.
* Test at an appropriate level of isolation. Eg.
* If youre testing a view, you do not need to test the whole application UI, you can just fetch the view provider using the public API and render the view into an element that you have created.
* You do not need to test that the view switcher works, there should be separate tests for that.
* You do not need to test that telemetry providers work, you can mock openmct.telemetry.request() to feed test data to the view.
* Use your best judgement when deciding on appropriate scope.
* Automated tests for plugins should start by actually installing the plugin being tested, and then test that installing the plugin adds the desired features and behavior to Open MCT, observing the above rules.
* All variables used in a test spec, including any instances of the Open MCT API should be declared inside of an appropriate block scope (not at the root level of the source file), and should be initialized in the relevant beforeEach block. `beforeEach` is preferable to `beforeAll` to avoid leaking of state between tests.
* A `afterEach` or `afterAll` should be used to do any clean up necessary to prevent leakage of state between test specs. This can happen when functions on `window` are wrapped, or when the URL is changed. [A convenience function](https://github.com/nasa/openmct/blob/master/src/utils/testing.js#L59) is provided for resetting the URL and clearing builtin spies between tests.
* If writing unit tests for legacy Angular code be sure to follow [best practices in order to avoid memory leaks](https://www.thecodecampus.de/blog/avoid-memory-leaks-angularjs-unit-tests/).
#### Examples
* [Example of an automated test spec for an object view plugin](https://github.com/nasa/openmct/blob/master/src/plugins/telemetryTable/pluginSpec.js)
* [Example of an automated test spec for API](https://github.com/nasa/openmct/blob/master/src/api/time/TimeAPISpec.js)
During automated testing, code coverage metrics will be reported. Line
coverage must remain at or above 80%.
### Commit Message Standards
@@ -326,7 +292,6 @@ checklist).
2. Unit tests included and/or updated with changes?
3. Command line build passes?
4. Changes have been smoke-tested?
5. Testing instructions included?
### Reviewer Checklist
@@ -334,4 +299,3 @@ checklist).
2. Appropriate unit tests included?
3. Code style and in-line documentation are appropriate?
4. Commit messages meet standards?
5. Has associated issue been labelled `unverified`? (only applicable if this PR closes the issue)

View File

@@ -1,6 +1,6 @@
# Open MCT License
Open MCT, Copyright (c) 2014-2020, United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.
Open MCT, Copyright (c) 2014-2019, United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

View File

@@ -28,11 +28,6 @@ Building and running Open MCT in your local dev environment is very easy. Be sur
Open MCT is now running, and can be accessed by pointing a web browser at [http://localhost:8080/](http://localhost:8080/)
## Open MCT v1.0.0
This represents a major overhaul of Open MCT with significant changes under the hood. We aim to maintain backward compatibility but if you do find compatibility issues, please let us know by filing an issue in this repository. If you are having major issues with v1.0.0 please check-out the v0.14.0 tag until we can resolve them for you.
If you are migrating an application built with Open MCT as a dependency to v1.0.0 from an earlier version, please refer to [our migration guide](https://nasa.github.io/openmct/documentation/migration-guide).
## Documentation
Documentation is available on the [Open MCT website](https://nasa.github.io/openmct/documentation/).

130
app.js
View File

@@ -7,72 +7,80 @@
* node app.js [options]
*/
(function () {
"use strict";
const options = require('minimist')(process.argv.slice(2));
const express = require('express');
const app = express();
const fs = require('fs');
const request = require('request');
var BUNDLE_FILE = 'bundles.json',
options = require('minimist')(process.argv.slice(2)),
express = require('express'),
app = express(),
fs = require('fs'),
request = require('request');
// Defaults
options.port = options.port || options.p || 8080;
options.host = options.host || 'localhost';
options.directory = options.directory || options.D || '.';
// Defaults
options.port = options.port || options.p || 8080;
options.host = options.host || 'localhost'
options.directory = options.directory || options.D || '.';
['include', 'exclude', 'i', 'x'].forEach(function (opt) {
options[opt] = options[opt] || [];
// Make sure includes/excludes always end up as arrays
options[opt] = Array.isArray(options[opt]) ?
options[opt] : [options[opt]];
});
options.include = options.include.concat(options.i);
options.exclude = options.exclude.concat(options.x);
// Show command line options
if (options.help || options.h) {
console.log("\nUsage: node app.js [options]\n");
console.log("Options:");
console.log(" --help, -h Show this message.");
console.log(" --port, -p <number> Specify port.");
console.log(" --directory, -D <bundle> Serve files from specified directory.");
console.log("");
process.exit(0);
}
app.disable('x-powered-by');
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);
});
const webpack = require('webpack');
const webpackConfig = require('./webpack.config.js');
webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
webpackConfig.plugins.push(function() { this.plugin('watch-run', function(watching, callback) { console.log('Begin compile at ' + new Date()); callback(); }) });
webpackConfig.entry.openmct = [
'webpack-hot-middleware/client?reload=true',
webpackConfig.entry.openmct
];
const compiler = webpack(webpackConfig);
app.use(require('webpack-dev-middleware')(
compiler,
{
publicPath: '/dist',
logLevel: 'warn'
// Show command line options
if (options.help || options.h) {
console.log("\nUsage: node app.js [options]\n");
console.log("Options:");
console.log(" --help, -h Show this message.");
console.log(" --port, -p <number> Specify port.");
console.log(" --host <host> Specify host to listen on.");
console.log(" --include, -i <bundle> Include the specified bundle.");
console.log(" --exclude, -x <bundle> Exclude the specified bundle.");
console.log(" --directory, -D <bundle> Serve files from specified directory.");
console.log("");
process.exit(0);
}
));
app.use(require('webpack-hot-middleware')(
compiler,
{
app.disable('x-powered-by');
}
));
// Override bundles.json for HTTP requests
app.use('/' + BUNDLE_FILE, function (req, res) {
var bundles;
// Expose index.html for development users.
app.get('/', function (req, res) {
fs.createReadStream('index.html').pipe(res);
});
try {
bundles = JSON.parse(fs.readFileSync(BUNDLE_FILE, 'utf8'));
} catch (e) {
bundles = [];
}
// Finally, open the HTTP server and log the instance to the console
app.listen(options.port, options.host, function() {
console.log('Open MCT application running at %s:%s', options.host, options.port)
});
// Handle command line inclusions/exclusions
bundles = bundles.concat(options.include);
bundles = bundles.filter(function (bundle) {
return options.exclude.indexOf(bundle) === -1;
});
bundles = bundles.filter(function (bundle, index) { // Uniquify
return bundles.indexOf(bundle) === index;
});
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'](options.directory));
// Finally, open the HTTP server and log the instance to the console
app.listen(options.port, options.host, function() {
console.log('Open MCT application running at %s:%s', options.host, options.port)
});
}());

27
bower.json Normal file
View File

@@ -0,0 +1,27 @@
{
"name": "openmct",
"description": "The Open MCT core platform",
"main": "",
"license": "Apache-2.0",
"moduleType": [],
"homepage": "http://nasa.github.io/openmct/",
"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.3.0",
"screenfull": "^3.0.0",
"node-uuid": "^1.4.7",
"comma-separated-values": "^3.6.4",
"file-saver": "1.3.3",
"zepto": "^1.1.6",
"eventemitter3": "^1.2.0",
"lodash": "3.10.1",
"almond": "~0.3.2",
"moment-timezone": "^0.5.13"
}
}

View File

@@ -1,21 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/

View File

@@ -125,22 +125,3 @@ 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.
### Testathons
Testathons can be used as a means of performing per-sprint and per-release testing.
#### Timing
For per-sprint testing, a testathon is typically performed at the beginning of the third week of a sprint, and again later that week to verify any fixes. For per-release testing, a testathon is typically performed prior to any formal testing processes that are applicable to that release.
#### Process
1. Prior to the scheduled testathon, a list will be compiled of all issues that are closed and unverified.
2. For each issue, testers should review the associated PR for testing instructions. See the contributing guide for instructions on [pull requests](https://github.com/nasa/openmct/blob/master/CONTRIBUTING.md#merging).
3. As each issue is verified via testing, any team members testing it should leave a comment on that issue indicating that it has been verified fixed.
4. If a bug is found that relates to an issue being tested, notes should be included on the associated issue, and the issue should be reopened. Bug notes should include reproduction steps.
5. For any bugs that are not obviously related to any of the issues under test, a new issue should be created with details about the bug, including reproduction steps. If unsure about whether a bug relates to an issue being tested, just create a new issue.
6. At the end of the testathon, triage will take place, where all tested issues will be reviewed.
7. If verified fixed, an issue will remain closed, and will have the “unverified” label removed.
8. For any bugs found, a severity will be assigned.
9. A second testathon will be scheduled for later in the week that will aim to address all issues identified as blockers, as well as any other issues scoped by the team during triage.
10. Any issues that were not tested will remain "unverified" and will be picked up in the next testathon.

View File

@@ -0,0 +1,8 @@
This bundle is intended to serve as an example of registering
extensions which are mapped directly to built-in Angular features.
These are:
* Controllers
* Directives
* Routes
* Services

View File

@@ -0,0 +1,74 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*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
}
]
}
});
});

View File

@@ -0,0 +1,24 @@
<!--
Open MCT, Copyright (c) 2014-2017, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<p>Hello, world! I am the default route.</p>
<p ng-controller="ExampleController">My controller has told me: "{{phrase}}"</p>
<span example-directive></span>

View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -19,14 +19,24 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
export default function ladTableCompositionPolicy(openmct) {
return function (parent, child) {
if(parent.type === 'LadTable') {
return openmct.telemetry.isTelemetryObject(child);
} else if(parent.type === 'LadTableSet') {
return child.type === 'LadTable';
/**
* Module defining ExampleController. Created by vwoeltje on 11/4/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function ExampleController($scope, exampleService) {
$scope.phrase = exampleService.getMessage();
}
return true;
return ExampleController;
}
}
);

View File

@@ -0,0 +1,66 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining ExampleDirective. Created by vwoeltje on 11/4/14.
*/
define(
[],
function () {
"use strict";
var HAS_EXTENSIONS = "A directive loaded these message from " +
"example extensions.",
NO_EXTENSIONS = "A directive tried to load example extensions," +
" but found none.",
MESSAGE = "I heard this from my partial constructor.";
/**
*
* @constructor
*/
function ExampleDirective(examples) {
// Build up a template from example extensions
var template = examples.length > 0 ?
HAS_EXTENSIONS : NO_EXTENSIONS;
template += "<ul>";
examples.forEach(function (E) {
template += "<li>";
if (typeof E === 'function') {
template += (new E(MESSAGE)).getText();
} else {
template += E.text;
}
template += "</li>";
});
template += "</ul>";
return {
template: template
};
}
return ExampleDirective;
}
);

View File

@@ -0,0 +1,46 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining ExampleService. Created by vwoeltje on 11/4/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function ExampleService() {
return {
getMessage: function () {
return "I heard this from a service";
}
};
}
return ExampleService;
}
);

View File

@@ -0,0 +1,82 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*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"
]
}
]
}
});
});

View File

@@ -0,0 +1,50 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining SomeAggregator. Created by vwoeltje on 11/5/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function SomeAggregator(someProviders) {
return {
getMessages: function () {
return someProviders.map(function (provider) {
return provider.getMessages();
}).reduce(function (a, b) {
return a.concat(b);
}, []);
}
};
}
return SomeAggregator;
}
);

View File

@@ -0,0 +1,48 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining SomeDecorator. Created by vwoeltje on 11/5/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function SomeDecorator(someProvider) {
return {
getMessages: function () {
return someProvider.getMessages().map(function (msg) {
return msg.toLocaleUpperCase();
});
}
};
}
return SomeDecorator;
}
);

View File

@@ -0,0 +1,48 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining SomeOtherDecorator. Created by vwoeltje on 11/5/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function SomeOtherDecorator(someProvider) {
return {
getMessages: function () {
return someProvider.getMessages().map(function (msg) {
return msg + "...";
});
}
};
}
return SomeOtherDecorator;
}
);

View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -19,19 +19,28 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
define(function () {
return {
name: 'Telemetry Table',
description: 'Display telemetry values for the current time bounds in tabular form. Supports filtering and sorting.',
creatable: true,
cssClass: 'icon-tabular-realtime',
initialize(domainObject) {
domainObject.composition = [];
domainObject.configuration = {
columnWidths: {},
hiddenColumns: {}
/**
* Module defining SomeOtherExample. Created by vwoeltje on 11/5/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function SomeOtherExample(someService) {
return {
getText: function () {
return someService.getMessages().join(" | ");
}
};
}
};
});
return SomeOtherExample;
}
);

View File

@@ -0,0 +1,48 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining SomeOtherProvider. Created by vwoeltje on 11/5/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function SomeOtherProvider() {
return {
getMessages: function () {
return [
"I am a message from some other provider."
];
}
};
}
return SomeOtherProvider;
}
);

View File

@@ -0,0 +1,48 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining SomeProvider. Created by vwoeltje on 11/5/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function SomeProvider() {
return {
getMessages: function () {
return [
"I am a message from some provider."
];
}
};
}
return SomeProvider;
}
);

View File

@@ -22,60 +22,59 @@
/*global define*/
define([
"./src/EventTelemetryProvider"
"./src/EventTelemetryProvider",
'legacyRegistry'
], function (
EventTelemetryProvider
EventTelemetryProvider,
legacyRegistry
) {
"use strict";
return {
name:"example/eventGenerator",
definition: {
"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"
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",
"cssClass": "icon-folder-new",
"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": "utc",
"name": "Timestamp",
"format": "utc"
}
],
"ranges": [
{
"key": "message",
"name": "Message",
"format": "string"
}
]
}
],
"types": [
{
"key": "eventGenerator",
"name": "Event Message Generator",
"cssClass": "icon-generator-events",
"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": "utc",
"name": "Timestamp",
"format": "utc"
}
],
"ranges": [
{
"key": "message",
"name": "Message",
"format": "string"
}
]
}
}
]
}
}
]
}
};
});
});

View File

@@ -22,23 +22,24 @@
/*global define */
/**
* Module defining EventTelemetry.
* Module defining EventTelemetry.
* Created by chacskaylo on 06/18/2015.
* Modified by shale on 06/23/2015.
* Modified by shale on 06/23/2015.
*/
define(
['../data/transcript.json'],
function (messages) {
['text!../data/transcript.json'],
function (transcript) {
"use strict";
var firstObservedTime = Date.now();
var firstObservedTime = Date.now(),
messages = JSON.parse(transcript);
function EventTelemetry(request, interval) {
var latestObservedTime = Date.now(),
count = Math.floor((latestObservedTime - firstObservedTime) / interval),
generatorData = {};
generatorData.getPointCount = function () {
return count;
};
@@ -47,13 +48,13 @@ define(
return i * interval +
(domain !== 'delta' ? firstObservedTime : 0);
};
generatorData.getRangeValue = function (i, range) {
var domainDelta = this.getDomainValue(i) - firstObservedTime,
generatorData.getRangeValue = function (i, range) {
var domainDelta = this.getDomainValue(i) - firstObservedTime,
ind = i % messages.length;
return messages[ind] + " - [" + domainDelta.toString() + "]";
};
};
return generatorData;
}

View File

@@ -34,9 +34,11 @@ define(
* @constructor
*/
function EventTelemetryProvider($q, $timeout) {
var subscriptions = [],
genInterval = 1000,
generating = false;
var
subscriptions = [],
genInterval = 1000,
generating = false,
id = Math.random() * 100000;
//
function matchesSource(request) {
@@ -45,6 +47,7 @@ define(
// Used internally; this will be repacked by doPackage
function generateData(request) {
//console.log("generateData " + (Date.now() - startTime).toString());
return {
key: request.key,
telemetry: new EventTelemetry(request, genInterval)

View File

@@ -58,15 +58,15 @@ define([], function () {
row,
i;
function copyDomainsToRow(telemetryRow, index) {
function copyDomainsToRow(row, index) {
domains.forEach(function (domain) {
telemetryRow[domain.name] = series.getDomainValue(index, domain.key);
row[domain.name] = series.getDomainValue(index, domain.key);
});
}
function copyRangesToRow(telemetryRow, index) {
function copyRangesToRow(row, index) {
ranges.forEach(function (range) {
telemetryRow[range.name] = series.getRangeValue(index, range.key);
row[range.name] = series.getRangeValue(index, range.key);
});
}

View File

@@ -22,26 +22,24 @@
/*global define*/
define([
'legacyRegistry',
'./ExportTelemetryAsCSVAction'
], function (ExportTelemetryAsCSVAction) {
], function (legacyRegistry, ExportTelemetryAsCSVAction) {
"use strict";
return {
name:"example/export",
definition: {
"name": "Example of using CSV Export",
"extensions": {
"actions": [
{
"key": "example.export",
"name": "Export Telemetry as CSV",
"implementation": ExportTelemetryAsCSVAction,
"category": "contextual",
"cssClass": "icon-download",
"depends": ["exportService"]
}
]
}
legacyRegistry.register("example/export", {
"name": "Example of using CSV Export",
"extensions": {
"actions": [
{
"key": "example.export",
"name": "Export Telemetry as CSV",
"implementation": ExportTelemetryAsCSVAction,
"category": "contextual",
"cssClass": "icon-download",
"depends": [ "exportService" ]
}
]
}
};
});
});

View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -19,25 +19,33 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
import Vue from 'vue';
import NotificationIndicator from './components/NotificationIndicator.vue';
/*global define*/
export default function plugin() {
return function install(openmct) {
let component = new Vue ({
provide: {
openmct
},
components: {
NotificationIndicator: NotificationIndicator
},
template: '<NotificationIndicator></NotificationIndicator>'
}),
indicator = {
key: 'notifications-indicator',
element: component.$mount().$el
};
define([
"./src/SomeExample",
'legacyRegistry'
], function (
SomeExample,
legacyRegistry
) {
"use strict";
openmct.indicators.add(indicator);
};
}
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"
]
}
]
}
});
});

View File

@@ -0,0 +1,52 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining SomeExample. Created by vwoeltje on 11/5/14.
*/
define(
[],
function () {
"use strict";
/**
*
* @constructor
*/
function SomeExample(exampleService, message) {
return {
getText: function () {
return [
'"',
exampleService.getMessage(),
'" and "',
message,
'"'
].join("");
}
};
}
return SomeExample;
}
);

View File

@@ -22,33 +22,32 @@
/*global define*/
define([
"./src/ExampleFormController"
"./src/ExampleFormController",
'legacyRegistry'
], function (
ExampleFormController
ExampleFormController,
legacyRegistry
) {
"use strict";
return {
name:"example/forms",
definition: {
"name": "Declarative Forms example",
"sources": "src",
"extensions": {
"controllers": [
{
"key": "ExampleFormController",
"implementation": ExampleFormController,
"depends": [
"$scope"
]
}
],
"routes": [
{
"templateUrl": "templates/exampleForm.html"
}
]
}
legacyRegistry.register("example/forms", {
"name": "Declarative Forms example",
"sources": "src",
"extensions": {
"controllers": [
{
"key": "ExampleFormController",
"implementation": ExampleFormController,
"depends": [
"$scope"
]
}
],
"routes": [
{
"templateUrl": "templates/exampleForm.html"
}
]
}
};
});
});

View File

@@ -9,8 +9,7 @@ define([
values: [
{
key: "name",
name: "Name",
format: "string"
name: "Name"
},
{
key: "utc",
@@ -28,16 +27,6 @@ define([
domain: 2
}
},
// Need to enable "LocalTimeSystem" plugin to make use of this
// {
// key: "local",
// name: "Time",
// format: "local-format",
// source: "utc",
// hints: {
// domain: 3
// }
// },
{
key: "sin",
name: "Sine",
@@ -60,8 +49,7 @@ define([
values: [
{
key: "name",
name: "Name",
format: "string"
name: "Name"
},
{
key: "utc",
@@ -71,15 +59,6 @@ define([
domain: 1
}
},
{
key: "local",
name: "Time",
format: "utc",
source: "utc",
hints: {
domain: 2
}
},
{
key: "state",
source: "value",
@@ -119,11 +98,11 @@ define([
};
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
return Object.assign(
{},
domainObject.telemetry,
METADATA_BY_TYPE[domainObject.type]
);
return _.extend(
{},
domainObject.telemetry,
METADATA_BY_TYPE[domainObject.type]
);
};
return GeneratorMetadataProvider;

View File

@@ -31,7 +31,6 @@ define([
period: 10,
offset: 0,
dataRateInHz: 1,
randomness: 0,
phase: 0
};
@@ -54,7 +53,6 @@ define([
'offset',
'dataRateInHz',
'phase',
'randomness'
];
request = request || {};

View File

@@ -27,35 +27,29 @@ define([
) {
var RED = {
sin: 0.9,
cos: 0.9
},
YELLOW = {
sin: 0.5,
cos: 0.5
},
var RED = 0.9,
YELLOW = 0.5,
LIMITS = {
rh: {
cssClass: "is-limit--upr is-limit--red",
cssClass: "s-limit-upr s-limit-red",
low: RED,
high: Number.POSITIVE_INFINITY,
name: "Red High"
},
rl: {
cssClass: "is-limit--lwr is-limit--red",
cssClass: "s-limit-lwr s-limit-red",
high: -RED,
low: Number.NEGATIVE_INFINITY,
name: "Red Low"
},
yh: {
cssClass: "is-limit--upr is-limit--yellow",
cssClass: "s-limit-upr s-limit-yellow",
low: YELLOW,
high: RED,
name: "Yellow High"
},
yl: {
cssClass: "is-limit--lwr is-limit--yellow",
cssClass: "s-limit-lwr s-limit-yellow",
low: -RED,
high: -YELLOW,
name: "Yellow Low"
@@ -73,18 +67,17 @@ define([
SinewaveLimitProvider.prototype.getLimitEvaluator = function (domainObject) {
return {
evaluate: function (datum, valueMetadata) {
var range = valueMetadata && valueMetadata.key;
if (datum[range] > RED[range]) {
var range = valueMetadata ? valueMetadata.key : 'sin'
if (datum[range] > RED) {
return LIMITS.rh;
}
if (datum[range] < -RED[range]) {
if (datum[range] < -RED) {
return LIMITS.rl;
}
if (datum[range] > YELLOW[range]) {
if (datum[range] > YELLOW) {
return LIMITS.yh;
}
if (datum[range] < -YELLOW[range]) {
if (datum[range] < -YELLOW) {
return LIMITS.yl;
}
}

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
define([
'raw-loader!./generatorWorker.js',
'text!./generatorWorker.js',
'uuid'
], function (
workerText,
@@ -89,7 +89,7 @@ define([
WorkerInterface.prototype.subscribe = function (request, cb) {
function callback(message) {
cb(message.data);
}
};
var messageId = this.dispatch('subscribe', request, callback);

View File

@@ -65,8 +65,8 @@
name: data.name,
utc: nextStep,
yesterday: nextStep - 60*60*24*1000,
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness),
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness)
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase),
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase)
}
});
nextStep += step;
@@ -84,10 +84,10 @@
function onRequest(message) {
var request = message.data;
if (request.end === undefined) {
if (request.end == undefined) {
request.end = Date.now();
}
if (request.start === undefined) {
if (request.start == undefined){
request.start = request.end - FIFTEEN_MINUTES;
}
@@ -99,7 +99,6 @@
var offset = request.offset;
var dataRateInHz = request.dataRateInHz;
var phase = request.phase;
var randomness = request.randomness;
var step = 1000 / dataRateInHz;
var nextStep = start - (start % step) + step;
@@ -111,8 +110,8 @@
name: request.name,
utc: nextStep,
yesterday: nextStep - 60*60*24*1000,
sin: sin(nextStep, period, amplitude, offset, phase, randomness),
cos: cos(nextStep, period, amplitude, offset, phase, randomness)
sin: sin(nextStep, period, amplitude, offset, phase),
cos: cos(nextStep, period, amplitude, offset, phase)
});
}
self.postMessage({
@@ -121,14 +120,14 @@
});
}
function cos(timestamp, period, amplitude, offset, phase, randomness) {
function cos(timestamp, period, amplitude, offset, phase) {
return amplitude *
Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + offset;
}
function sin(timestamp, period, amplitude, offset, phase, randomness) {
function sin(timestamp, period, amplitude, offset, phase) {
return amplitude *
Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + offset;
}
function sendError(error, message) {

View File

@@ -33,24 +33,25 @@ define([
GeneratorMetadataProvider
) {
return function (openmct) {
return function(openmct){
openmct.types.addType("example.state-generator", {
name: "State Generator",
description: "For development use. Generates test enumerated telemetry by cycling through a given set of states",
cssClass: "icon-generator-telemetry",
cssClass: "icon-telemetry",
creatable: true,
form: [
{
name: "State Duration (seconds)",
control: "numberfield",
control: "textfield",
cssClass: "l-input-sm l-numeric",
key: "duration",
required: true,
property: [
"telemetry",
"duration"
]
],
pattern: "^\\d*(\\.\\d*)?$"
}
],
initialize: function (object) {
@@ -65,7 +66,7 @@ define([
openmct.types.addType("generator", {
name: "Sine Wave Generator",
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
cssClass: "icon-generator-telemetry",
cssClass: "icon-telemetry",
creatable: true,
form: [
{
@@ -122,17 +123,6 @@ define([
"telemetry",
"phase"
]
},
{
name: "Randomness",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "randomness",
required: true,
property: [
"telemetry",
"randomness"
]
}
],
initialize: function (object) {
@@ -141,8 +131,7 @@ define([
amplitude: 1,
offset: 0,
dataRateInHz: 1,
phase: 0,
randomness: 0
phase: 0
};
}
});

View File

@@ -22,28 +22,27 @@
/*global define*/
define([
"./src/ExampleIdentityService"
"./src/ExampleIdentityService",
'legacyRegistry'
], function (
ExampleIdentityService
ExampleIdentityService,
legacyRegistry
) {
"use strict";
return {
name:"example/identity",
definition: {
"extensions": {
"components": [
{
"implementation": ExampleIdentityService,
"provides": "identityService",
"type": "provider",
"depends": [
"dialogService",
"$q"
]
}
]
}
legacyRegistry.register("example/identity", {
"extensions": {
"components": [
{
"implementation": ExampleIdentityService,
"provides": "identityService",
"type": "provider",
"depends": [
"dialogService",
"$q"
]
}
]
}
};
});
});

View File

@@ -22,37 +22,36 @@
define([
], function (
], function(
) {
function ImageryPlugin() {
var IMAGE_SAMPLES = [
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18731.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18732.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18733.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18734.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18735.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18736.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18737.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18738.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18739.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18740.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18741.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18742.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18743.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18744.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18745.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18746.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18747.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18748.jpg"
];
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18731.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18732.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18733.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18734.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18735.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18736.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18737.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18738.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18739.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18740.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18741.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18742.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18743.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18744.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18745.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18746.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18747.jpg",
"https://www.hq.nasa.gov/alsj/a16/AS16-117-18748.jpg"
];
function pointForTimestamp(timestamp, name) {
return {
name: name,
utc: Math.floor(timestamp / 5000) * 5000,
local: Math.floor(timestamp / 5000) * 5000,
url: IMAGE_SAMPLES[Math.floor(timestamp / 5000) % IMAGE_SAMPLES.length]
};
}
@@ -66,7 +65,7 @@ define([
callback(pointForTimestamp(Date.now(), domainObject.name));
}, 5000);
return function () {
return function (interval) {
clearInterval(interval);
};
}
@@ -79,7 +78,7 @@ define([
},
request: function (domainObject, options) {
var start = options.start;
var end = Math.min(options.end, Date.now());
var end = options.end;
var data = [];
while (start <= end && data.length < 5000) {
data.push(pointForTimestamp(start, domainObject.name));
@@ -119,14 +118,6 @@ define([
name: 'Time',
key: 'utc',
format: 'utc',
hints: {
domain: 2
}
},
{
name: 'Local Time',
key: 'local',
format: 'local-format',
hints: {
domain: 1
}

View File

@@ -21,22 +21,25 @@
*****************************************************************************/
/*global define*/
define([], function () {
define([
'legacyRegistry'
], function (
legacyRegistry
) {
"use strict";
return {
name:"example/mobile",
definition: {
"name": "Mobile",
"description": "Allows elements with pertinence to mobile usage and development",
"extensions": {
"stylesheets": [
{
"stylesheetUrl": "css/mobile-example.css",
"priority": "mandatory"
}
]
}
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"
}
]
}
};
});
});

View File

@@ -24,92 +24,92 @@
define([
"./src/RemsTelemetryServerAdapter",
"./src/RemsTelemetryModelProvider",
"./src/RemsTelemetryProvider"
"./src/RemsTelemetryProvider",
'legacyRegistry',
"module"
], function (
RemsTelemetryServerAdapter,
RemsTelemetryModelProvider,
RemsTelemetryProvider
RemsTelemetryProvider,
legacyRegistry
) {
"use strict";
return {
name:"example/msl",
definition: {
"name" : "Mars Science Laboratory Data Adapter",
"extensions" : {
"types": [
{
"name":"Mars Science Laboratory",
"key": "msl.curiosity",
"cssClass": "icon-object"
},
{
"name": "Instrument",
"key": "msl.instrument",
"cssClass": "icon-object",
"model": {"composition": []}
},
{
"name": "Measurement",
"key": "msl.measurement",
"cssClass": "icon-telemetry",
"model": {"telemetry": {}},
"telemetry": {
"source": "rems.source",
"domains": [
{
"name": "Time",
"key": "utc",
"format": "utc"
}
]
}
legacyRegistry.register("example/msl", {
"name" : "Mars Science Laboratory Data Adapter",
"extensions" : {
"types": [
{
"name":"Mars Science Laboratory",
"key": "msl.curiosity",
"cssClass": "icon-object"
},
{
"name": "Instrument",
"key": "msl.instrument",
"cssClass": "icon-object",
"model": {"composition": []}
},
{
"name": "Measurement",
"key": "msl.measurement",
"cssClass": "icon-telemetry",
"model": {"telemetry": {}},
"telemetry": {
"source": "rems.source",
"domains": [
{
"name": "Time",
"key": "utc",
"format": "utc"
}
]
}
],
"constants": [
{
"key": "REMS_WS_URL",
"value": "/proxyUrl?url=http://cab.inta-csic.es/rems/wp-content/plugins/marsweather-widget/api.php"
}
],
"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"
}
],
"models": [
{
"id": "msl:curiosity",
"priority": "preferred",
"model": {
"type": "msl.curiosity",
"name": "Mars Science Laboratory",
"composition": ["msl_tlm:rems"]
}
],
"roots": [
{
"id": "msl:curiosity"
}
],
"models": [
{
"id": "msl:curiosity",
"priority": "preferred",
"model": {
"type": "msl.curiosity",
"name": "Mars Science Laboratory",
"composition": ["msl_tlm:rems"]
}
}
],
"services": [
{
"key":"rems.adapter",
"implementation": RemsTelemetryServerAdapter,
"depends": ["$http", "$log", "REMS_WS_URL"]
}
],
"components": [
{
"provides": "modelService",
"type": "provider",
"implementation": RemsTelemetryModelProvider,
"depends": ["rems.adapter"]
},
{
"provides": "telemetryService",
"type": "provider",
"implementation": RemsTelemetryProvider,
"depends": ["rems.adapter", "$q"]
}
]
}
}
],
"services": [
{
"key":"rems.adapter",
"implementation": RemsTelemetryServerAdapter,
"depends": ["$http", "$log", "REMS_WS_URL"]
}
],
"components": [
{
"provides": "modelService",
"type": "provider",
"implementation": RemsTelemetryModelProvider,
"depends": ["rems.adapter"]
},
{
"provides": "telemetryService",
"type": "provider",
"implementation": RemsTelemetryProvider,
"depends": ["rems.adapter", "$q"]
}
]
}
};
});
});

View File

@@ -76,4 +76,4 @@ define(
]
};
}
);
);

View File

@@ -22,7 +22,7 @@
/*global define*/
define(
function () {
function (){
"use strict";
var PREFIX = "msl_tlm:",
@@ -32,20 +32,20 @@ define(
string: "string"
};
function RemsTelemetryModelProvider(adapter) {
function RemsTelemetryModelProvider(adapter){
function isRelevant(id) {
return id.indexOf(PREFIX) === 0;
}
function makeId(element) {
function makeId(element){
return PREFIX + element.identifier;
}
function buildTaxonomy(dictionary) {
function buildTaxonomy(dictionary){
var models = {};
function addMeasurement(measurement, parent) {
function addMeasurement(measurement, parent){
var format = FORMAT_MAPPINGS[measurement.type];
models[makeId(measurement)] = {
type: "msl.measurement",
@@ -73,12 +73,12 @@ define(
location: spacecraftId,
composition: measurements.map(makeId)
};
measurements.forEach(function (measurement) {
measurements.forEach(function(measurement) {
addMeasurement(measurement, instrumentId);
});
}
(dictionary.instruments || []).forEach(function (instrument) {
(dictionary.instruments || []).forEach(function(instrument) {
addInstrument(instrument, "msl:curiosity");
});
return models;

View File

@@ -72,10 +72,10 @@ define (
* This data source does not support real-time subscriptions
*/
RemsTelemetryProvider.prototype.subscribe = function (callback, requests) {
return function () {};
return function() {};
};
RemsTelemetryProvider.prototype.unsubscribe = function (callback, requests) {
return function () {};
return function() {};
};
return RemsTelemetryProvider;

View File

@@ -54,8 +54,8 @@ define(
* @returns {number} A count of the number of data values available in
* this series
*/
RemsTelemetrySeries.prototype.getPointCount = function () {
return this.data.length;
RemsTelemetrySeries.prototype.getPointCount = function() {
return this.data.length;
};
/**
* The domain value at the given index. The Rems telemetry data is
@@ -64,8 +64,8 @@ define(
* @param index
* @returns {number} the time value in ms since 1 January 1970
*/
RemsTelemetrySeries.prototype.getDomainValue = function (index) {
return this.data[index].date;
RemsTelemetrySeries.prototype.getDomainValue = function(index) {
return this.data[index].date;
};
/**
@@ -75,8 +75,8 @@ define(
* value of.
* @returns {number} A floating point number
*/
RemsTelemetrySeries.prototype.getRangeValue = function (index) {
return this.data[index].value;
RemsTelemetrySeries.prototype.getRangeValue = function(index) {
return this.data[index].value;
};
return RemsTelemetrySeries;

View File

@@ -68,18 +68,18 @@ define(
* given request ID.
* @private
*/
RemsTelemetryServerAdapter.prototype.requestHistory = function (request) {
RemsTelemetryServerAdapter.prototype.requestHistory = function(request) {
var self = this,
id = request.key;
var dataTransforms = this.dataTransforms;
function processResponse(response) {
function processResponse(response){
var data = [];
/*
* History data is organised by Sol. Iterate over sols...
*/
response.data.soles.forEach(function (solData) {
response.data.soles.forEach(function(solData){
/*
* Check that valid data exists
*/
@@ -106,13 +106,13 @@ define(
//Filter results to match request parameters
function filterResults(results) {
return results.filter(function (result) {
return results.filter(function(result){
return result.date >= (request.start || Number.MIN_VALUE) &&
result.date <= (request.end || Number.MAX_VALUE);
});
}
function packageAndResolve(results) {
function packageAndResolve(results){
return {id: id, values: results};
}
@@ -132,7 +132,7 @@ define(
* @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) {
RemsTelemetryServerAdapter.prototype.history = function(request) {
return this.requestHistory(request);
};

View File

@@ -26,66 +26,61 @@ define([
"./src/NotificationLaunchController",
"./src/DialogLaunchIndicator",
"./src/NotificationLaunchIndicator",
"./res/dialog-launch.html",
"./res/notification-launch.html"
'legacyRegistry'
], function (
DialogLaunchController,
NotificationLaunchController,
DialogLaunchIndicator,
NotificationLaunchIndicator,
DialogLaunch,
NotificationLaunch
legacyRegistry
) {
"use strict";
return {
name:"example/notifications",
definition: {
"extensions": {
"templates": [
{
"key": "dialogLaunchTemplate",
"template": DialogLaunch
},
{
"key": "notificationLaunchTemplate",
"template": NotificationLaunch
}
],
"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"
}
]
}
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"
}
]
}
};
});
});

View File

@@ -1,9 +1,9 @@
<span class="h-indicator" ng-controller="DialogLaunchController">
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
<div class="c-indicator c-indicator--clickable icon-box-with-arrow s-status-available"><span class="label c-indicator__label">
<button ng-click="launchProgress(true)">Known</button>
<button ng-click="launchProgress(false)">Unknown</button>
<button ng-click="launchError()">Error</button>
<button ng-click="launchInfo()">Info</button>
<div class="ls-indicator icon-box-with-arrow s-status-available"><span class="label">
<a ng-click="launchProgress(true)">Known</a>
<a ng-click="launchProgress(false)">Unknown</a>
<a ng-click="launchError()">Error</a>
<a ng-click="launchInfo()">Info</a>
</span></div>
</span>

View File

@@ -1,9 +1,9 @@
<span class="h-indicator" ng-controller="NotificationLaunchController">
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
<div class="c-indicator c-indicator--clickable icon-bell s-status-available"><span class="label c-indicator__label">
<button ng-click="newInfo()">Success</button>
<button ng-click="newError()">Error</button>
<button ng-click="newAlert()">Alert</button>
<button ng-click="newProgress()">Progress</button>
<div class="ls-indicator icon-bell s-status-available"><span class="label">
<a ng-click="newInfo()">Success</a>
<a ng-click="newError()">Error</a>
<a ng-click="newAlert()">Alert</a>
<a ng-click="newProgress()">Progress</a>
</span></div>
</span>

View File

@@ -137,12 +137,12 @@ define(
" attention to an event.",
severity: "info",
primaryOption: {
label: "OK",
callback: function () {
$log.debug("OK Pressed");
dialog.dismiss();
label: "OK",
callback: function () {
$log.debug("OK Pressed");
dialog.dismiss();
}
}
}
};
dialog = dialogService.showBlockingMessage(model);

View File

@@ -51,26 +51,76 @@ define(
return actionTexts[Math.floor(Math.random()*3)];
}
function getExampleActions() {
var actions = [
{
label: "Try Again",
callback: function () {
$log.debug("Try Again pressed");
}
},
{
label: "Remove",
callback: function () {
$log.debug("Remove pressed");
}
},
{
label: "Cancel",
callback: function () {
$log.debug("Cancel pressed");
}
}
];
// Randomly remove some actions off the top; leave at least one
actions.splice(0,Math.floor(Math.random() * actions.length));
return actions;
}
function getExampleSeverity() {
var severities = [
"info",
"alert",
"error"
];
return severities[Math.floor(Math.random() * severities.length)];
}
/**
* Launch a new notification with a severity level of 'Error'.
*/
$scope.newError = function () {
$scope.newError = function(){
notificationService.notify({
title: "Example error notification " + messageCounter++,
hint: "An error has occurred",
severity: "error"
});
severity: "error",
primaryOption: {
label: 'Retry',
callback: function() {
$log.info('Retry clicked');
}
},
options: getExampleActions()});
};
/**
* Launch a new notification with a severity of 'Alert'.
*/
$scope.newAlert = function () {
$scope.newAlert = function(){
notificationService.notify({
title: "Alert notification " + (messageCounter++),
hint: "This is an alert message",
severity: "alert",
autoDismiss: true
});
primaryOption: {
label: 'Retry',
callback: function() {
$log.info('Retry clicked');
}
},
options: getExampleActions()});
};
@@ -78,42 +128,39 @@ define(
* Launch a new notification with a progress bar that is updated
* periodically, tracking an ongoing process.
*/
$scope.newProgress = function () {
let progress = 0;
$scope.newProgress = function(){
var notificationModel = {
title: "Progress notification example",
severity: "info",
progress: progress,
actionText: getExampleActionText()
progress: 0,
actionText: getExampleActionText(),
unknownProgress: false
};
let notification;
/**
* Simulate an ongoing process and update the progress bar.
* @param notification
*/
function incrementProgress() {
progress = Math.min(100, Math.floor(progress + Math.random() * 30))
let progressText = ["Estimated time" +
function incrementProgress(notificationModel) {
notificationModel.progress = Math.min(100, Math.floor(notificationModel.progress + Math.random() * 30));
notificationModel.progressText = ["Estimated time" +
" remaining:" +
" about ", 60 - Math.floor((progress / 100) * 60), " seconds"].join(" ");
notification.progress(progress, progressText);
if (progress < 100) {
$timeout(function () {
incrementProgress(notificationModel);
}, 1000);
" about ", 60 - Math.floor((notificationModel.progress / 100) * 60), " seconds"].join(" ");
if (notificationModel.progress < 100) {
$timeout(function(){incrementProgress(notificationModel);}, 1000);
}
}
notification = notificationService.notify(notificationModel);
incrementProgress();
notificationService.notify(notificationModel);
incrementProgress(notificationModel);
};
/**
* Launch a new notification with severity level of INFO.
*/
$scope.newInfo = function () {
$scope.newInfo = function(){
notificationService.info({
title: "Example Info notification " + messageCounter++
});

View File

@@ -22,34 +22,33 @@
/*global define*/
define([
"./src/BrowserPersistenceProvider"
"./src/BrowserPersistenceProvider",
'legacyRegistry'
], function (
BrowserPersistenceProvider
BrowserPersistenceProvider,
legacyRegistry
) {
"use strict";
return {
name:"example/persistence",
definition: {
"extensions": {
"components": [
{
"provides": "persistenceService",
"type": "provider",
"implementation": BrowserPersistenceProvider,
"depends": [
"$q",
"PERSISTENCE_SPACE"
]
}
],
"constants": [
{
"key": "PERSISTENCE_SPACE",
"value": "mct"
}
]
}
legacyRegistry.register("example/persistence", {
"extensions": {
"components": [
{
"provides": "persistenceService",
"type": "provider",
"implementation": BrowserPersistenceProvider,
"depends": [
"$q",
"PERSISTENCE_SPACE"
]
}
],
"constants": [
{
"key": "PERSISTENCE_SPACE",
"value": "mct"
}
]
}
};
});
});

View File

@@ -22,25 +22,24 @@
/*global define*/
define([
"./src/ExamplePolicy"
"./src/ExamplePolicy",
'legacyRegistry'
], function (
ExamplePolicy
ExamplePolicy,
legacyRegistry
) {
"use strict";
return {
name:"example/policy",
definition: {
"name": "Example Policy",
"description": "Provides an example of using policies to prohibit actions.",
"extensions": {
"policies": [
{
"implementation": ExamplePolicy,
"category": "action"
}
]
}
legacyRegistry.register("example/policy", {
"name": "Example Policy",
"description": "Provides an example of using policies to prohibit actions.",
"extensions": {
"policies": [
{
"implementation": ExamplePolicy,
"category": "action"
}
]
}
};
});
});

View File

@@ -23,34 +23,33 @@
define([
"./src/WatchIndicator",
"./src/DigestIndicator"
"./src/DigestIndicator",
'legacyRegistry'
], function (
WatchIndicator,
DigestIndicator
DigestIndicator,
legacyRegistry
) {
"use strict";
return {
name:"example/profiling",
definition: {
"extensions": {
"indicators": [
{
"implementation": WatchIndicator,
"depends": [
"$interval",
"$rootScope"
]
},
{
"implementation": DigestIndicator,
"depends": [
"$interval",
"$rootScope"
]
}
]
}
legacyRegistry.register("example/profiling", {
"extensions": {
"indicators": [
{
"implementation": WatchIndicator,
"depends": [
"$interval",
"$rootScope"
]
},
{
"implementation": DigestIndicator,
"depends": [
"$interval",
"$rootScope"
]
}
]
}
};
});
});

View File

@@ -22,43 +22,42 @@
/*global define*/
define([
"./src/ScratchPersistenceProvider"
"./src/ScratchPersistenceProvider",
'legacyRegistry'
], function (
ScratchPersistenceProvider
ScratchPersistenceProvider,
legacyRegistry
) {
"use strict";
return {
name:"example/scratchpad",
definition: {
"extensions": {
"roots": [
{
"id": "scratch:root"
}
],
"models": [
{
"id": "scratch:root",
"model": {
"type": "folder",
"composition": [],
"name": "Scratchpad"
},
"priority": "preferred"
}
],
"components": [
{
"provides": "persistenceService",
"type": "provider",
"implementation": ScratchPersistenceProvider,
"depends": [
"$q"
]
}
]
}
legacyRegistry.register("example/scratchpad", {
"extensions": {
"roots": [
{
"id": "scratch:root"
}
],
"models": [
{
"id": "scratch:root",
"model": {
"type": "folder",
"composition": [],
"name": "Scratchpad"
},
"priority": "preferred"
}
],
"components": [
{
"provides": "persistenceService",
"type": "provider",
"implementation": ScratchPersistenceProvider,
"depends": [
"$q"
]
}
]
}
};
});
});

View File

@@ -60,7 +60,7 @@ define(
ScratchPersistenceProvider.prototype.readObject = function (space, key) {
return this.$q.when(
(space === 'scratch' && this.table[key]) ?
JSON.parse(this.table[key]) : undefined
JSON.parse(this.table[key]) : undefined
);
};

View File

@@ -1,19 +0,0 @@
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data() {
return {
msg: 'Hello world!'
}
}
}
</script>
<style>
.example {
color: red;
}
</style>

View File

@@ -1,35 +0,0 @@
import Vue from 'Vue';
import HelloWorld from './HelloWorld.vue';
function SimpleVuePlugin() {
return function install(openmct) {
openmct.types.addType('hello-world', {
name: 'Hello World',
description: 'An introduction object',
creatable: true
});
openmct.objectViews.addProvider({
name: "demo-provider",
key: "hello-world",
cssClass: "icon-packet",
canView: function (d) {
return d.type === 'hello-world';
},
view: function (domainObject) {
var vm;
return {
show: function (container) {
vm = new Vue(HelloWorld);
container.appendChild(vm.$mount().$el);
},
destroy: function (container) {
vm.$destroy();
}
};
}
});
}
}
export default SimpleVuePlugin

View File

@@ -1,32 +1,16 @@
define([
"./src/ExampleStyleGuideModelProvider",
"./src/MCTExample",
"./res/templates/intro.html",
"./res/templates/standards.html",
"./res/templates/colors.html",
"./res/templates/status.html",
"./res/templates/glyphs.html",
"./res/templates/controls.html",
"./res/templates/input.html",
"./res/templates/menus.html"
'legacyRegistry'
], function (
ExampleStyleGuideModelProvider,
MCTExample,
introTemplate,
standardsTemplate,
colorsTemplate,
statusTemplate,
glyphsTemplate,
controlsTemplate,
inputTemplate,
menusTemplate
legacyRegistry
) {
return {
name:"example/styleguide",
definition: {
"name": "Open MCT Style Guide",
"description": "Examples and documentation illustrating UI styles in use in Open MCT.",
"extensions":
legacyRegistry.register("example/styleguide", {
"name": "Open MCT Style Guide",
"description": "Examples and documentation illustrating UI styles in use in Open MCT.",
"extensions":
{
"types": [
{ "key": "styleguide.intro", "name": "Introduction", "cssClass": "icon-page", "description": "Introduction and overview to the style guide" },
@@ -39,14 +23,14 @@ define([
{ "key": "styleguide.menus", "name": "Menus", "cssClass": "icon-page", "description": "Context menus, dropdowns" }
],
"views": [
{ "key": "styleguide.intro", "type": "styleguide.intro", "template": introTemplate, "editable": false },
{ "key": "styleguide.standards", "type": "styleguide.standards", "template": standardsTemplate, "editable": false },
{ "key": "styleguide.colors", "type": "styleguide.colors", "template": colorsTemplate, "editable": false },
{ "key": "styleguide.status", "type": "styleguide.status", "template": statusTemplate, "editable": false },
{ "key": "styleguide.glyphs", "type": "styleguide.glyphs", "template": glyphsTemplate, "editable": false },
{ "key": "styleguide.controls", "type": "styleguide.controls", "template": controlsTemplate, "editable": false },
{ "key": "styleguide.input", "type": "styleguide.input", "template": inputTemplate, "editable": false },
{ "key": "styleguide.menus", "type": "styleguide.menus", "template": menusTemplate, "editable": false }
{ "key": "styleguide.intro", "type": "styleguide.intro", "templateUrl": "templates/intro.html", "editable": false },
{ "key": "styleguide.standards", "type": "styleguide.standards", "templateUrl": "templates/standards.html", "editable": false },
{ "key": "styleguide.colors", "type": "styleguide.colors", "templateUrl": "templates/colors.html", "editable": false },
{ "key": "styleguide.status", "type": "styleguide.status", "templateUrl": "templates/status.html", "editable": false },
{ "key": "styleguide.glyphs", "type": "styleguide.glyphs", "templateUrl": "templates/glyphs.html", "editable": false },
{ "key": "styleguide.controls", "type": "styleguide.controls", "templateUrl": "templates/controls.html", "editable": false },
{ "key": "styleguide.input", "type": "styleguide.input", "templateUrl": "templates/input.html", "editable": false },
{ "key": "styleguide.menus", "type": "styleguide.menus", "templateUrl": "templates/menus.html", "editable": false }
],
"roots": [
{
@@ -101,8 +85,17 @@ define([
"$q"
]
}
],
"stylesheets": [
{
"stylesheetUrl": "css/style-guide-espresso.css",
"theme": "espresso"
},
{
"stylesheetUrl": "css/style-guide-snow.css",
"theme": "snow"
}
]
}
}
};
});
});

View File

@@ -0,0 +1,210 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2016, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
.l-style-guide {
font-size: 0.9em;
text-align: justify;
margin: auto 10%;
a.link {
color: $colorKey;
}
h1, h2, strong, b {
color: pullForward($colorBodyFg, 50%);
}
h2 {
font-size: 1.25em;
}
h3 {
font-size: 0.9em;
margin: $interiorMargin 0;
&:not(:first-child) {
margin-top: $interiorMarginLg * 2;
}
text-transform: uppercase;
}
strong, b {
font-weight: normal;
}
.w-markup {
//Wrap markup example "pre" element
background-color: $colorCode;
border-radius: $interiorMargin;
display: block;
padding: $interiorMarginLg $interiorMarginLg;
position: relative;
}
.w-mct-example {
color: #ccc;
> div { margin-bottom: $interiorMarginLg; }
}
code,
pre {
font-size: 0.8rem;
}
code {
background-color: $colorCode;
border-radius: $controlCr;
display: inline-block;
padding: 1px $interiorMargin;
}
pre {
display: block;
margin: 0;
max-height: 300px;
overflow: auto;
padding-bottom: $interiorMarginLg;
white-space: pre;
}
table, ul {
margin-bottom: $interiorMarginLg;
width: auto;
}
.themed {
display: none; // Each themed styleguide file will set this to block.
}
.doc-title {
color: rgba(#fff, 0.3);
text-transform: uppercase;
}
.l-section {
border-top: 1px solid rgba(#999, 0.3);
margin-top: 2em;
padding-top: 1em;
.cols {
display: flex;
flex-direction: row;
.col {
flex: 1 1 auto;
&:not(:last-child) {
$v: $interiorMargin * 4;
border-right: 1px solid $colorInteriorBorder;
margin-right: $v;
padding-right: $v;
}
min-width: 300px;
img {
width: 100%;
}
}
&.cols1-1 {
// 2 cols, equal width
.col {
width: 50%;
}
}
&.cols1-2 {
// 3 cols, first is 1/3 of the width
.col:first-child {
width: 33%;
}
.col:last-child {
width: 66%;
}
}
&.cols2-1 {
// 3 cols, first is 2/3 of the width
.col:first-child {
width: 66%;
}
.col:last-child {
width: 33%;
}
}
}
}
// Example grid of glyphs
.items-holder.grid {
table.details {
width: 100%;
td {
font-size: inherit;
&.label {
color: pushBack($colorBodyFg, 10%);
text-transform: uppercase;
white-space: nowrap;
}
}
}
.item.glyph-item,
.item.swatch-item {
margin-bottom: 50px;
margin-right: 10px;
position: relative;
text-align: left;
.glyph {
color: $colorGlyphExample;
font-size: 5em;
margin: $interiorMarginLg 0;
text-align: center;
}
}
.item.glyph-item {
width: 225px;
height: 200px;
}
.item.swatch-item {
$h: 150px;
$d: 75px;
width: 200px;
height: $h;
.glyph {
text-shadow: 0px 1px 10px rgba(black, 0.3);
}
.h-swatch {
position: relative;
height: $d + $interiorMarginLg;
}
.swatch {
height: $d; width: $d;
border: 1px solid $colorInteriorBorder;
border-radius: 15%;
position: absolute;
left: 50%;
transform: translateX(-50%);
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2019, United States Government
* Open MCT, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -19,33 +19,19 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
@import "bourbon";
@import "../../../../platform/commonUI/general/res/sass/constants";
@import "../../../../platform/commonUI/general/res/sass/mixins";
@import "../../../../platform/commonUI/themes/espresso/res/sass/constants";
@import "../../../../platform/commonUI/themes/espresso/res/sass/mixins";
@import "../../../../platform/commonUI/general/res/sass/glyphs";
@import "../../../../platform/commonUI/general/res/sass/icons";
/***************** PLOTLY OVERRIDES */
.plot-container.plotly {
.bglayer .bg {
fill: $colorPlotBg !important;
fill-opacity: 1 !important;
stroke: $colorInteriorBorder;
stroke-width: 1 !important;
}
// Thematic constants
$colorCode: rgba(black, 0.2);
$colorGlyphExample: #fff;
.cartesianlayer .gridlayer {
.x,
.y {
path {
opacity: $opacityPlotHash;
stroke: $colorPlotHash !important;
}
}
}
@import "style-guide-base";
.xtick,
.ytick,
.g-xtitle,
.g-ytitle {
text {
fill: $colorPlotFg !important;
font-size: 12px !important;
}
}
}
div.themed.espresso { display: block; }
span.themed.espresso { display: inline; }

View File

@@ -0,0 +1,37 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2015, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
@import "bourbon";
@import "../../../../platform/commonUI/general/res/sass/constants";
@import "../../../../platform/commonUI/general/res/sass/mixins";
@import "../../../../platform/commonUI/themes/snow/res/sass/constants";
@import "../../../../platform/commonUI/themes/snow/res/sass/mixins";
@import "../../../../platform/commonUI/general/res/sass/glyphs";
@import "../../../../platform/commonUI/general/res/sass/icons";
// Thematic constants
$colorCode: rgba(black, 0.1);
$colorGlyphExample: darken($colorBodyBg, 30%);
@import "style-guide-base";
div.themed.snow { display: block; }
span.themed.snow { display: inline; }

View File

@@ -34,7 +34,7 @@
<p>As you develop plugins for Open MCT, consider how a generalized component might be combined with others when designing to create a rich and powerful larger object, rather than adding a single monolithic, non-modular plugin. To solve a particular problem or allow a new feature in Open MCT, you may need to introduce more than just one new object type.</p>
</div>
<div class="col">
<img src="../images/diagram-objects.svg" />
<img src="/example/styleguide/res/images/diagram-objects.svg" />
</div>
</div>
</div>
@@ -48,7 +48,7 @@
<p>The types of objects that a container can hold should be based on the purpose of the container and the views that it affords. For example, a Folders purpose is to allow a user to conceptually organize objects of all other types; a Folder must therefore be able to contain an object of any type.</p>
</div>
<div class="col">
<img src="../images/diagram-containment.svg" />
<img src="/example/styleguide/res/images/diagram-containment.svg" />
</div>
</div>
</div>
@@ -60,7 +60,7 @@
<p>Views are simply different ways to view the content of a given object. For example, telemetry data could be viewed as a plot or a table. A clock can display its time in analog fashion or with digital numbers. In each view, all of the content is present; its just represented differently. When providing views for an object, all the content of the object should be present in each view.</p>
</div>
<div class="col">
<img src="../images/diagram-views.svg" />
<img src="/example/styleguide/res/images/diagram-views.svg" />
</div>
</div>
</div>
@@ -70,4 +70,4 @@
<p></p>
<p></p>
<p></p>
</div>
</div>

View File

@@ -30,14 +30,14 @@ define(
var pages = {};
// Add pages
pages.intro = { name: "Introduction", type: "styleguide.intro", location: "styleguide:home" };
pages.standards = { name: "Standards", type: "styleguide.standards", location: "styleguide:home" };
pages.colors = { name: "Colors", type: "styleguide.colors", location: "styleguide:home" };
pages.glyphs = { name: "Glyphs", type: "styleguide.glyphs", location: "styleguide:home" };
pages.status = { name: "Status Indication", type: "styleguide.status", location: "styleguide:home" };
pages.controls = { name: "Controls", type: "styleguide.controls", location: "styleguide:ui-elements" };
pages.input = { name: "Text Inputs", type: "styleguide.input", location: "styleguide:ui-elements" };
pages.menus = { name: "Menus", type: "styleguide.menus", location: "styleguide:ui-elements" };
pages['intro'] = { name: "Introduction", type: "styleguide.intro", location: "styleguide:home" };
pages['standards'] = { name: "Standards", type: "styleguide.standards", location: "styleguide:home" };
pages['colors'] = { name: "Colors", type: "styleguide.colors", location: "styleguide:home" };
pages['glyphs'] = { name: "Glyphs", type: "styleguide.glyphs", location: "styleguide:home" };
pages['status'] = { name: "Status Indication", type: "styleguide.status", location: "styleguide:home" };
pages['controls'] = { name: "Controls", type: "styleguide.controls", location: "styleguide:ui-elements" };
pages['input'] = { name: "Text Inputs", type: "styleguide.input", location: "styleguide:ui-elements" };
pages['menus'] = { name: "Menus", type: "styleguide.menus", location: "styleguide:ui-elements" };
return {
getModels: function () {
@@ -48,4 +48,4 @@ define(
return ExampleStyleGuideModelProvider
}
);
);

View File

@@ -1,5 +1,5 @@
define([
'../res/templates/mct-example.html'
'text!../res/templates/mct-example.html'
], function (
MCTExampleTemplate
) {

View File

@@ -0,0 +1,68 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/ExampleTaxonomyModelProvider",
'legacyRegistry'
], function (
ExampleTaxonomyModelProvider,
legacyRegistry
) {
"use strict";
legacyRegistry.register("example/taxonomy", {
"name": "Example taxonomy",
"description": "Example illustrating the addition of a static top-level hierarchy",
"extensions": {
"roots": [
{
"id": "exampleTaxonomy"
}
],
"models": [
{
"id": "exampleTaxonomy",
"model": {
"type": "folder",
"name": "Stub Subsystems",
"composition": [
"examplePacket0",
"examplePacket1",
"examplePacket2"
]
}
}
],
"components": [
{
"provides": "modelService",
"type": "provider",
"implementation": ExampleTaxonomyModelProvider,
"depends": [
"$q"
]
}
]
}
});
});

View File

@@ -0,0 +1,69 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define(
[],
function () {
"use strict";
function ExampleTaxonomyModelProvider($q) {
var models = {},
packetId,
telemetryId,
i,
j;
// Add some "subsystems"
for (i = 0; i < 3; i += 1) {
packetId = "examplePacket" + i;
models[packetId] = {
name: "Stub Subsystem " + (i + 1),
type: "telemetry.panel",
composition: []
};
// Add some "telemetry points"
for (j = 0; j < 100 * (i + 1); j += 1) {
telemetryId = "exampleTelemetry" + j;
models[telemetryId] = {
name: "SWG" + i + "." + j,
type: "generator",
telemetry: {
period: 10 + i + j
}
};
models[packetId].composition.push(telemetryId);
}
}
return {
getModels: function () {
return $q.when(models);
}
};
}
return ExampleTaxonomyModelProvider;
}
);

1
example/worker/README.md Normal file
View File

@@ -0,0 +1 @@
Example of running a Web Worker using the `workerService`.

52
example/worker/bundle.js Normal file
View File

@@ -0,0 +1,52 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/FibonacciIndicator",
'legacyRegistry'
], function (
FibonacciIndicator,
legacyRegistry
) {
"use strict";
legacyRegistry.register("example/worker", {
"extensions": {
"indicators": [
{
"implementation": FibonacciIndicator,
"depends": [
"workerService",
"$rootScope"
]
}
],
"workers": [
{
"key": "example.fibonacci",
"scriptUrl": "FibonacciWorker.js"
}
]
}
});
});

View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2019, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -19,43 +19,49 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
import WebPageComponent from './components/WebPage.vue';
import Vue from 'vue';
define(
[],
function () {
"use strict";
export default function WebPage(openmct) {
return {
key: 'webPage',
name: 'Web Page',
cssClass: 'icon-page',
canView: function (domainObject) {
return domainObject.type === 'webPage';
},
view: function (domainObject) {
let component;
/**
* Displays Fibonacci numbers in the status area.
* @constructor
*/
function FibonacciIndicator(workerService, $rootScope) {
var latest,
counter = 0,
worker = workerService.run('example.fibonacci');
function requestNext() {
worker.postMessage([counter]);
counter += 1;
}
function handleResponse(event) {
latest = event.data;
$rootScope.$apply();
requestNext();
}
worker.onmessage = handleResponse;
requestNext();
return {
show: function (element) {
component = new Vue({
el: element,
components: {
WebPageComponent: WebPageComponent
},
provide: {
openmct,
domainObject
},
template: '<web-page-component></web-page-component>'
});
getCssClass: function () {
return "icon-object-unknown";
},
destroy: function (element) {
component.$destroy();
component = undefined;
getText: function () {
return "" + latest;
},
getDescription: function () {
return "";
}
};
},
priority: function () {
return 1;
}
};
}
return FibonacciIndicator;
}
);

View File

@@ -0,0 +1,15 @@
/*global self*/
(function () {
"use strict";
// Calculate fibonacci numbers inefficiently.
// We can do this because we're on a background thread, and
// won't halt the UI.
function fib(n) {
return n < 2 ? n : (fib(n - 1) + fib(n - 2));
}
self.onmessage = function (event) {
self.postMessage(fib(event.data));
};
}());

181
gulpfile.js Normal file
View File

@@ -0,0 +1,181 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global require,__dirname*/
require("v8-compile-cache");
var gulp = require('gulp'),
sourcemaps = require('gulp-sourcemaps'),
path = require('path'),
fs = require('fs'),
git = require('git-rev-sync'),
moment = require('moment'),
project = require('./package.json'),
paths = {
main: 'openmct.js',
dist: 'dist',
reports: 'dist/reports',
scss: ['./platform/**/*.scss', './example/**/*.scss'],
assets: [
'./{example,platform}/**/*.{css,css.map,png,svg,ico,woff,eot,ttf}'
],
scripts: [ 'openmct.js', 'platform/**/*.js', 'src/**/*.js' ],
specs: [ 'platform/**/*Spec.js', 'src/**/*Spec.js' ],
},
options = {
requirejsOptimize: {
name: 'bower_components/almond/almond.js',
include: paths.main.replace('.js', ''),
wrap: {
start: (function () {
var buildVariables = {
version: project.version,
timestamp: moment.utc(Date.now()).format(),
revision: fs.existsSync('.git') ? git.long() : 'Unknown',
branch: fs.existsSync('.git') ? git.branch() : 'Unknown'
};
return fs.readFileSync("src/start.frag", 'utf-8')
.replace(/@@(\w+)/g, function (match, key) {
return buildVariables[key];
});;
}()),
endFile: "src/end.frag"
},
optimize: 'uglify2',
uglify2: { output: { comments: /@preserve/ } },
mainConfigFile: paths.main,
wrapShim: true
},
karma: {
configFile: path.resolve(__dirname, 'karma.conf.js'),
singleRun: true
},
sass: {
sourceComments: true
}
};
if (process.env.NODE_ENV === 'development') {
options.requirejsOptimize.optimize = 'none';
}
gulp.task('scripts', function () {
var requirejsOptimize = require('gulp-requirejs-optimize');
return gulp.src(paths.main)
.pipe(sourcemaps.init())
.pipe(requirejsOptimize(options.requirejsOptimize))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(paths.dist));
});
gulp.task('test', function (done) {
var karma = require('karma');
new karma.Server(options.karma, done).start();
});
gulp.task('stylesheets', function () {
var sass = require('gulp-sass');
var rename = require('gulp-rename');
var bourbon = require('node-bourbon');
options.sass.includePaths = bourbon.includePaths;
return gulp.src(paths.scss, {base: '.'})
.pipe(sourcemaps.init())
.pipe(sass(options.sass).on('error', sass.logError))
.pipe(rename(function (file) {
file.dirname =
file.dirname.replace(path.sep + 'sass', path.sep + 'css');
return file;
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(__dirname));
});
gulp.task('lint', function () {
var jshint = require('gulp-jshint');
var merge = require('merge-stream');
var nonspecs = paths.specs.map(function (glob) {
return "!" + glob;
}),
scriptLint = gulp.src(paths.scripts.concat(nonspecs))
.pipe(jshint()),
specLint = gulp.src(paths.specs)
.pipe(jshint({ jasmine: true }));
return merge(scriptLint, specLint)
.pipe(jshint.reporter('gulp-jshint-html-reporter', {
filename: paths.reports + '/lint/jshint-report.html',
createMissingFolders : true
}))
.pipe(jshint.reporter('default'))
.pipe(jshint.reporter('fail'));
});
gulp.task('checkstyle', function () {
var jscs = require('gulp-jscs');
var mkdirp = require('mkdirp');
var reportName = 'jscs-html-report.html';
var reportPath = path.resolve(paths.reports, 'checkstyle', reportName);
var moveReport = fs.rename.bind(fs, reportName, reportPath, function () {});
mkdirp.sync(path.resolve(paths.reports, 'checkstyle'));
return gulp.src(paths.scripts)
.pipe(jscs())
.pipe(jscs.reporter())
.pipe(jscs.reporter('jscs-html-reporter')).on('finish', moveReport)
.pipe(jscs.reporter('fail'));
});
gulp.task('fixstyle', function () {
var jscs = require('gulp-jscs');
return gulp.src(paths.scripts, { base: '.' })
.pipe(jscs({ fix: true }))
.pipe(gulp.dest('.'));
});
gulp.task('assets', ['stylesheets'], function () {
return gulp.src(paths.assets)
.pipe(gulp.dest(paths.dist));
});
gulp.task('watch', function () {
return gulp.watch(paths.scss, ['stylesheets', 'assets']);
});
gulp.task('serve', function () {
console.log('Running development server with all defaults');
var app = require('./app.js');
});
gulp.task('develop', ['serve', 'stylesheets', 'watch']);
gulp.task('install', [ 'assets', 'scripts' ]);
gulp.task('verify', [ 'lint', 'test', 'checkstyle' ]);
gulp.task('build', [ 'verify', 'install' ]);

View File

@@ -1,5 +1,5 @@
<!--
Open MCT, Copyright (c) 2014-2020, United States Government
Open MCT, Copyright (c) 2014-2017, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
@@ -26,97 +26,66 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title></title>
<script src="dist/openmct.js"></script>
<link rel="icon" type="image/png" href="dist/favicons/favicon-96x96.png" sizes="96x96" type="image/x-icon">
<link rel="icon" type="image/png" href="dist/favicons/favicon-32x32.png" sizes="32x32" type="image/x-icon">
<link rel="icon" type="image/png" href="dist/favicons/favicon-16x16.png" sizes="16x16" type="image/x-icon">
</head>
<body>
</body>
<script>
const THIRTY_SECONDS = 30 * 1000;
const THIRTY_MINUTES = THIRTY_SECONDS * 60;
<script src="bower_components/requirejs/require.js"> </script>
<script>
var THIRTY_MINUTES = 30 * 60 * 1000;
[
'example/eventGenerator'
].forEach(
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
);
openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.Espresso());
openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.Generator());
openmct.install(openmct.plugins.ExampleImagery());
openmct.install(openmct.plugins.UTCTimeSystem());
openmct.install(openmct.plugins.AutoflowView({
type: "telemetry.panel"
}));
openmct.install(openmct.plugins.DisplayLayout({
showAsView: ['summary-widget', 'example.imagery']
}));
openmct.install(openmct.plugins.Conductor({
menuOptions: [
{
name: "Fixed",
timeSystem: 'utc',
bounds: {
start: Date.now() - THIRTY_MINUTES,
end: Date.now()
},
// commonly used bounds can be stored in history
// bounds (start and end) can accept either a milliseconds number
// or a callback function returning a milliseconds number
// a function is useful for invoking Date.now() at exact moment of preset selection
presets: [
require(['openmct'], function (openmct) {
[
'example/eventGenerator',
'example/styleguide'
].forEach(
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
);
openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.Espresso());
openmct.install(openmct.plugins.Generator());
openmct.install(openmct.plugins.ExampleImagery());
openmct.install(openmct.plugins.UTCTimeSystem());
openmct.install(openmct.plugins.ImportExport());
openmct.install(openmct.plugins.AutoflowView({
type: "telemetry.panel"
}));
openmct.install(openmct.plugins.Conductor({
menuOptions: [
{
label: 'Last Day',
name: "Fixed",
timeSystem: 'utc',
bounds: {
start: () => Date.now() - 1000 * 60 * 60 * 24,
end: () => Date.now()
start: Date.now() - THIRTY_MINUTES,
end: Date.now()
}
},
{
label: 'Last 2 hours',
bounds: {
start: () => Date.now() - 1000 * 60 * 60 * 2,
end: () => Date.now()
}
},
{
label: 'Last hour',
bounds: {
start: () => Date.now() - 1000 * 60 * 60,
end: () => Date.now()
name: "Realtime",
timeSystem: 'utc',
clock: 'local',
clockOffsets: {
start: -25 * 60 * 1000,
end: 5 * 60 * 1000
}
}
],
// maximum recent bounds to retain in conductor history
records: 10,
// maximum duration between start and end bounds
// for utc-based time systems this is in milliseconds
limit: 1000 * 60 * 60 * 24
},
{
name: "Realtime",
timeSystem: 'utc',
clock: 'local',
clockOffsets: {
start: - THIRTY_MINUTES,
end: THIRTY_SECONDS
}
}
]
}));
openmct.install(openmct.plugins.SummaryWidget());
openmct.install(openmct.plugins.Notebook());
openmct.install(openmct.plugins.LADTable());
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
openmct.install(openmct.plugins.ObjectMigration());
openmct.install(openmct.plugins.ClearData(
['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked'],
{indicator: true}
));
openmct.start();
</script>
]
}));
openmct.install(openmct.plugins.SummaryWidget());
openmct.install(openmct.plugins.Notebook());
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
openmct.time.timeSystem('utc');
openmct.start();
window.openmct = openmct;
});
</script>
<link rel="stylesheet" href="platform/commonUI/general/res/css/startup-base.css">
<link rel="stylesheet" href="platform/commonUI/general/res/css/openmct.css">
<link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-16x16.png" sizes="16x16">
<link rel="shortcut icon" href="platform/commonUI/general/res/images/favicons/favicon.ico">
</head>
<body>
<div class="l-splash-holder s-splash-holder">
<div class="l-splash s-splash"></div>
</div>
</body>
</html>

View File

@@ -21,81 +21,91 @@
*****************************************************************************/
/*global module,process*/
module.exports = function(config) {
config.set({
const devMode = process.env.NODE_ENV !== 'production';
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'FirefoxHeadless'];
const coverageEnabled = process.env.COVERAGE === 'true';
const reporters = ['progress', 'html'];
// Base path that will be used to resolve all file patterns.
basePath: '',
if (coverageEnabled) {
reporters.push('coverage-istanbul');
}
// Frameworks to use
// Available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'requirejs'],
module.exports = (config) => {
const webpackConfig = require('./webpack.config.js');
delete webpackConfig.output;
// List of files / patterns to load in the browser.
// By default, files are also included in a script tag.
files: [
{pattern: 'bower_components/**/*.js', included: false},
{pattern: 'node_modules/d3-*/**/*.js', included: false},
{pattern: 'node_modules/vue/**/*.js', included: false},
{pattern: 'node_modules/printj/dist/*.js', included: false},
{pattern: 'src/**/*', included: false},
{pattern: 'node_modules/painterro/build/*.js', included: false},
{pattern: 'node_modules/html2canvas/dist/*', included: false},
{pattern: 'example/**/*.html', included: false},
{pattern: 'example/**/*.js', included: false},
{pattern: 'example/**/*.json', included: false},
{pattern: 'platform/**/*.js', included: false},
{pattern: 'warp/**/*.js', included: false},
{pattern: 'platform/**/*.html', included: false},
'test-main.js'
],
if (!devMode || coverageEnabled) {
webpackConfig.module.rules.push({
test: /\.js$/,
exclude: /node_modules|example|lib|dist/,
use: {
loader: 'istanbul-instrumenter-loader',
options: {
esModules: true
// List of files to exclude.
exclude: [
'platform/framework/src/Main.js'
],
// Preprocess matching files before serving them to the browser.
// https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'src/**/!(*Spec).js': [ 'coverage' ],
'platform/**/src/**/!(*Spec).js': [ 'coverage' ]
},
// Test results reporter to use
// Possible values: 'dots', 'progress'
// Available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage', 'html'],
// Web server port.
port: 9876,
// Wnable / disable colors in the output (reporters and logs).
colors: true,
logLevel: config.LOG_INFO,
// Rerun tests when any file changes.
autoWatch: true,
// Specify browsers to run tests in.
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'ChromeHeadless'
],
// Code coverage reporting.
coverageReporter: {
dir: process.env.CIRCLE_ARTIFACTS ?
process.env.CIRCLE_ARTIFACTS + '/coverage' :
"dist/reports/coverage",
check: {
global: {
lines: 80,
excludes: ['src/plugins/plot/**/*.js']
}
}
});
}
config.set({
basePath: '',
frameworks: ['jasmine'],
files: [
'platform/**/*Spec.js',
'src/**/*Spec.js'
],
port: 9876,
reporters: reporters,
browsers: browsers,
customLaunchers: {
ChromeDebugging: {
base: 'Chrome',
flags: ['--remote-debugging-port=9222'],
debug: true
}
},
colors: true,
logLevel: config.LOG_INFO,
autoWatch: true,
// HTML test reporting.
htmlReporter: {
outputDir: "dist/reports/tests",
preserveDescribeNesting: true,
foldAll: false
},
coverageIstanbulReporter: {
fixWebpackSourcePaths: true,
dir: process.env.CIRCLE_ARTIFACTS ?
process.env.CIRCLE_ARTIFACTS + '/coverage' :
"dist/reports/coverage",
reports: ['html', 'lcovonly', 'text-summary'],
thresholds: {
global: {
lines: 63
}
}
},
preprocessors: {
'platform/**/*Spec.js': ['webpack', 'sourcemap'],
'src/**/*Spec.js': ['webpack', 'sourcemap']
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only',
logLevel: 'warn'
},
singleRun: true,
browserNoActivityTimeout: 90000
// Continuous Integration mode.
// If true, Karma captures browsers, runs the tests and exits.
singleRun: true
});
}
};

View File

@@ -19,19 +19,102 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global module*/
/*global requirejs,BUILD_CONSTANTS*/
const matcher = /\/openmct.js$/;
if (document.currentScript) {
let src = document.currentScript.src;
if (src && matcher.test(src)) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = src.replace(matcher, '') + '/';
requirejs.config({
"paths": {
"legacyRegistry": "src/legacyRegistry",
"angular": "bower_components/angular/angular.min",
"angular-route": "bower_components/angular-route/angular-route.min",
"csv": "bower_components/comma-separated-values/csv.min",
"EventEmitter": "bower_components/eventemitter3/index",
"es6-promise": "bower_components/es6-promise/es6-promise.min",
"moment": "bower_components/moment/moment",
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
"moment-timezone": "bower_components/moment-timezone/builds/moment-timezone-with-data",
"saveAs": "bower_components/file-saver/FileSaver.min",
"screenfull": "bower_components/screenfull/dist/screenfull.min",
"text": "bower_components/text/text",
"uuid": "bower_components/node-uuid/uuid",
"vue": "node_modules/vue/dist/vue.min",
"zepto": "bower_components/zepto/zepto.min",
"lodash": "bower_components/lodash/lodash",
"d3-selection": "node_modules/d3-selection/dist/d3-selection.min",
"d3-scale": "node_modules/d3-scale/build/d3-scale.min",
"d3-axis": "node_modules/d3-axis/dist/d3-axis.min",
"d3-array": "node_modules/d3-array/dist/d3-array.min",
"d3-collection": "node_modules/d3-collection/dist/d3-collection.min",
"d3-color": "node_modules/d3-color/build/d3-color.min",
"d3-format": "node_modules/d3-format/build/d3-format.min",
"d3-interpolate": "node_modules/d3-interpolate/build/d3-interpolate.min",
"d3-time": "node_modules/d3-time/dist/d3-time.min",
"d3-time-format": "node_modules/d3-time-format/dist/d3-time-format.min",
"html2canvas": "node_modules/html2canvas/dist/html2canvas.min",
"painterro": "node_modules/painterro/build/painterro.min",
"printj": "node_modules/printj/dist/printj.min"
},
"shim": {
"angular": {
"exports": "angular"
},
"angular-route": {
"deps": ["angular"]
},
"EventEmitter": {
"exports": "EventEmitter"
},
"moment-duration-format": {
"deps": ["moment"]
},
"painterro": {
"exports": "Painterro"
},
"saveAs": {
"exports": "saveAs"
},
"screenfull": {
"exports": "screenfull"
},
"zepto": {
"exports": "Zepto"
},
"lodash": {
"exports": "lodash"
},
"d3-selection": {
"exports": "d3-selection"
},
"d3-scale": {
"deps": ["d3-array", "d3-collection", "d3-color", "d3-format", "d3-interpolate", "d3-time", "d3-time-format"],
"exports": "d3-scale"
},
"d3-axis": {
"exports": "d3-axis"
},
"dom-to-image": {
"exports": "domtoimage"
}
}
}
});
const MCT = require('./src/MCT');
define([
'./platform/framework/src/Main',
'./src/defaultRegistry',
'./src/MCT',
'./src/plugins/buildInfo/plugin'
], function (Main, defaultRegistry, MCT, buildInfo) {
var openmct = new MCT();
var openmct = new MCT();
openmct.legacyRegistry = defaultRegistry;
openmct.install(openmct.plugins.Plot());
module.exports = openmct;
if (typeof BUILD_CONSTANTS !== 'undefined') {
openmct.install(buildInfo(BUILD_CONSTANTS));
}
openmct.on('start', function () {
return new Main().run(defaultRegistry);
});
return openmct;
});

View File

@@ -1,17 +1,8 @@
{
"name": "openmct",
"version": "1.0.0-snapshot",
"description": "The Open MCT core platform",
"dependencies": {},
"devDependencies": {
"angular": ">=1.8.0",
"angular-route": "1.4.14",
"babel-eslint": "8.2.6",
"comma-separated-values": "^3.6.4",
"concurrently": "^3.6.1",
"copy-webpack-plugin": "^4.5.2",
"cross-env": "^6.0.3",
"css-loader": "^1.0.0",
"version": "0.14.0-SNAPSHOT",
"description": "The Open MCT core platform.",
"dependencies": {
"d3-array": "1.2.x",
"d3-axis": "1.0.x",
"d3-collection": "1.0.x",
@@ -22,78 +13,58 @@
"d3-selection": "1.3.x",
"d3-time": "1.0.x",
"d3-time-format": "2.1.x",
"eslint": "5.2.0",
"eslint-plugin-vue": "^6.0.0",
"eslint-plugin-you-dont-need-lodash-underscore": "^6.10.0",
"eventemitter3": "^1.2.0",
"exports-loader": "^0.7.0",
"express": "^4.13.1",
"fast-sass-loader": "1.4.6",
"file-loader": "^1.1.11",
"file-saver": "^1.3.8",
"minimist": "^1.1.1",
"painterro": "0.2.65",
"request": "^2.69.0",
"vue": "^2.5.6"
},
"devDependencies": {
"bower": "^1.7.7",
"git-rev-sync": "^1.4.0",
"glob": ">= 3.0.0",
"html-loader": "^0.5.5",
"gulp": "^3.9.1",
"gulp-jscs": "^3.0.2",
"gulp-jshint": "^2.0.0",
"gulp-jshint-html-reporter": "^0.1.3",
"gulp-rename": "^1.2.2",
"gulp-requirejs-optimize": "^0.3.1",
"gulp-sass": "^3.1.0",
"gulp-sourcemaps": "^1.6.0",
"html2canvas": "^1.0.0-alpha.12",
"imports-loader": "^0.8.0",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine-core": "^3.1.0",
"jscs-html-reporter": "^0.1.0",
"jsdoc": "^3.3.2",
"jshint": "^2.7.0",
"karma": "^2.0.3",
"karma-chrome-launcher": "^2.2.0",
"karma-firefox-launcher": "^1.3.0",
"karma-cli": "^1.0.1",
"karma-coverage": "^1.1.2",
"karma-coverage-istanbul-reporter": "^2.1.1",
"karma-html-reporter": "^0.2.7",
"karma-jasmine": "^1.1.2",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^3.0.0",
"location-bar": "^3.0.1",
"lodash": "^4.17.12",
"karma-requirejs": "^1.1.0",
"markdown-toc": "^0.11.7",
"marked": "^0.3.5",
"mini-css-extract-plugin": "^0.4.1",
"minimist": "^1.1.1",
"moment": "2.25.3",
"moment-duration-format": "^2.2.2",
"moment-timezone": "0.5.28",
"merge-stream": "^1.0.0",
"mkdirp": "^0.5.1",
"moment": "^2.11.1",
"node-bourbon": "^4.2.3",
"node-sass": "^4.9.2",
"painterro": "^1.0.35",
"printj": "^1.2.1",
"raw-loader": "^0.5.1",
"request": "^2.69.0",
"printj": "^1.1.0",
"requirejs": "2.1.x",
"split": "^1.0.0",
"style-loader": "^1.0.1",
"uuid": "^3.3.3",
"v8-compile-cache": "^1.1.0",
"vue": "2.5.6",
"vue-loader": "^15.2.6",
"vue-template-compiler": "2.5.6",
"webpack": "^4.16.2",
"webpack-cli": "^3.1.0",
"webpack-dev-middleware": "^3.1.3",
"webpack-hot-middleware": "^2.22.3",
"zepto": "^1.2.0"
"v8-compile-cache": "^1.1.0"
},
"scripts": {
"clean": "rm -rf ./dist",
"start": "node app.js",
"lint": "eslint platform example src --ext .js,.vue openmct.js",
"lint:fix": "eslint platform example src --ext .js,.vue openmct.js --fix",
"build:prod": "cross-env NODE_ENV=production webpack",
"build:dev": "webpack",
"build:watch": "webpack --watch",
"test": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --single-run",
"test:debug": "cross-env NODE_ENV=debug karma start --no-single-run",
"test:coverage": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" COVERAGE=true karma start --single-run",
"test:watch": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --no-single-run",
"verify": "concurrently 'npm:test' 'npm:lint'",
"test": "karma start --single-run",
"jshint": "jshint platform example",
"lint": "./node_modules/gulp/bin/gulp.js lint",
"checkstyle": "./node_modules/gulp/bin/gulp.js checkstyle",
"watch": "karma start",
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
"otherdoc": "node docs/gendocs.js --in docs/src --out dist/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'",
"docs": "npm run jsdoc ; npm run otherdoc",
"prepare": "npm run build:prod"
"prepare": "node ./node_modules/bower/bin/bower install && node ./node_modules/gulp/bin/gulp.js install"
},
"repository": {
"type": "git",

View File

@@ -21,17 +21,18 @@
*****************************************************************************/
define([
"./res/templates/about-dialog.html",
"text!./res/templates/about-dialog.html",
"./src/LogoController",
"./src/AboutController",
"./src/LicenseController",
"./res/templates/app-logo.html",
"./res/templates/about-logo.html",
"./res/templates/overlay-about.html",
"./res/templates/license-apache.html",
"./res/templates/license-mit.html",
"./res/templates/licenses.html",
"./res/templates/licenses-export-md.html"
"text!./res/templates/app-logo.html",
"text!./res/templates/about-logo.html",
"text!./res/templates/overlay-about.html",
"text!./res/templates/license-apache.html",
"text!./res/templates/license-mit.html",
"text!./res/templates/licenses.html",
"text!./res/templates/licenses-export-md.html",
'legacyRegistry'
], function (
aboutDialogTemplate,
LogoController,
@@ -43,139 +44,137 @@ define([
licenseApacheTemplate,
licenseMitTemplate,
licensesTemplate,
licensesExportMdTemplate
licensesExportMdTemplate,
legacyRegistry
) {
return {
name:"platform/commonUI/about",
definition: {
"name": "About Open MCT",
"extensions": {
"templates": [
{
"key": "app-logo",
"priority": "optional",
"template": appLogoTemplate
},
{
"key": "about-logo",
"priority": "preferred",
"template": aboutLogoTemplate
},
{
"key": "about-dialog",
"template": aboutDialogTemplate
},
{
"key": "overlay-about",
"template": overlayAboutTemplate
},
{
"key": "license-apache",
"template": licenseApacheTemplate
},
{
"key": "license-mit",
"template": licenseMitTemplate
}
],
"controllers": [
{
"key": "LogoController",
"depends": [
"overlayService"
],
"implementation": LogoController
},
{
"key": "AboutController",
"depends": [
"versions[]",
"$window"
],
"implementation": AboutController
},
{
"key": "LicenseController",
"depends": [
"licenses[]"
],
"implementation": LicenseController
}
],
"licenses": [
{
"name": "Json.NET",
"version": "6.0.8",
"author": "Newtonsoft",
"description": "JSON serialization/deserialization",
"website": "http://www.newtonsoft.com/json",
"copyright": "Copyright (c) 2007 James Newton-King",
"license": "license-mit",
"link": "https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md"
},
{
"name": "Nancy",
"version": "0.23.2",
"author": "Andreas Håkansson, Steven Robbins and contributors",
"description": "Embedded web server",
"website": "http://nancyfx.org/",
"copyright": "Copyright © 2010 Andreas Håkansson, Steven Robbins and contributors",
"license": "license-mit",
"link": "http://www.opensource.org/licenses/mit-license.php"
},
{
"name": "Nancy.Hosting.Self",
"version": "0.23.2",
"author": "Andreas Håkansson, Steven Robbins and contributors",
"description": "Embedded web server",
"website": "http://nancyfx.org/",
"copyright": "Copyright © 2010 Andreas Håkansson, Steven Robbins and contributors",
"license": "license-mit",
"link": "http://www.opensource.org/licenses/mit-license.php"
},
{
"name": "SuperSocket",
"version": "0.9.0.2",
"author": " Kerry Jiang",
"description": "Supports SuperWebSocket",
"website": "https://supersocket.codeplex.com/",
"copyright": "Copyright 2010-2014 Kerry Jiang (kerry-jiang@hotmail.com)",
"license": "license-apache",
"link": "https://supersocket.codeplex.com/license"
},
{
"name": "SuperWebSocket",
"version": "0.9.0.2",
"author": " Kerry Jiang",
"description": "WebSocket implementation for client-server communication",
"website": "https://superwebsocket.codeplex.com/",
"copyright": "Copyright 2010-2014 Kerry Jiang (kerry-jiang@hotmail.com)",
"license": "license-apache",
"link": "https://superwebsocket.codeplex.com/license"
},
{
"name": "log4net",
"version": "2.0.3",
"author": "Apache Software Foundation",
"description": "Logging",
"website": "http://logging.apache.org/log4net/",
"copyright": "Copyright © 2004-2015 Apache Software Foundation.",
"license": "license-apache",
"link": "http://logging.apache.org/log4net/license.html"
}
],
"routes": [
{
"when": "/licenses",
"template": licensesTemplate
},
{
"when": "/licenses-md",
"template": licensesExportMdTemplate
}
]
}
legacyRegistry.register("platform/commonUI/about", {
"name": "About Open MCT",
"extensions": {
"templates": [
{
"key": "app-logo",
"priority": "optional",
"template": appLogoTemplate
},
{
"key": "about-logo",
"priority": "preferred",
"template": aboutLogoTemplate
},
{
"key": "about-dialog",
"template": aboutDialogTemplate
},
{
"key": "overlay-about",
"template": overlayAboutTemplate
},
{
"key": "license-apache",
"template": licenseApacheTemplate
},
{
"key": "license-mit",
"template": licenseMitTemplate
}
],
"controllers": [
{
"key": "LogoController",
"depends": [
"overlayService"
],
"implementation": LogoController
},
{
"key": "AboutController",
"depends": [
"versions[]",
"$window"
],
"implementation": AboutController
},
{
"key": "LicenseController",
"depends": [
"licenses[]"
],
"implementation": LicenseController
}
],
"licenses": [
{
"name": "Json.NET",
"version": "6.0.8",
"author": "Newtonsoft",
"description": "JSON serialization/deserialization",
"website": "http://www.newtonsoft.com/json",
"copyright": "Copyright (c) 2007 James Newton-King",
"license": "license-mit",
"link": "https://github.com/JamesNK/Newtonsoft.Json/blob/master/LICENSE.md"
},
{
"name": "Nancy",
"version": "0.23.2",
"author": "Andreas Håkansson, Steven Robbins and contributors",
"description": "Embedded web server",
"website": "http://nancyfx.org/",
"copyright": "Copyright © 2010 Andreas Håkansson, Steven Robbins and contributors",
"license": "license-mit",
"link": "http://www.opensource.org/licenses/mit-license.php"
},
{
"name": "Nancy.Hosting.Self",
"version": "0.23.2",
"author": "Andreas Håkansson, Steven Robbins and contributors",
"description": "Embedded web server",
"website": "http://nancyfx.org/",
"copyright": "Copyright © 2010 Andreas Håkansson, Steven Robbins and contributors",
"license": "license-mit",
"link": "http://www.opensource.org/licenses/mit-license.php"
},
{
"name": "SuperSocket",
"version": "0.9.0.2",
"author": " Kerry Jiang",
"description": "Supports SuperWebSocket",
"website": "https://supersocket.codeplex.com/",
"copyright": "Copyright 2010-2014 Kerry Jiang (kerry-jiang@hotmail.com)",
"license": "license-apache",
"link": "https://supersocket.codeplex.com/license"
},
{
"name": "SuperWebSocket",
"version": "0.9.0.2",
"author": " Kerry Jiang",
"description": "WebSocket implementation for client-server communication",
"website": "https://superwebsocket.codeplex.com/",
"copyright": "Copyright 2010-2014 Kerry Jiang (kerry-jiang@hotmail.com)",
"license": "license-apache",
"link": "https://superwebsocket.codeplex.com/license"
},
{
"name": "log4net",
"version": "2.0.3",
"author": "Apache Software Foundation",
"description": "Logging",
"website": "http://logging.apache.org/log4net/",
"copyright": "Copyright © 2004-2015 Apache Software Foundation.",
"license": "license-apache",
"link": "http://logging.apache.org/log4net/license.html"
}
],
"routes": [
{
"when": "/licenses",
"template": licensesTemplate
},
{
"when": "/licenses-md",
"template": licensesExportMdTemplate
}
]
}
};
});
});

View File

@@ -21,157 +21,292 @@
*****************************************************************************/
define([
"./src/BrowseController",
"./src/PaneController",
"./src/InspectorPaneController",
"./src/BrowseObjectController",
"./src/MenuArrowController",
"./src/ObjectHeaderController",
"./src/navigation/NavigationService",
"./src/navigation/NavigateAction",
"./src/navigation/OrphanNavigationHandler",
"./src/windowing/NewTabAction",
"./res/templates/browse.html",
"./res/templates/browse-object.html",
"./res/templates/browse/object-header.html",
"./res/templates/browse/object-header-frame.html",
"./res/templates/menu-arrow.html",
"./res/templates/back-arrow.html",
"./res/templates/browse/object-properties.html",
"./res/templates/browse/inspector-region.html"
"./src/windowing/FullscreenAction",
"./src/windowing/WindowTitler",
"text!./res/templates/browse.html",
"text!./res/templates/browse-object.html",
"text!./res/templates/items/grid-item.html",
"text!./res/templates/browse/object-header.html",
"text!./res/templates/browse/object-header-frame.html",
"text!./res/templates/menu-arrow.html",
"text!./res/templates/back-arrow.html",
"text!./res/templates/items/items.html",
"text!./res/templates/browse/object-properties.html",
"text!./res/templates/browse/inspector-region.html",
'legacyRegistry'
], function (
BrowseController,
PaneController,
InspectorPaneController,
BrowseObjectController,
MenuArrowController,
ObjectHeaderController,
NavigationService,
NavigateAction,
OrphanNavigationHandler,
NewTabAction,
FullscreenAction,
WindowTitler,
browseTemplate,
browseObjectTemplate,
gridItemTemplate,
objectHeaderTemplate,
objectHeaderFrameTemplate,
menuArrowTemplate,
backArrowTemplate,
itemsTemplate,
objectPropertiesTemplate,
inspectorRegionTemplate
inspectorRegionTemplate,
legacyRegistry
) {
return {
name:"platform/commonUI/browse",
definition: {
"extensions": {
"routes": [
],
"constants": [
{
"key": "DEFAULT_PATH",
"value": "mine",
"priority": "fallback"
}
],
"representations": [
{
"key": "browse-object",
"template": browseObjectTemplate,
"gestures": [
"drop"
],
"uses": [
"view"
]
},
{
"key": "object-header",
"template": objectHeaderTemplate,
"uses": [
"type"
]
},
{
"key": "object-header-frame",
"template": objectHeaderFrameTemplate,
"uses": [
"type"
]
},
{
"key": "menu-arrow",
"template": menuArrowTemplate,
"uses": [
"action"
],
"gestures": [
"menu"
]
},
{
"key": "back-arrow",
"uses": [
"context"
],
"template": backArrowTemplate
},
{
"key": "object-properties",
"template": objectPropertiesTemplate
},
{
"key": "inspector-region",
"template": inspectorRegionTemplate
}
],
"services": [
{
"key": "navigationService",
"implementation": NavigationService,
"depends": [
"$window"
]
}
],
"actions": [
{
"key": "navigate",
"implementation": NavigateAction,
"depends": [
"navigationService"
]
},
{
"key": "window",
"name": "Open In New Tab",
"implementation": NewTabAction,
"description": "Open in a new browser tab",
"category": [
"view-control",
"contextual"
],
"depends": [
"urlService",
"$window"
],
"group": "windowing",
"cssClass": "icon-new-window",
"priority": "preferred"
}
],
"runs": [
{
"implementation": OrphanNavigationHandler,
"depends": [
"throttle",
"topic",
"navigationService"
]
}
],
"templates": [
{
key: "browseRoot",
template: browseTemplate
},
{
key: "browseObject",
template: browseObjectTemplate
},
{
key: "inspectorRegion",
template: inspectorRegionTemplate
}
]
}
legacyRegistry.register("platform/commonUI/browse", {
"extensions": {
"routes": [
{
"when": "/browse/:ids*?",
"template": browseTemplate,
"reloadOnSearch": false
},
{
"when": "",
"redirectTo": "/browse/"
}
],
"constants": [
{
"key": "DEFAULT_PATH",
"value": "mine",
"priority": "fallback"
}
],
"controllers": [
{
"key": "BrowseController",
"implementation": BrowseController,
"depends": [
"$scope",
"$route",
"$location",
"objectService",
"navigationService",
"urlService",
"DEFAULT_PATH"
]
},
{
"key": "PaneController",
"implementation": PaneController,
"priority": "preferred",
"depends": [
"$scope",
"agentService",
"$window",
"$location",
"$attrs",
"navigationService"
]
},
{
"key": "BrowseObjectController",
"implementation": BrowseObjectController,
"depends": [
"$scope",
"$location",
"$route"
]
},
{
"key": "MenuArrowController",
"implementation": MenuArrowController,
"depends": [
"$scope"
]
},
{
"key": "InspectorPaneController",
"implementation": InspectorPaneController,
"priority": "preferred",
"depends": [
"$scope",
"agentService",
"$window",
"navigationService",
"$location",
"$attrs"
]
},
{
"key": "ObjectHeaderController",
"implementation": ObjectHeaderController,
"depends": [
"$scope"
]
}
],
"representations": [
{
"key": "browse-object",
"template": browseObjectTemplate,
"gestures": [
"drop"
],
"uses": [
"view"
]
},
{
"key": "grid-item",
"template": gridItemTemplate,
"uses": [
"type",
"action",
"location"
],
"gestures": [
"info",
"menu"
]
},
{
"key": "object-header",
"template": objectHeaderTemplate,
"uses": [
"type"
]
},
{
"key": "object-header-frame",
"template": objectHeaderFrameTemplate,
"uses": [
"type"
]
},
{
"key": "menu-arrow",
"template": menuArrowTemplate,
"uses": [
"action"
],
"gestures": [
"menu"
]
},
{
"key": "back-arrow",
"uses": [
"context"
],
"template": backArrowTemplate
},
{
"key": "object-properties",
"template": objectPropertiesTemplate
},
{
"key": "inspector-region",
"template": inspectorRegionTemplate
}
],
"services": [
{
"key": "navigationService",
"implementation": NavigationService,
"depends": [
"$window"
]
}
],
"actions": [
{
"key": "navigate",
"implementation": NavigateAction,
"depends": [
"navigationService"
]
},
{
"key": "window",
"name": "Open In New Tab",
"implementation": NewTabAction,
"description": "Open in a new browser tab",
"category": [
"view-control",
"contextual"
],
"depends": [
"urlService",
"$window"
],
"group": "windowing",
"cssClass": "icon-new-window",
"priority": "preferred"
},
{
"key": "fullscreen",
"implementation": FullscreenAction,
"category": "view-control",
"group": "windowing",
"priority": "default"
}
],
"views": [
{
"key": "items",
"name": "Grid",
"cssClass": "icon-thumbs-strip",
"description": "Grid of available items",
"template": itemsTemplate,
"uses": [
"composition"
],
"gestures": [
"drop"
],
"type": "folder",
"editable": false
}
],
"runs": [
{
"implementation": WindowTitler,
"depends": [
"navigationService",
"$rootScope",
"$document"
]
},
{
"implementation": OrphanNavigationHandler,
"depends": [
"throttle",
"topic",
"navigationService"
]
}
],
"licenses": [
{
"name": "screenfull.js",
"version": "1.2.0",
"description": "Wrapper for cross-browser usage of fullscreen API",
"author": "Sindre Sorhus",
"website": "https://github.com/sindresorhus/screenfull.js/",
"copyright": "Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
"license": "license-mit",
"link": "https://github.com/sindresorhus/screenfull.js/blob/gh-pages/license"
}
]
}
};
});
});

View File

@@ -66,4 +66,5 @@
</mct-representation>
</div>
</div>
<mct-include key="'conductor'" class="abs holder flex-elem flex-fixed l-flex-row l-time-conductor-holder"></mct-include>
</div>

View File

@@ -0,0 +1,45 @@
<!--
Open MCT, Copyright (c) 2014-2018, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<!-- For selected, add class 'selected' to outer div -->
<div class='item grid-item' ng-click='action.perform("navigate")'>
<div class='contents abs'>
<div class='top-bar bar abs'>
<span class='icon-people' title='Shared'></span>
<mct-representation class="desktop-hide" key="'info-button'" mct-object="domainObject"></mct-representation>
</div>
<div class='item-main abs lg'>
<span class="t-item-icon" ng-class="{ 'l-icon-link':location.isLink() }">
<span class="t-item-icon-glyph ng-binding {{type.getCssClass()}}"></span>
</span>
<div class='abs item-open icon-pointer-right'></div>
</div>
<div class='bottom-bar bar abs'>
<div class='title'>{{model.name}}</div>
<div class='details'>
<span>{{type.getName()}}</span>
<span ng-show="model.composition !== undefined">
- {{model.composition.length}} Item<span ng-show="model.composition.length > 1">s</span>
</span>
</div>
</div>
</div>
</div>

View File

@@ -2,32 +2,26 @@
Open MCT, Copyright (c) 2014-2018, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<template>
<div></div>
</template>
<script>
export default {
inject: ['openmct'],
mounted() {
this.openmct.indicators.indicatorObjects.forEach((indicator) => {
this.$el.appendChild(indicator.element);
});
}
}
</script>
<div class='items-holder grid abs'>
<mct-representation key="'grid-item'"
ng-repeat="childObject in composition"
mct-object="childObject">
</mct-representation>
</div>

View File

@@ -0,0 +1,214 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* This bundle implements Browse mode.
* @namespace platform/commonUI/browse
*/
define(
['lodash'],
function (_) {
/**
* The BrowseController is used to populate the initial scope in Browse
* mode. It loads the root object from the objectService and makes it
* available in the scope for Angular template's; this is the point at
* which Angular templates first have access to the domain object
* hierarchy.
*
* @memberof platform/commonUI/browse
* @constructor
*/
function BrowseController(
$scope,
$route,
$location,
objectService,
navigationService,
urlService,
defaultPath
) {
var initialPath = ($route.current.params.ids || defaultPath).split("/"),
currentIds;
$scope.treeModel = {
selectedObject: undefined,
onSelection: function (object) {
navigationService.setNavigation(object, true);
},
allowSelection: function (object) {
var domainObjectInView = navigationService.getNavigation(),
isInEditMode = domainObjectInView.getCapability('status').get('editing');
if (isInEditMode) {
var actions = object.getCapability('action'),
previewAction = actions.getActions({key: 'mct-preview-action'})[0];
if (previewAction && previewAction.perform) {
previewAction.perform();
return false;
} else {
return navigationService.shouldNavigate();
}
} else {
return true;
}
}
};
function idsForObject(domainObject) {
return urlService
.urlForLocation("", domainObject)
.replace('/', '');
}
// Find an object in an array of objects.
function findObject(domainObjects, id) {
var i;
for (i = 0; i < domainObjects.length; i += 1) {
if (domainObjects[i].getId() === id) {
return domainObjects[i];
}
}
}
// helper, fetch a single object from the object service.
function getObject(id) {
return objectService.getObjects([id])
.then(function (results) {
return results[id];
});
}
// recursively locate and return an object inside of a container
// via a path. If at any point in the recursion it fails to find
// the next object, it will return the parent.
function findViaComposition(containerObject, path) {
var nextId = path.shift();
if (!nextId) {
return containerObject;
}
return containerObject.useCapability('composition')
.then(function (composees) {
var nextObject = findObject(composees, nextId);
if (!nextObject) {
return containerObject;
}
if (!nextObject.hasCapability('composition')) {
return nextObject;
}
return findViaComposition(nextObject, path);
});
}
function navigateToObject(desiredObject) {
$scope.navigatedObject = desiredObject;
$scope.treeModel.selectedObject = desiredObject;
currentIds = idsForObject(desiredObject);
$route.current.pathParams.ids = currentIds;
$location.path('/browse/' + currentIds);
}
function getLastChildIfRoot(object) {
if (object.getId() !== 'ROOT') {
return object;
}
return object.useCapability('composition')
.then(function (composees) {
return composees[composees.length - 1];
});
}
function navigateToPath(path) {
return getObject('ROOT')
.then(function (root) {
return findViaComposition(root, path);
})
.then(getLastChildIfRoot)
.then(function (object) {
navigationService.setNavigation(object);
});
}
getObject('ROOT')
.then(function (root) {
$scope.domainObject = root;
navigateToPath(initialPath);
});
// Handle navigation events from view service. Only navigates
// if path has changed.
function navigateDirectlyToModel(domainObject) {
var newIds = idsForObject(domainObject);
if (currentIds !== newIds) {
currentIds = newIds;
navigateToObject(domainObject);
}
}
// Listen for changes in navigation state.
navigationService.addListener(navigateDirectlyToModel);
// Listen for route changes which are caused by browser events
// (e.g. bookmarks to pages in OpenMCT) and prevent them. Instead,
// navigate to the path ourselves, which results in it being
// properly set.
$scope.$on('$routeChangeStart', function (event, route, oldRoute) {
if (route.$$route === $route.current.$$route) {
if (route.pathParams.ids &&
route.pathParams.ids !== $route.current.pathParams.ids) {
var otherParams = _.omit(route.params, 'ids');
var oldOtherParams = _.omit(oldRoute.params, 'ids');
var deletedParams = _.omit(oldOtherParams, _.keys(otherParams));
event.preventDefault();
navigateToPath(route.pathParams.ids.split('/'))
.then(function () {
if (!_.isEqual(otherParams, oldOtherParams)) {
_.forEach(otherParams, function (v, k) {
$location.search(k, v);
});
_.forEach(deletedParams, function (k) {
$location.search(k, null);
});
}
});
} else {
navigateToPath([]);
}
}
});
// Clean up when the scope is destroyed
$scope.$on("$destroy", function () {
navigationService.removeListener(navigateDirectlyToModel);
});
}
return BrowseController;
}
);

View File

@@ -0,0 +1,74 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
[],
function () {
/**
* Controller for the `browse-object` representation of a domain
* object (the right-hand side of Browse mode.)
* @memberof platform/commonUI/browse
* @constructor
*/
function BrowseObjectController($scope, $location, $route) {
var navigatedObject;
function setViewForDomainObject(domainObject) {
var locationViewKey = $location.search().view;
function selectViewIfMatching(view) {
if (view.key === locationViewKey) {
$scope.representation = $scope.representation || {};
$scope.representation.selected = view;
}
}
if (locationViewKey) {
((domainObject && domainObject.useCapability('view')) || [])
.forEach(selectViewIfMatching);
}
navigatedObject = domainObject;
}
function updateQueryParam(viewKey) {
if (viewKey && $location.search().view !== viewKey) {
$location.search('view', viewKey);
}
}
$scope.$watch('domainObject', setViewForDomainObject);
$scope.$watch('representation.selected.key', updateQueryParam);
$scope.$on('$locationChangeSuccess', function () {
setViewForDomainObject($scope.domainObject);
});
$scope.doAction = function (action) {
return $scope[action] && $scope[action]();
};
}
return BrowseObjectController;
}
);

View File

@@ -0,0 +1,78 @@
/*****************************************************************************
* 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(
["./PaneController"],
function (PaneController) {
/**
* Pane controller that reveals inspector, if hidden, when object
* switches to edit mode.
*
* @param $scope
* @param agentService
* @param $window
* @param navigationService
* @constructor
*/
function InspectorPaneController($scope, agentService, $window, navigationService, $location, $attrs) {
PaneController.call(this, $scope, agentService, $window, $location, $attrs);
var statusListener,
self = this;
function showInspector(statuses) {
if (statuses.indexOf('editing') !== -1 && !self.visible()) {
self.toggle();
}
}
function attachStatusListener(domainObject) {
// Remove existing status listener if existing
if (statusListener) {
statusListener();
}
if (domainObject.hasCapability("status")) {
statusListener = domainObject.getCapability("status").listen(showInspector);
}
return statusListener;
}
var domainObject = navigationService.getNavigation();
if (domainObject) {
attachStatusListener(domainObject);
}
navigationService.addListener(attachStatusListener);
$scope.$on("$destroy", function () {
statusListener();
navigationService.removeListener(attachStatusListener);
});
}
InspectorPaneController.prototype = Object.create(PaneController.prototype);
return InspectorPaneController;
}
);

View File

@@ -0,0 +1,59 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* Module defining MenuArrowController. Created by shale on 06/30/2015.
*/
define(
[],
function () {
/**
* A left-click on the menu arrow should display a
* context menu. This controller launches the context
* menu.
* @memberof platform/commonUI/browse
* @constructor
*/
function MenuArrowController($scope) {
this.$scope = $scope;
}
/**
* Show a context menu for the domain object in this scope.
*
* @param event the browser event which caused this (used to
* position the menu)
*/
MenuArrowController.prototype.showMenu = function (event) {
var actionContext = {
key: 'menu',
domainObject: this.$scope.domainObject,
event: event
};
this.$scope.domainObject.getCapability('action').perform(actionContext);
};
return MenuArrowController;
}
);

View File

@@ -0,0 +1,92 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
[],
function () {
/**
* Controller to provide the ability to inline edit an object name.
*
* @constructor
* @memberof platform/commonUI/browse
*/
function ObjectHeaderController($scope) {
this.$scope = $scope;
this.domainObject = $scope.domainObject;
this.editable = this.allowEdit();
}
/**
* Updates the object name on blur and enter keypress events.
*
* @param event the mouse event
*/
ObjectHeaderController.prototype.updateName = function (event) {
if (!event || !event.currentTarget) {
return;
}
if (event.type === 'blur') {
this.updateModel(event);
} else if (event.which === 13) {
this.updateModel(event);
event.currentTarget.blur();
window.getSelection().removeAllRanges();
}
};
/**
* Updates the model.
*
* @param event the mouse event
* @param private
*/
ObjectHeaderController.prototype.updateModel = function (event) {
var name = event.currentTarget.textContent.replace(/\n/g, ' ');
if (name.length === 0) {
name = "Unnamed " + this.domainObject.getCapability("type").typeDef.name;
event.currentTarget.textContent = name;
}
if (name !== this.domainObject.getModel().name) {
this.domainObject.getCapability('mutation').mutate(function (model) {
model.name = name;
});
}
};
/**
* Checks if the domain object is editable.
*
* @private
* @return true if object is editable
*/
ObjectHeaderController.prototype.allowEdit = function () {
var type = this.domainObject && this.domainObject.getCapability('type');
return !!(type && type.hasFeature('creation'));
};
return ObjectHeaderController;
}
);

View File

@@ -0,0 +1,88 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
[],
function () {
var navigationListenerAdded = false;
/**
* Controller to provide the ability to show/hide the tree in
* Browse mode.
* @constructor
* @memberof platform/commonUI/browse
*/
function PaneController($scope, agentService, $window, $location, $attrs, navigationService) {
var self = this;
this.agentService = agentService;
var hideParameterPresent = $location.search().hasOwnProperty($attrs.hideParameter);
if ($attrs.hideParameter && hideParameterPresent) {
this.state = false;
$location.search($attrs.hideParameter, undefined);
} else {
this.state = true;
}
/**
* Callback to invoke when any selection occurs in the tree.
* This controller can be passed in as the `parameters` object
* to the tree representation.
*
* @property {Function} callback
* @memberof platform/commonUI/browse.PaneController#
*/
this.callback = function () {
// Note that, since this is a callback to pass, this is not
// declared as a method but as a property which happens to
// be a function.
if (agentService.isPhone() && agentService.isPortrait()) {
// On phones, trees should collapse in portrait mode
// when something is navigated-to.
self.state = false;
}
};
if (navigationService && navigationService.addListener && !navigationListenerAdded) {
navigationService.addListener(this.callback);
navigationListenerAdded = true;
}
}
/**
* Toggle the visibility of the pane.
*/
PaneController.prototype.toggle = function () {
this.state = !this.state;
};
/**
* Get the desired visibility state of the pane.
* @returns {boolean} true when visible
*/
PaneController.prototype.visible = function () {
return !!this.state;
};
return PaneController;
}
);

View File

@@ -58,7 +58,7 @@ define([], function () {
function checkNavigation() {
var navigatedObject = navigationService.getNavigation();
if (navigatedObject && navigatedObject.hasCapability('context')) {
if (navigatedObject.hasCapability('context')) {
if (!navigatedObject.getCapability('editor').isEditContextRoot()) {
preventOrphanNavigation(navigatedObject);
}

View File

@@ -0,0 +1,64 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* Module defining FullscreenAction. Created by vwoeltje on 11/18/14.
*/
define(
["screenfull"],
function (screenfull) {
var ENTER_FULLSCREEN = "Enter full screen mode",
EXIT_FULLSCREEN = "Exit full screen mode";
/**
* The fullscreen action toggles between fullscreen display
* and regular in-window display.
* @memberof platform/commonUI/browse
* @constructor
* @implements {Action}
*/
function FullscreenAction(context) {
this.context = context;
}
FullscreenAction.prototype.perform = function () {
screenfull.toggle();
};
FullscreenAction.prototype.getMetadata = function () {
// We override getMetadata, because the icon cssClass and
// description need to be determined at run-time
// based on whether or not we are currently
// full screen.
var metadata = Object.create(FullscreenAction);
metadata.cssClass = screenfull.isFullscreen ? "icon-fullscreen-expand" : "icon-fullscreen-collapse";
metadata.description = screenfull.isFullscreen ?
EXIT_FULLSCREEN : ENTER_FULLSCREEN;
metadata.group = "windowing";
metadata.context = this.context;
return metadata;
};
return FullscreenAction;
}
);

View File

@@ -0,0 +1,51 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
[],
function () {
/**
* Updates the title of the current window to reflect the name
* of the currently navigated-to domain object.
* @memberof platform/commonUI/browse
* @constructor
*/
function WindowTitler(navigationService, $rootScope, $document) {
// Look up name of the navigated domain object...
function getNavigatedObjectName() {
var navigatedObject = navigationService.getNavigation();
return navigatedObject && navigatedObject.getModel().name;
}
// Set the window title...
function setTitle(name) {
$document[0].title = name;
}
// Watch the former, and invoke the latter
$rootScope.$watch(getNavigatedObjectName, setTitle);
}
return WindowTitler;
}
);

View File

@@ -0,0 +1,266 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global console*/
/**
* MCTRepresentationSpec. Created by vwoeltje on 11/6/14.
*/
define(
[
"../src/BrowseController",
"../src/navigation/NavigationService"
],
function (
BrowseController,
NavigationService
) {
describe("The browse controller", function () {
var mockScope,
mockRoute,
mockLocation,
mockObjectService,
mockNavigationService,
mockRootObject,
mockUrlService,
mockDefaultRootObject,
mockOtherDomainObject,
mockNextObject,
testDefaultRoot,
controller;
function waitsForNavigation() {
return new Promise(function (resolve) {
mockNavigationService.setNavigation.and.callFake(function (obj) {
var returnValue;
try {
returnValue = NavigationService.prototype.setNavigation.call(mockNavigationService, obj);
} catch (err) {
console.error(err);
//Not rejecting because 'setNavigation' has been called, which is what's being tested here.
//Rejecting will fail tests.
}
resolve();
return returnValue;
});
});
}
function instantiateController() {
controller = new BrowseController(
mockScope,
mockRoute,
mockLocation,
mockObjectService,
mockNavigationService,
mockUrlService,
testDefaultRoot
);
}
beforeEach(function () {
testDefaultRoot = "some-root-level-domain-object";
mockScope = jasmine.createSpyObj(
"$scope",
["$on", "$watch"]
);
mockRoute = { current: { params: {}, pathParams: {} } };
mockUrlService = jasmine.createSpyObj(
"urlService",
["urlForLocation"]
);
mockUrlService.urlForLocation.and.callFake(function (mode, object) {
if (object === mockDefaultRootObject) {
return [mode, testDefaultRoot].join('/');
}
if (object === mockOtherDomainObject) {
return [mode, 'other'].join('/');
}
if (object === mockNextObject) {
return [mode, testDefaultRoot, 'next'].join('/');
}
throw new Error('Tried to get url for unexpected object');
});
mockLocation = jasmine.createSpyObj(
"$location",
["path"]
);
mockObjectService = jasmine.createSpyObj(
"objectService",
["getObjects"]
);
mockNavigationService = new NavigationService({});
[
"getNavigation",
"setNavigation",
"addListener",
"removeListener"
].forEach(function (method) {
spyOn(mockNavigationService, method)
.and.callThrough();
});
mockRootObject = jasmine.createSpyObj(
"rootObjectContainer",
["getId", "getCapability", "getModel", "useCapability", "hasCapability"]
);
mockDefaultRootObject = jasmine.createSpyObj(
"defaultRootObject",
["getId", "getCapability", "getModel", "useCapability", "hasCapability"]
);
mockOtherDomainObject = jasmine.createSpyObj(
"otherDomainObject",
["getId", "getCapability", "getModel", "useCapability", "hasCapability"]
);
mockNextObject = jasmine.createSpyObj(
"nestedDomainObject",
["getId", "getCapability", "getModel", "useCapability", "hasCapability"]
);
mockObjectService.getObjects.and.returnValue(Promise.resolve({
ROOT: mockRootObject
}));
mockRootObject.useCapability.and.returnValue(Promise.resolve([
mockOtherDomainObject,
mockDefaultRootObject
]));
mockRootObject.hasCapability.and.returnValue(true);
mockDefaultRootObject.useCapability.and.returnValue(Promise.resolve([
mockNextObject
]));
mockDefaultRootObject.hasCapability.and.returnValue(true);
mockOtherDomainObject.hasCapability.and.returnValue(false);
mockNextObject.useCapability.and.returnValue(undefined);
mockNextObject.hasCapability.and.returnValue(false);
mockNextObject.getId.and.returnValue("next");
mockDefaultRootObject.getId.and.returnValue(testDefaultRoot);
instantiateController();
return waitsForNavigation();
});
it("uses composition to set the navigated object, if there is none", function () {
instantiateController();
return waitsForNavigation().then(function () {
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject);
});
});
it("navigates to a root-level object, even when default path is not found", function () {
mockDefaultRootObject.getId
.and.returnValue("something-other-than-the-" + testDefaultRoot);
instantiateController();
return waitsForNavigation().then(function () {
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject);
});
});
it("does not try to override navigation", function () {
mockNavigationService.getNavigation.and.returnValue(mockDefaultRootObject);
instantiateController();
return waitsForNavigation().then(function () {
expect(mockScope.navigatedObject).toBe(mockDefaultRootObject);
});
});
it("updates scope when navigated object changes", function () {
// Should have registered a listener - call it
mockNavigationService.addListener.calls.mostRecent().args[0](
mockOtherDomainObject
);
expect(mockScope.navigatedObject).toEqual(mockOtherDomainObject);
});
it("releases its navigation listener when its scope is destroyed", function () {
expect(mockScope.$on).toHaveBeenCalledWith(
"$destroy",
jasmine.any(Function)
);
mockScope.$on.calls.mostRecent().args[1]();
// Should remove the listener it added earlier
expect(mockNavigationService.removeListener).toHaveBeenCalledWith(
mockNavigationService.addListener.calls.mostRecent().args[0]
);
});
it("uses route parameters to choose initially-navigated object", function () {
mockRoute.current.params.ids = testDefaultRoot + "/next";
instantiateController();
return waitsForNavigation().then(function () {
expect(mockScope.navigatedObject).toBe(mockNextObject);
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockNextObject);
});
});
it("handles invalid IDs by going as far as possible", function () {
// Idea here is that if we get a bad path of IDs,
// browse controller should traverse down it until
// it hits an invalid ID.
mockRoute.current.params.ids = testDefaultRoot + "/junk";
instantiateController();
return waitsForNavigation().then(function () {
expect(mockScope.navigatedObject).toBe(mockDefaultRootObject);
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject);
});
});
it("handles compositionless objects by going as far as possible", function () {
// Idea here is that if we get a path which passes
// through an object without a composition, browse controller
// should stop at it since remaining IDs cannot be loaded.
mockRoute.current.params.ids = testDefaultRoot + "/next/junk";
instantiateController();
return waitsForNavigation().then(function () {
expect(mockScope.navigatedObject).toBe(mockNextObject);
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockNextObject);
});
});
it("updates the displayed route to reflect current navigation", function () {
// In order to trigger a route update and not a route change,
// the current route must be updated before location.path is
// called.
expect(mockRoute.current.pathParams.ids)
.not
.toBe(testDefaultRoot + '/next');
mockLocation.path.and.callFake(function () {
expect(mockRoute.current.pathParams.ids)
.toBe(testDefaultRoot + '/next');
});
mockNavigationService.addListener.calls.mostRecent().args[0](
mockNextObject
);
expect(mockLocation.path).toHaveBeenCalledWith(
'/browse/' + testDefaultRoot + '/next'
);
});
});
}
);

View File

@@ -0,0 +1,93 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
["../src/BrowseObjectController"],
function (BrowseObjectController) {
describe("The browse object controller", function () {
var mockScope,
mockLocation,
mockRoute,
controller;
// Utility function; look for a $watch on scope and fire it
function fireWatch(expr, value) {
mockScope.$watch.calls.all().forEach(function (call) {
if (call.args[0] === expr) {
call.args[1](value);
}
});
}
beforeEach(function () {
mockScope = jasmine.createSpyObj(
"$scope",
["$on", "$watch"]
);
mockRoute = { current: { params: {} } };
mockLocation = jasmine.createSpyObj(
"$location",
["path", "search"]
);
mockLocation.search.and.returnValue({});
controller = new BrowseObjectController(
mockScope,
mockLocation,
mockRoute
);
});
it("updates query parameters when selected view changes", function () {
fireWatch("representation.selected.key", "xyz");
expect(mockLocation.search).toHaveBeenCalledWith('view', "xyz");
// Allows the path index to be checked
// prior to setting $route.current
mockLocation.path.and.returnValue("/browse/");
});
it("sets the active view from query parameters", function () {
var mockDomainObject = jasmine.createSpyObj(
"domainObject",
['getId', 'getModel', 'getCapability', 'useCapability']
),
testViews = [
{ key: 'abc' },
{ key: 'def', someKey: 'some value' },
{ key: 'xyz' }
];
mockDomainObject.useCapability.and.callFake(function (c) {
return (c === 'view') && testViews;
});
mockLocation.search.and.returnValue({ view: 'def' });
fireWatch('domainObject', mockDomainObject);
expect(mockScope.representation.selected)
.toEqual(testViews[1]);
});
});
}
);

View File

@@ -0,0 +1,103 @@
/*****************************************************************************
* 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(
["../src/InspectorPaneController"],
function (InspectorPaneController) {
describe("The InspectorPaneController", function () {
var mockScope,
mockAgentService,
mockDomainObject,
mockWindow,
mockStatusCapability,
mockNavigationService,
mockNavigationUnlistener,
mockStatusUnlistener,
controller,
mockLocation,
mockAttrs;
beforeEach(function () {
mockScope = jasmine.createSpyObj("$scope", ["$on"]);
mockWindow = jasmine.createSpyObj("$window", ["open"]);
mockAgentService = jasmine.createSpyObj(
"agentService",
["isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape"]
);
mockNavigationUnlistener = jasmine.createSpy("navigationUnlistener");
mockNavigationService = jasmine.createSpyObj(
"navigationService",
["getNavigation", "addListener"]
);
mockNavigationService.addListener.and.returnValue(mockNavigationUnlistener);
mockStatusUnlistener = jasmine.createSpy("statusUnlistener");
mockStatusCapability = jasmine.createSpyObj(
"statusCapability",
["listen"]
);
mockStatusCapability.listen.and.returnValue(mockStatusUnlistener);
mockDomainObject = jasmine.createSpyObj(
'domainObject',
[
'getId',
'getModel',
'getCapability',
'hasCapability'
]
);
mockDomainObject.getId.and.returnValue("domainObject");
mockDomainObject.getModel.and.returnValue({});
mockDomainObject.hasCapability.and.returnValue(true);
mockDomainObject.getCapability.and.returnValue(mockStatusCapability);
mockLocation = jasmine.createSpyObj('location', ['search']);
mockLocation.search.and.returnValue({});
mockAttrs = {};
controller = new InspectorPaneController(mockScope, mockAgentService, mockWindow, mockNavigationService, mockLocation, mockAttrs);
});
it("listens for changes to navigation and attaches a status" +
" listener", function () {
expect(mockNavigationService.addListener).toHaveBeenCalledWith(jasmine.any(Function));
mockNavigationService.addListener.calls.mostRecent().args[0](mockDomainObject);
expect(mockStatusCapability.listen).toHaveBeenCalledWith(jasmine.any(Function));
});
it("if hidden, shows the inspector when domain object switches to" +
" edit mode", function () {
controller.toggle();
// test pre-condition that inspector is hidden
expect(controller.visible()).toBe(false);
mockNavigationService.addListener.calls.mostRecent().args[0](mockDomainObject);
mockStatusCapability.listen.calls.mostRecent().args[0](["editing"]);
expect(controller.visible()).toBe(true);
});
});
}
);

View File

@@ -0,0 +1,79 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* MenuArrowControllerSpec. Created by shale on 07/02/2015.
*/
define(
["../src/MenuArrowController"],
function (MenuArrowController) {
describe("The menu arrow controller ", function () {
var mockScope,
mockDomainObject,
mockEvent,
mockContextMenuAction,
mockActionContext,
controller;
beforeEach(function () {
mockScope = jasmine.createSpyObj(
"$scope",
[""]
);
mockDomainObject = jasmine.createSpyObj(
"domainObject",
["getCapability"]
);
mockEvent = jasmine.createSpyObj(
"event",
["preventDefault"]
);
mockContextMenuAction = jasmine.createSpyObj(
"action",
["perform", "getActions"]
);
mockActionContext = jasmine.createSpyObj(
"actionContext",
[""]
);
mockActionContext.domainObject = mockDomainObject;
mockActionContext.event = mockEvent;
mockScope.domainObject = mockDomainObject;
mockDomainObject.getCapability.and.returnValue(mockContextMenuAction);
mockContextMenuAction.perform.and.returnValue(jasmine.any(Function));
controller = new MenuArrowController(mockScope);
});
it("calls the context menu action when clicked", function () {
// Simulate a click on the menu arrow
controller.showMenu(mockEvent);
// Expect the menu action to be performed
expect(mockDomainObject.getCapability).toHaveBeenCalledWith('action');
expect(mockContextMenuAction.perform).toHaveBeenCalled();
});
});
}
);

View File

@@ -0,0 +1,137 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
["../src/ObjectHeaderController"],
function (ObjectHeaderController) {
describe("The object header controller", function () {
var mockScope,
mockDomainObject,
mockCapabilities,
mockMutationCapability,
mockTypeCapability,
mockEvent,
mockCurrentTarget,
model,
controller;
beforeEach(function () {
mockMutationCapability = jasmine.createSpyObj("mutation", ["mutate"]);
mockTypeCapability = jasmine.createSpyObj("type", ["typeDef", "hasFeature"]);
mockTypeCapability.typeDef = { name: ""};
mockTypeCapability.hasFeature.and.callFake(function (feature) {
return feature === 'creation';
});
mockCapabilities = {
mutation: mockMutationCapability,
type: mockTypeCapability
};
model = {
name: "Test name"
};
mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "getModel"]);
mockDomainObject.getModel.and.returnValue(model);
mockDomainObject.getCapability.and.callFake(function (key) {
return mockCapabilities[key];
});
mockScope = {
domainObject: mockDomainObject
};
mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "textContent"]);
mockCurrentTarget.blur.and.returnValue(mockCurrentTarget);
mockEvent = {
which: {},
type: {},
currentTarget: mockCurrentTarget
};
controller = new ObjectHeaderController(mockScope);
});
it("updates the model with new name on blur", function () {
mockEvent.type = "blur";
mockCurrentTarget.textContent = "New name";
controller.updateName(mockEvent);
expect(mockMutationCapability.mutate).toHaveBeenCalled();
});
it("updates the model with a default for blank names", function () {
mockEvent.type = "blur";
mockCurrentTarget.textContent = "";
controller.updateName(mockEvent);
expect(mockCurrentTarget.textContent.length).not.toEqual(0);
expect(mockMutationCapability.mutate).toHaveBeenCalled();
});
it("does not update the model if the same name", function () {
mockEvent.type = "blur";
mockCurrentTarget.textContent = mockDomainObject.getModel().name;
controller.updateName(mockEvent);
expect(mockMutationCapability.mutate).not.toHaveBeenCalled();
});
it("updates the model on enter keypress event only", function () {
mockCurrentTarget.textContent = "New name";
controller.updateName(mockEvent);
expect(mockMutationCapability.mutate).not.toHaveBeenCalled();
mockEvent.which = 13;
controller.updateName(mockEvent);
expect(mockMutationCapability.mutate).toHaveBeenCalledWith(jasmine.any(Function));
mockMutationCapability.mutate.calls.mostRecent().args[0](model);
expect(mockDomainObject.getModel().name).toBe("New name");
});
it("blurs the field on enter key press", function () {
mockCurrentTarget.textContent = "New name";
mockEvent.which = 13;
controller.updateName(mockEvent);
expect(mockEvent.currentTarget.blur).toHaveBeenCalled();
});
it("allows editting name when object is creatable", function () {
expect(controller.allowEdit()).toBe(true);
});
it("disallows editting name when object is non-creatable", function () {
mockTypeCapability.hasFeature.and.returnValue(false);
expect(controller.allowEdit()).toBe(false);
});
});
}
);

View File

@@ -0,0 +1,118 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
["../src/PaneController"],
function (PaneController) {
describe("The PaneController", function () {
var mockScope,
mockAgentService,
mockDomainObjects,
mockWindow,
controller,
mockLocation,
mockAttrs;
// We want to reinstantiate for each test case
// because device state can influence constructor-time behavior
function instantiateController() {
return new PaneController(
mockScope,
mockAgentService,
mockWindow,
mockLocation,
mockAttrs
);
}
beforeEach(function () {
mockScope = jasmine.createSpyObj("$scope", ["$on"]);
mockDomainObjects = ['a', 'b'].map(function (id) {
var mockDomainObject = jasmine.createSpyObj(
'domainObject-' + id,
['getId', 'getModel', 'getCapability']
);
mockDomainObject.getId.and.returnValue(id);
mockDomainObject.getModel.and.returnValue({});
return mockDomainObject;
});
mockAgentService = jasmine.createSpyObj(
"agentService",
["isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape"]
);
mockWindow = jasmine.createSpyObj("$window", ["open"]);
mockLocation = jasmine.createSpyObj('location', ['search']);
mockLocation.search.and.returnValue({});
mockAttrs = {};
});
it("is initially visible", function () {
expect(instantiateController().visible()).toBeTruthy();
});
it("allows visibility to be toggled", function () {
controller = instantiateController();
controller.toggle();
expect(controller.visible()).toBeFalsy();
controller.toggle();
expect(controller.visible()).toBeTruthy();
});
it("collapses on navigation changes on portrait-oriented phones", function () {
mockAgentService.isMobile.and.returnValue(true);
mockAgentService.isPhone.and.returnValue(true);
mockAgentService.isPortrait.and.returnValue(true);
controller = instantiateController();
expect(controller.visible()).toBeTruthy();
// Simulate a change from the tree by invoking controller's
controller.callback();
// Tree should have collapsed
expect(controller.visible()).toBeFalsy();
});
describe("specifying hideParameter", function () {
beforeEach(function () {
mockAttrs = {hideParameter: 'hideTree'};
});
it("sets pane state to false when in location.search", function () {
mockLocation.search.and.returnValue({'hideTree': true});
expect(instantiateController().visible()).toBe(false);
expect(mockLocation.search).toHaveBeenCalledWith('hideTree', undefined);
});
it("sets state to true when not found in location.search", function () {
mockLocation.search.and.returnValue({});
expect(instantiateController().visible()).toBe(true);
expect(mockLocation.search).not.toHaveBeenCalledWith('hideTree', undefined);
});
});
});
}
);

View File

@@ -56,7 +56,7 @@ define([
return action.perform()
.then(function () {
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDomainObject, true);
.toHaveBeenCalledWith(mockDomainObject, true);
});
});

Some files were not shown because too many files have changed in this diff Show More