Compare commits

..

10 Commits

403 changed files with 19725 additions and 25582 deletions

View File

@ -5,16 +5,9 @@ module.exports = {
"jasmine": true, "jasmine": true,
"amd": true "amd": true
}, },
"globals": { "extends": "eslint:recommended",
"_": "readonly"
},
"extends": [
"eslint:recommended",
"plugin:vue/recommended"
],
"parser": "vue-eslint-parser",
"parserOptions": {
"parser": "babel-eslint", "parser": "babel-eslint",
"parserOptions": {
"allowImportExportEverywhere": true, "allowImportExportEverywhere": true,
"ecmaVersion": 2015, "ecmaVersion": 2015,
"ecmaFeatures": { "ecmaFeatures": {
@ -65,38 +58,7 @@ module.exports = {
} }
], ],
"dot-notation": "error", "dot-notation": "error",
"indent": ["error", 4], "indent": ["error", 4]
"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": [ "overrides": [
{ {

76
API.md
View File

@ -52,6 +52,7 @@
- [The URL Status Indicator](#the-url-status-indicator) - [The URL Status Indicator](#the-url-status-indicator)
- [Creating a Simple Indicator](#creating-a-simple-indicator) - [Creating a Simple Indicator](#creating-a-simple-indicator)
- [Custom Indicators](#custom-indicators) - [Custom Indicators](#custom-indicators)
- [Included Plugins](#included-plugins)
<!-- END doctoc generated TOC please keep comment here to allow auto update --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->
@ -108,13 +109,15 @@ script loaders are also supported.
<html> <html>
<head> <head>
<title>Open MCT</title> <title>Open MCT</title>
<script src="dist/openmct.js"></script> <script src="openmct.js"></script>
</head> </head>
<body> <body>
<script> <script>
openmct.setAssetPath('openmct/dist');
openmct.install(openmct.plugins.LocalStorage()); openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.MyItems()); openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.UTCTimeSystem()); openmct.install(openmct.plugins.UTCTimeSystem());
openmct.install(openmct.plugins.Espresso());
openmct.start(); openmct.start();
</script> </script>
</body> </body>
@ -125,6 +128,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 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 in the section on [Building from Source](#building-from-source) then these
assets will have been downloaded along with the Open MCT javascript library. 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, There are some plugins bundled with the application that provide UI,
persistence, and other default configuration which are necessary to be able to persistence, and other default configuration which are necessary to be able to
@ -231,7 +237,7 @@ attributes
of this object. This is used for specifying an icon to appear next to each of this object. This is used for specifying an icon to appear next to each
object of this type. 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 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). defining a new object type](https://github.com/nasa/openmct-tutorial#step-3---providing-objects).
@ -423,7 +429,7 @@ attribute | type | flags | notes
###### Value Hints ###### Value Hints
Each telemetry value description has an object defining hints. Keys in this this object represent the hint itself, and the value represents the weight of that hint. A lower weight means the hint has a higher priority. For example, multiple values could be hinted for use as the y-axis of a plot (raw, engineering), but the highest priority would be the default choice. Likewise, a table will use hints to determine the default order of columns. Each telemetry value description has an object defining hints. Keys in this this object represent the hint itself, and the value represents the weight of that hint. A lower weight means the hint has a higher priority. For example, multiple values could be hinted for use as the y axis of a plot (raw, engineering), but the highest priority would be the default choice. Likewise, a table will use hints to determine the default order of columns.
Known hints: Known hints:
@ -505,7 +511,7 @@ example:
} }
``` ```
This strategy says "I want the latest data point in this time range". A provider which recognizes this request should return only one value-- the latest-- in the requested time range. Depending on your back-end implementation, performing these queries in bulk can be a large performance increase. These are generally issued by views that are only capable of displaying a single value and only need to show the latest value. This strategy says "I want the lastest data point in this time range". A provider which recognizes this request should return only one value-- the latest-- in the requested time range. Depending on your back-end implementation, performing these queries in bulk can be a large performance increase. These are generally issued by views that are only capable of displaying a single value and only need to show the latest value.
##### `minmax` request strategy ##### `minmax` request strategy
@ -600,7 +606,7 @@ evaluator, take a look at `examples/generator/SinewaveLimitProvider.js`.
### Telemetry Consumer APIs **draft** ### Telemetry Consumer APIs **draft**
The APIs for requesting telemetry from Open MCT -- e.g. for use in custom views -- are currently in draft state and are being revised. If you'd like to experiment with them before they are finalized, please contact the team via the contact-us link on our website. The APIs for requesting telemetry from Open MCT -- e.g. for use in custom views -- are currently in draft state and are being revised. If you'd like to experiement with them before they are finalized, please contact the team via the contact-us link on our website.
## Time API ## Time API
@ -988,7 +994,7 @@ A common use case for indicators is to convey the state of some external system
persistence backend or HTTP server. So long as this system is accessible via HTTP request, persistence backend or HTTP server. So long as this system is accessible via HTTP request,
Open MCT provides a general purpose indicator to show whether the server is available and Open MCT provides a general purpose indicator to show whether the server is available and
returing a 2xx status code. The URL Status Indicator is made available as a default plugin. See returing a 2xx status code. The URL Status Indicator is made available as a default plugin. See
the [documentation](./src/plugins/URLIndicatorPlugin) for details on how to install and configure the [Included Plugins](#included-plugins) below for details on how to install and configure the
URL Status Indicator. URL Status Indicator.
### Creating a Simple Indicator ### Creating a Simple Indicator
@ -1027,7 +1033,7 @@ different colors to indicate status.
### Custom Indicators ### Custom Indicators
A completely custom indicator can be added by simply providing a DOM element to place alongside other indicators. A completely custom indicator can be added by simple providing a DOM element to place alongside other indicators.
``` javascript ``` javascript
var domNode = document.createElement('div'); var domNode = document.createElement('div');
@ -1040,3 +1046,59 @@ A completely custom indicator can be added by simply providing a DOM element to
element: domNode element: domNode
}); });
``` ```
## Included Plugins
Open MCT is packaged along with a few general-purpose plugins:
* `openmct.plugins.Conductor` provides a user interface for working with time
within the application. If activated, configuration must be provided. This is
detailed in the section on [Time Conductor Configuration](#time-conductor-configuration).
* `openmct.plugins.CouchDB` is an adapter for using CouchDB for persistence
of user-created objects. This is a constructor that takes the URL for the
CouchDB database as a parameter, e.g.
```javascript
openmct.install(openmct.plugins.CouchDB('http://localhost:5984/openmct'))
```
* `openmct.plugins.Elasticsearch` is an adapter for using Elasticsearch for
persistence of user-created objects. This is a
constructor that takes the URL for the Elasticsearch instance as a
parameter. eg.
```javascript
openmct.install(openmct.plugins.CouchDB('http://localhost:9200'))
```
* `openmct.plugins.Espresso` and `openmct.plugins.Snow` are two different
themes (dark and light) available for Open MCT. Note that at least one
of these themes must be installed for Open MCT to appear correctly.
* `openmct.plugins.URLIndicator` adds an indicator which shows the
availability of a URL with the following options:
- `url` : URL to indicate the status of
- `iconClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items)
- `interval`: Interval between checking the connection, defaults to `10000`
- `label` Name showing up as text in the status bar, defaults to url
```javascript
openmct.install(openmct.plugins.URLIndicator({
url: 'http://localhost:8080',
iconClass: 'check',
interval: 10000,
label: 'Localhost'
})
);
```
* `openmct.plugins.LocalStorage` provides persistence of user-created
objects in browser-local storage. This is particularly useful in
development environments.
* `openmct.plugins.MyItems` adds a top-level folder named "My Items"
when the application is first started, providing a place for a
user to store created items.
* `openmct.plugins.UTCTimeSystem` provides a default time system for Open MCT.
Generally, you will want to either install these plugins, or install
different plugins that provide persistence and an initial folder
hierarchy.
eg.
```javascript
openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.MyItems());
```

View File

@ -1,7 +0,0 @@
# Open MCT License
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.
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.

691
LICENSES.md Normal file
View File

@ -0,0 +1,691 @@
# Open MCT Licenses
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 as follows.
## Software Components Licenses
This software includes components released under the following licenses:
---
### SuperSocket
#### Info
* Link: https://supersocket.codeplex.com/
* Version: 0.9.0.2
* Author: Kerry Jiang
* Description: Supports SuperWebSocket
#### License
Copyright 2012 Kerry Jiang (kerry-jiang@hotmail.com)
SuperSocket 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.
---
### SuperWebSocket
#### Info
* Link: https://superswebocket.codeplex.com/
* Version: 0.9.0.2
* Author: Kerry Jiang
* Description: WebSocket implementation for client-server communication
#### License
Copyright 2010-2013 Kerry Jiang (kerry-jiang@hotmail.com)
SuperWebSocket 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.
---
### log4net
#### Info
* Link: http://logging.apache.org/log4net/
* Version: 1.2.13
* Author: Apache Software Foundation
* Description: Logging.
#### License
Copyright © 2004-2015 Apache Software Foundation.
log4net 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.
---
### Blanket.js
#### Info
* Link: http://blanketjs.org/
* Version: 1.1.5
* Author: Alex Seville
* Description: Code coverage measurement and reporting
#### License
Copyright (c) 2013 Alex Seville
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Jasmine
#### Info
* Link: http://jasmine.github.io/
* Version: 1.3.1
* Author: Pivotal Labs
* Description: Unit testing
#### License
Copyright (c) 2008-2011 Pivotal Labs
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### RequireJS
#### Info
* Link: http://requirejs.org/
* Version: 2.1.22
* Author: The Dojo Foundation
* Description: Script loader
#### License
Copyright (c) 2010-2015, The Dojo Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### requirejs-text
#### Info
* Link: https://github.com/requirejs/text
* Version: 2.0.14
* Author: The Dojo Foundation
* Description: Text loading plugin for RequireJS
#### License
Copyright (c) 2010-2014, The Dojo Foundation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
---
### AngularJS
#### Info
* Link: http://angularjs.org/
* Version: 1.4.4
* Author: Google
* Description: Client-side web application framework
#### License
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Angular-Route
#### Info
* Link: http://angularjs.org/
* Version: 1.4.4
* Author: Google
* Description: Client-side view routing
#### License
Copyright (c) 2010-2015 Google, Inc. http://angularjs.org
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### ES6-Promise
#### Info
* Link: https://github.com/jakearchibald/es6-promise
* Version: 3.0.2
* Authors: Yehuda Katz, Tom Dale, Stefan Penner and contributors
* Description: Promise polyfill for pre-ECMAScript 6 browsers
#### License
Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### screenfull.js
#### Info
* Link: https://github.com/sindresorhus/screenfull.js/
* Version: 3.0.0
* Author: Sindre Sorhus
* Description: Wrapper for cross-browser usage of fullscreen API
#### License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Math.uuid.js
#### Info
* Link: https://github.com/broofa/node-uuid
* Version: 1.4.7
* Author: Robert Kieffer
* Description: Unique identifer generation.
#### License
Copyright (c) 2010-2012 Robert Kieffer
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Normalize.css
#### Info
* Link: https://github.com/necolas/normalize.css
* Version: 1.1.2
* Authors: Nicolas Gallagher, Jonathan Neal
* Description: Browser style normalization
#### License
Copyright (c) Nicolas Gallagher and Jonathan Neal
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Moment.js
#### Info
* Link: http://momentjs.com
* Version: 2.11.1
* Authors: Tim Wood, Iskren Chernev, Moment.js contributors
* Description: Time/date parsing/formatting
#### License
Copyright (c) 2011-2014 Tim Wood, Iskren Chernev, Moment.js contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### moment-duration-format
#### Info
* Link: https://github.com/jsmreese/moment-duration-format
* Version: 1.3.0
* Authors: John Madhavan-Reese
* Description: Duration parsing/formatting
#### License
Copyright 2014 John Madhavan-Reese
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### CSV.js
#### Info
* Link: https://github.com/knrz/CSV.js
* Version: 3.6.4
* Authors: Kash Nouroozi
* Description: Encoder for CSV (comma separated values) export
#### License
Copyright (c) 2014 Kash Nouroozi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
---
### FileSaver.js
#### Info
* Link: https://github.com/eligrey/FileSaver.js/
* Version: 0.0.2
* Authors: Eli Grey
* Description: File download initiator (for file exports)
#### License
Copyright © 2015 Eli Grey.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Zepto
#### Info
* Link: http://zeptojs.com/
* Version: 1.1.6
* Authors: Thomas Fuchs
* Description: DOM manipulation
#### License
Copyright (c) 2010-2016 Thomas Fuchs
http://zeptojs.com/
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Json.NET
#### Info
* Link: http://www.newtonsoft.com/json
* Version: 6.0.8
* Author: Newtonsoft
* Description: JSON serialization/deserialization
#### License
Copyright (c) 2007 James Newton-King
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Nancy
#### Info
* Link: http://nancyfx.org
* Version: 0.23.2
* Author: Andreas Håkansson, Steven Robbins and contributors
* Description: Embedded web server
#### License
Copyright © 2010 Andreas Håkansson, Steven Robbins and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Nancy.Hosting.Self
#### Info
* Link: http://nancyfx.org
* Version: 0.23.2
* Author: Andreas Håkansson, Steven Robbins and contributors
* Description: Embedded web server
#### License
Copyright © 2010 Andreas Håkansson, Steven Robbins and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
---
### Almond
* Link: https://github.com/requirejs/almond
* Version: 0.3.3
* Author: jQuery Foundation
* Description: Lightweight RequireJS replacement for builds
#### License
Copyright jQuery Foundation and other contributors, https://jquery.org/
This software consists of voluntary contributions made by many
individuals. For exact contribution history, see the revision history
available at https://github.com/requirejs/almond
The following license applies to all parts of this software except as
documented below:
====
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
====
Copyright and related rights for sample code are waived via CC0. Sample
code is defined as all source code displayed within the prose of the
documentation.
CC0: http://creativecommons.org/publicdomain/zero/1.0/
====
Files located in the node_modules directory, and certain utilities used
to build or test the software in the test and dist directories, are
externally maintained libraries used by this software which have their own
licenses; we recommend you read them, as their terms may differ from the
terms above.
### Lodash
* Link: https://lodash.com
* Version: 3.10.1
* Author: Dojo Foundation
* Description: Utility functions
#### License
Copyright 2012-2015 The Dojo Foundation <http://dojofoundation.org/>
Based on Underscore.js, copyright 2009-2015 Jeremy Ashkenas,
DocumentCloud and Investigative Reporters & Editors <http://underscorejs.org/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
### EventEmitter3
* Link: https://github.com/primus/eventemitter3
* Version: 1.2.0
* Author: Arnout Kazemier
* Description: Event-driven programming support
#### License
The MIT License (MIT)
Copyright (c) 2014 Arnout Kazemier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -9,6 +9,26 @@ Please visit our [Official Site](https://nasa.github.io/openmct/) and [Getting S
Try Open MCT now with our [live demo](https://openmct-demo.herokuapp.com/). Try Open MCT now with our [live demo](https://openmct-demo.herokuapp.com/).
![Demo](https://nasa.github.io/openmct/static/res/images/Open-MCT.Browse.Layout.Mars-Weather-1.jpg) ![Demo](https://nasa.github.io/openmct/static/res/images/Open-MCT.Browse.Layout.Mars-Weather-1.jpg)
## New API
A simpler, [easier-to-use API](https://nasa.github.io/openmct/docs/api/)
has been added to Open MCT. Changes in this
API include a move away from a declarative system of JSON configuration files
towards an imperative system based on function calls. Developers will be able
to extend and build on Open MCT by making direct function calls to a public
API. Open MCT is also being refactored to minimize the dependencies that using
Open MCT imposes on developers, such as the current requirement to use
AngularJS.
This new API has not yet been heavily used and is likely to contain defects.
You can help by trying it out, and reporting any issues you encounter
using our GitHub issue tracker. Such issues may include bugs, suggestions,
missing documentation, or even just requests for help if you're having
trouble.
We want Open MCT to be as easy to use, install, run, and develop for as
possible, and your feedback will help us get there!
## Building and Running Open MCT Locally ## Building and Running Open MCT Locally
Building and running Open MCT in your local dev environment is very easy. Be sure you have [Git](https://git-scm.com/downloads) and [Node.js](https://nodejs.org/) installed, then follow the directions below. Need additional information? Check out the [Getting Started](https://nasa.github.io/openmct/getting-started/) page on our website. Building and running Open MCT in your local dev environment is very easy. Be sure you have [Git](https://git-scm.com/downloads) and [Node.js](https://nodejs.org/) installed, then follow the directions below. Need additional information? Check out the [Getting Started](https://nasa.github.io/openmct/getting-started/) page on our website.
@ -28,14 +48,9 @@ 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 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
Documentation is available on the [Open MCT website](https://nasa.github.io/openmct/documentation/). Documentation is available on the [Open MCT website](https://nasa.github.io/openmct/documentation/). The documentation can also be built locally.
### Examples ### Examples
@ -43,29 +58,48 @@ The clearest examples for developing Open MCT plugins are in the
[tutorials](https://github.com/nasa/openmct-tutorial) provided in [tutorials](https://github.com/nasa/openmct-tutorial) provided in
our documentation. our documentation.
We want Open MCT to be as easy to use, install, run, and develop for as For a practical example of a telemetry adapter, see David Hudson's
possible, and your feedback will help us get there! Feedback can be provided via [GitHub issues](https://github.com/nasa/openmct/issues), or by emailing us at [arc-dl-openmct@mail.nasa.gov](mailto:arc-dl-openmct@mail.nasa.gov). [Kerbal Space Program plugin](https://github.com/hudsonfoo/kerbal-openmct),
which allows [Kerbal Space Program](https://kerbalspaceprogram.com) players
to build and use displays for their own missions in Open MCT.
## Building Applications With Open MCT Additional examples are available in the `examples` hierarchy of this
repository; however, be aware that these examples are
[not fully-documented](https://github.com/nasa/openmct/issues/846), so
the tutorials will likely serve as a better starting point.
Open MCT is built using [`npm`](http://npmjs.com/) and [`webpack`](https://webpack.js.org/). ### Building the Open MCT Documentation Locally
Open MCT's documentation is generated by an
[npm](https://www.npmjs.com/)-based build. It has additional dependencies that
may not be available on every platform and thus is not covered in the standard
npm install. Ensure your system has [libcairo](http://cairographics.org/)
installed and then run the following commands:
See our documentation for a guide on [building Applications with Open MCT](https://github.com/nasa/openmct/blob/master/API.md#starting-an-open-mct-application). * `npm install`
* `npm install canvas nomnoml`
* `npm run docs`
## Plugins Documentation will be generated in `target/docs`.
Open MCT can be extended via plugins that make calls to the Open MCT API. A plugin is a group ## Deploying Open MCT
of software components (including source code and resources such as images and HTML templates)
that is intended to be added or removed as a single unit.
As well as providing an extension mechanism, most of the core Open MCT codebase is also Open MCT is built using [`npm`](http://npmjs.com/)
written as plugins.
For information on writing plugins, please see [our API documentation](https://github.com/nasa/openmct/blob/master/API.md#plugins). To build Open MCT for deployment:
`npm run prepare`
This will compile and minify JavaScript sources, as well as copy over assets.
The contents of the `dist` folder will contain a runnable Open MCT
instance (e.g. by starting an HTTP server in that directory), including:
* `openmct.js` - Open MCT source code.
* `openmct.css` - Basic styles to load to prevent a FOUC.
* `index.html`, an example to run Open MCT in the basic configuration.
## Tests ## Tests
Tests are written for [Jasmine 3](https://jasmine.github.io/api/3.1/global) Tests are written for [Jasmine 3](http://jasmine.github.io/)
and run by [Karma](http://karma-runner.github.io). To run: and run by [Karma](http://karma-runner.github.io). To run:
`npm test` `npm test`
@ -81,7 +115,7 @@ naming convention is otherwise the same.)
### Test Reporting ### Test Reporting
When `npm test` is run, test results will be written as HTML to When `npm test` is run, test results will be written as HTML to
`dist/reports/tests/`. Code coverage information is written to `dist/reports/coverage`. `target/tests`. Code coverage information is written to `target/coverage`.
# Glossary # Glossary
@ -91,8 +125,11 @@ addressed (either by updating this glossary or changing code to reflect
correct usage.) Other developer documentation, particularly in-line correct usage.) Other developer documentation, particularly in-line
documentation, may presume an understanding of these terms. documentation, may presume an understanding of these terms.
* _plugin_: A plugin is a removable, reusable grouping of software elements. * _bundle_: A bundle is a removable, reusable grouping of software elements.
The application is composed of plugins. The application is composed of bundles. Plug-ins are bundles. For more
information, refer to framework documentation (under `platform/framework`.)
* _capability_: An object which exposes dynamic behavior or non-persistent
state associated with a domain object.
* _composition_: In the context of a domain object, this refers to the set of * _composition_: In the context of a domain object, this refers to the set of
other domain objects that compose or are contained by that object. A domain other domain objects that compose or are contained by that object. A domain
object's composition is the set of domain objects that should appear object's composition is the set of domain objects that should appear
@ -107,8 +144,13 @@ documentation, may presume an understanding of these terms.
* _domain object_: A meaningful object to the user; a distinct thing in * _domain object_: A meaningful object to the user; a distinct thing in
the work support by Open MCT. Anything that appears in the left-hand the work support by Open MCT. Anything that appears in the left-hand
tree is a domain object. tree is a domain object.
* _identifier_: A tuple consisting of a namespace and a key, which together uniquely * _extension_: An extension is a unit of functionality exposed to the
identifies a domain object. platform in a declarative fashion by a bundle. For more
information, refer to framework documentation (under `platform/framework`.)
* _id_: A string which uniquely identifies a domain object.
* _key_: When used as an object property, this refers to the machine-readable
identifier for a specific thing in a set of things. (Most often used in the
context of extensions or other similar application-specific object sets.)
* _model_: The persistent state associated with a domain object. A domain * _model_: The persistent state associated with a domain object. A domain
object's model is a JavaScript object which can be converted to JSON object's model is a JavaScript object which can be converted to JSON
without losing information (that is, it contains no methods.) without losing information (that is, it contains no methods.)
@ -120,5 +162,7 @@ documentation, may presume an understanding of these terms.
a user clicks on a domain object in the tree, they are _navigating_ to a user clicks on a domain object in the tree, they are _navigating_ to
it, and it is thereafter considered the _navigated_ object (until the it, and it is thereafter considered the _navigated_ object (until the
user makes another such choice.) user makes another such choice.)
* _namespace_: A name used to identify a persistence store. A running open MCT * _space_: A name used to identify a persistence store. Interactions with
application could potentially use multiple persistence stores, with the persistence will generally involve a `space` parameter in some form, to
distinguish multiple persistence stores from one another (for cases
where there are multiple valid persistence locations available.)

2
app.js
View File

@ -16,7 +16,7 @@ const request = require('request');
// Defaults // Defaults
options.port = options.port || options.p || 8080; options.port = options.port || options.p || 8080;
options.host = options.host || 'localhost'; options.host = options.host || options.h || 'localhost';
options.directory = options.directory || options.D || '.'; options.directory = options.directory || options.D || '.';
// Show command line options // Show command line options

View File

@ -1,5 +1,5 @@
<!-- <!--
Open MCT, Copyright (c) 2014-2020, United States Government Open MCT, Copyright (c) 2014-2018, United States Government
as represented by the Administrator of the National Aeronautics and Space as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved. Administration. All rights reserved.

View File

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government * Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *

View File

@ -33,5 +33,5 @@ As we transition to a new API, the following documentation for the old API
* The [Developer's Guide](guide/) goes into more detail about how to use the * The [Developer's Guide](guide/) goes into more detail about how to use the
platform and the functionality that it provides. platform and the functionality that it provides.
* The [Tutorials](https://github.com/nasa/openmct-tutorial) give examples of extending the platform to add * The [Tutorials](tutorials/) give examples of extending the platform to add
functionality, and integrate with data sources. functionality, and integrate with data sources.

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

3309
docs/src/tutorials/index.md Normal file

File diff suppressed because it is too large Load Diff

View File

@ -22,15 +22,15 @@
/*global define*/ /*global define*/
define([ define([
"./src/EventTelemetryProvider" "./src/EventTelemetryProvider",
'legacyRegistry'
], function ( ], function (
EventTelemetryProvider EventTelemetryProvider,
legacyRegistry
) { ) {
"use strict"; "use strict";
return { legacyRegistry.register("example/eventGenerator", {
name:"example/eventGenerator",
definition: {
"name": "Event Message Generator", "name": "Event Message Generator",
"description": "For development use. Creates sample event message data that mimics a live data stream.", "description": "For development use. Creates sample event message data that mimics a live data stream.",
"extensions": { "extensions": {
@ -76,6 +76,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

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

View File

@ -58,15 +58,15 @@ define([], function () {
row, row,
i; i;
function copyDomainsToRow(telemetryRow, index) { function copyDomainsToRow(row, index) {
domains.forEach(function (domain) { 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) { ranges.forEach(function (range) {
telemetryRow[range.name] = series.getRangeValue(index, range.key); row[range.name] = series.getRangeValue(index, range.key);
}); });
} }

View File

@ -22,13 +22,12 @@
/*global define*/ /*global define*/
define([ define([
'legacyRegistry',
'./ExportTelemetryAsCSVAction' './ExportTelemetryAsCSVAction'
], function (ExportTelemetryAsCSVAction) { ], function (legacyRegistry, ExportTelemetryAsCSVAction) {
"use strict"; "use strict";
return { legacyRegistry.register("example/export", {
name:"example/export",
definition: {
"name": "Example of using CSV Export", "name": "Example of using CSV Export",
"extensions": { "extensions": {
"actions": [ "actions": [
@ -42,6 +41,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -22,15 +22,15 @@
/*global define*/ /*global define*/
define([ define([
"./src/ExampleFormController" "./src/ExampleFormController",
'legacyRegistry'
], function ( ], function (
ExampleFormController ExampleFormController,
legacyRegistry
) { ) {
"use strict"; "use strict";
return { legacyRegistry.register("example/forms", {
name:"example/forms",
definition: {
"name": "Declarative Forms example", "name": "Declarative Forms example",
"sources": "src", "sources": "src",
"extensions": { "extensions": {
@ -49,6 +49,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -9,8 +9,7 @@ define([
values: [ values: [
{ {
key: "name", key: "name",
name: "Name", name: "Name"
format: "string"
}, },
{ {
key: "utc", key: "utc",

View File

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

View File

@ -89,7 +89,7 @@ define([
WorkerInterface.prototype.subscribe = function (request, cb) { WorkerInterface.prototype.subscribe = function (request, cb) {
function callback(message) { function callback(message) {
cb(message.data); cb(message.data);
} };
var messageId = this.dispatch('subscribe', request, callback); var messageId = this.dispatch('subscribe', request, callback);

View File

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

View File

@ -122,17 +122,6 @@ define([
"telemetry", "telemetry",
"phase" "phase"
] ]
},
{
name: "Randomness",
control: "numberfield",
cssClass: "l-input-sm l-numeric",
key: "randomness",
required: true,
property: [
"telemetry",
"randomness"
]
} }
], ],
initialize: function (object) { initialize: function (object) {
@ -141,8 +130,7 @@ define([
amplitude: 1, amplitude: 1,
offset: 0, offset: 0,
dataRateInHz: 1, dataRateInHz: 1,
phase: 0, phase: 0
randomness: 0
}; };
} }
}); });

View File

@ -22,15 +22,15 @@
/*global define*/ /*global define*/
define([ define([
"./src/ExampleIdentityService" "./src/ExampleIdentityService",
'legacyRegistry'
], function ( ], function (
ExampleIdentityService ExampleIdentityService,
legacyRegistry
) { ) {
"use strict"; "use strict";
return { legacyRegistry.register("example/identity", {
name:"example/identity",
definition: {
"extensions": { "extensions": {
"components": [ "components": [
{ {
@ -44,6 +44,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -65,7 +65,7 @@ define([
callback(pointForTimestamp(Date.now(), domainObject.name)); callback(pointForTimestamp(Date.now(), domainObject.name));
}, 5000); }, 5000);
return function () { return function (interval) {
clearInterval(interval); clearInterval(interval);
}; };
} }

View File

@ -21,12 +21,16 @@
*****************************************************************************/ *****************************************************************************/
/*global define*/ /*global define*/
define([], function () { define([
'legacyRegistry'
], function (
legacyRegistry
) {
"use strict"; "use strict";
return { legacyRegistry.register("example/mobile", {
name:"example/mobile",
definition: {
"name": "Mobile", "name": "Mobile",
"description": "Allows elements with pertinence to mobile usage and development", "description": "Allows elements with pertinence to mobile usage and development",
"extensions": { "extensions": {
@ -37,6 +41,5 @@ define([], function () {
} }
] ]
} }
} });
};
}); });

View File

@ -24,16 +24,17 @@
define([ define([
"./src/RemsTelemetryServerAdapter", "./src/RemsTelemetryServerAdapter",
"./src/RemsTelemetryModelProvider", "./src/RemsTelemetryModelProvider",
"./src/RemsTelemetryProvider" "./src/RemsTelemetryProvider",
'legacyRegistry',
"module"
], function ( ], function (
RemsTelemetryServerAdapter, RemsTelemetryServerAdapter,
RemsTelemetryModelProvider, RemsTelemetryModelProvider,
RemsTelemetryProvider RemsTelemetryProvider,
legacyRegistry
) { ) {
"use strict"; "use strict";
return { legacyRegistry.register("example/msl", {
name:"example/msl",
definition: {
"name" : "Mars Science Laboratory Data Adapter", "name" : "Mars Science Laboratory Data Adapter",
"extensions" : { "extensions" : {
"types": [ "types": [
@ -109,7 +110,6 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -27,20 +27,20 @@ define([
"./src/DialogLaunchIndicator", "./src/DialogLaunchIndicator",
"./src/NotificationLaunchIndicator", "./src/NotificationLaunchIndicator",
"./res/dialog-launch.html", "./res/dialog-launch.html",
"./res/notification-launch.html" "./res/notification-launch.html",
'legacyRegistry'
], function ( ], function (
DialogLaunchController, DialogLaunchController,
NotificationLaunchController, NotificationLaunchController,
DialogLaunchIndicator, DialogLaunchIndicator,
NotificationLaunchIndicator, NotificationLaunchIndicator,
DialogLaunch, DialogLaunch,
NotificationLaunch NotificationLaunch,
legacyRegistry
) { ) {
"use strict"; "use strict";
return { legacyRegistry.register("example/notifications", {
name:"example/notifications",
definition: {
"extensions": { "extensions": {
"templates": [ "templates": [
{ {
@ -86,6 +86,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -22,15 +22,15 @@
/*global define*/ /*global define*/
define([ define([
"./src/BrowserPersistenceProvider" "./src/BrowserPersistenceProvider",
'legacyRegistry'
], function ( ], function (
BrowserPersistenceProvider BrowserPersistenceProvider,
legacyRegistry
) { ) {
"use strict"; "use strict";
return { legacyRegistry.register("example/persistence", {
name:"example/persistence",
definition: {
"extensions": { "extensions": {
"components": [ "components": [
{ {
@ -50,6 +50,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

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

View File

@ -23,16 +23,16 @@
define([ define([
"./src/WatchIndicator", "./src/WatchIndicator",
"./src/DigestIndicator" "./src/DigestIndicator",
'legacyRegistry'
], function ( ], function (
WatchIndicator, WatchIndicator,
DigestIndicator DigestIndicator,
legacyRegistry
) { ) {
"use strict"; "use strict";
return { legacyRegistry.register("example/profiling", {
name:"example/profiling",
definition: {
"extensions": { "extensions": {
"indicators": [ "indicators": [
{ {
@ -51,6 +51,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -22,15 +22,15 @@
/*global define*/ /*global define*/
define([ define([
"./src/ScratchPersistenceProvider" "./src/ScratchPersistenceProvider",
'legacyRegistry'
], function ( ], function (
ScratchPersistenceProvider ScratchPersistenceProvider,
legacyRegistry
) { ) {
"use strict"; "use strict";
return { legacyRegistry.register("example/scratchpad", {
name:"example/scratchpad",
definition: {
"extensions": { "extensions": {
"roots": [ "roots": [
{ {
@ -59,6 +59,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -3,6 +3,8 @@ import HelloWorld from './HelloWorld.vue';
function SimpleVuePlugin () { function SimpleVuePlugin () {
return function install(openmct) { return function install(openmct) {
var views = (openmct.mainViews || openmct.objectViews);
openmct.types.addType('hello-world', { openmct.types.addType('hello-world', {
name: 'Hello World', name: 'Hello World',
description: 'An introduction object', description: 'An introduction object',

View File

@ -8,7 +8,8 @@ define([
"./res/templates/glyphs.html", "./res/templates/glyphs.html",
"./res/templates/controls.html", "./res/templates/controls.html",
"./res/templates/input.html", "./res/templates/input.html",
"./res/templates/menus.html" "./res/templates/menus.html",
'legacyRegistry'
], function ( ], function (
ExampleStyleGuideModelProvider, ExampleStyleGuideModelProvider,
MCTExample, MCTExample,
@ -19,11 +20,10 @@ define([
glyphsTemplate, glyphsTemplate,
controlsTemplate, controlsTemplate,
inputTemplate, inputTemplate,
menusTemplate menusTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("example/styleguide", {
name:"example/styleguide",
definition: {
"name": "Open MCT Style Guide", "name": "Open MCT Style Guide",
"description": "Examples and documentation illustrating UI styles in use in Open MCT.", "description": "Examples and documentation illustrating UI styles in use in Open MCT.",
"extensions": "extensions":
@ -103,6 +103,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

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

View File

@ -38,12 +38,11 @@
const THIRTY_MINUTES = 30 * 60 * 1000; const THIRTY_MINUTES = 30 * 60 * 1000;
[ [
'example/eventGenerator' 'example/eventGenerator',
'example/styleguide'
].forEach( ].forEach(
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry) openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
); );
openmct.install(openmct.plugins.Espresso());
openmct.install(openmct.plugins.MyItems()); openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.LocalStorage()); openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.Generator()); openmct.install(openmct.plugins.Generator());

View File

@ -1,6 +1,6 @@
{ {
"name": "openmct", "name": "openmct",
"version": "1.0.0-snapshot", "version": "1.0.0-beta",
"description": "The Open MCT core platform", "description": "The Open MCT core platform",
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
@ -11,7 +11,6 @@
"comma-separated-values": "^3.6.4", "comma-separated-values": "^3.6.4",
"concurrently": "^3.6.1", "concurrently": "^3.6.1",
"copy-webpack-plugin": "^4.5.2", "copy-webpack-plugin": "^4.5.2",
"cross-env": "^6.0.3",
"css-loader": "^1.0.0", "css-loader": "^1.0.0",
"d3-array": "1.2.x", "d3-array": "1.2.x",
"d3-axis": "1.0.x", "d3-axis": "1.0.x",
@ -24,7 +23,6 @@
"d3-time": "1.0.x", "d3-time": "1.0.x",
"d3-time-format": "2.1.x", "d3-time-format": "2.1.x",
"eslint": "5.2.0", "eslint": "5.2.0",
"eslint-plugin-vue": "^6.0.0",
"eventemitter3": "^1.2.0", "eventemitter3": "^1.2.0",
"exports-loader": "^0.7.0", "exports-loader": "^0.7.0",
"express": "^4.13.1", "express": "^4.13.1",
@ -63,8 +61,7 @@
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"request": "^2.69.0", "request": "^2.69.0",
"split": "^1.0.0", "split": "^1.0.0",
"style-loader": "^1.0.1", "style-loader": "^0.21.0",
"uuid": "^3.3.3",
"v8-compile-cache": "^1.1.0", "v8-compile-cache": "^1.1.0",
"vue": "2.5.6", "vue": "2.5.6",
"vue-loader": "^15.2.6", "vue-loader": "^15.2.6",
@ -77,13 +74,13 @@
}, },
"scripts": { "scripts": {
"start": "node app.js", "start": "node app.js",
"lint": "eslint platform example src/**/*.{js,vue} openmct.js", "lint": "eslint platform src openmct.js",
"lint:fix": "eslint platform example src/**/*.{js,vue} openmct.js --fix", "lint:fix": "eslint platform src openmct.js --fix",
"build:prod": "cross-env NODE_ENV=production webpack", "build:prod": "NODE_ENV=production webpack",
"build:dev": "webpack", "build:dev": "webpack",
"build:watch": "webpack --watch", "build:watch": "webpack --watch",
"test": "karma start --single-run", "test": "karma start --single-run",
"test-debug": "cross-env NODE_ENV=debug karma start --no-single-run", "test-debug": "NODE_ENV=debug karma start --no-single-run",
"test:watch": "karma start --no-single-run", "test:watch": "karma start --no-single-run",
"verify": "concurrently 'npm:test' 'npm:lint'", "verify": "concurrently 'npm:test' 'npm:lint'",
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api", "jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",

View File

@ -31,7 +31,8 @@ define([
"./res/templates/license-apache.html", "./res/templates/license-apache.html",
"./res/templates/license-mit.html", "./res/templates/license-mit.html",
"./res/templates/licenses.html", "./res/templates/licenses.html",
"./res/templates/licenses-export-md.html" "./res/templates/licenses-export-md.html",
'legacyRegistry'
], function ( ], function (
aboutDialogTemplate, aboutDialogTemplate,
LogoController, LogoController,
@ -43,12 +44,11 @@ define([
licenseApacheTemplate, licenseApacheTemplate,
licenseMitTemplate, licenseMitTemplate,
licensesTemplate, licensesTemplate,
licensesExportMdTemplate licensesExportMdTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/about", {
name:"platform/commonUI/about",
definition: {
"name": "About Open MCT", "name": "About Open MCT",
"extensions": { "extensions": {
"templates": [ "templates": [
@ -176,6 +176,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -32,7 +32,8 @@ define([
"./res/templates/menu-arrow.html", "./res/templates/menu-arrow.html",
"./res/templates/back-arrow.html", "./res/templates/back-arrow.html",
"./res/templates/browse/object-properties.html", "./res/templates/browse/object-properties.html",
"./res/templates/browse/inspector-region.html" "./res/templates/browse/inspector-region.html",
'legacyRegistry'
], function ( ], function (
NavigationService, NavigationService,
NavigateAction, NavigateAction,
@ -45,12 +46,11 @@ define([
menuArrowTemplate, menuArrowTemplate,
backArrowTemplate, backArrowTemplate,
objectPropertiesTemplate, objectPropertiesTemplate,
inspectorRegionTemplate inspectorRegionTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/browse", {
name:"platform/commonUI/browse",
definition: {
"extensions": { "extensions": {
"routes": [ "routes": [
], ],
@ -172,6 +172,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -30,7 +30,8 @@ define([
"./res/templates/message.html", "./res/templates/message.html",
"./res/templates/notification-message.html", "./res/templates/notification-message.html",
"./res/templates/overlay-message-list.html", "./res/templates/overlay-message-list.html",
"./res/templates/overlay.html" "./res/templates/overlay.html",
'legacyRegistry'
], function ( ], function (
DialogService, DialogService,
OverlayService, OverlayService,
@ -41,12 +42,11 @@ define([
messageTemplate, messageTemplate,
notificationMessageTemplate, notificationMessageTemplate,
overlayMessageListTemplate, overlayMessageListTemplate,
overlayTemplate overlayTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/dialog", {
name:"platform/commonUI/dialog",
definition: {
"extensions": { "extensions": {
"services": [ "services": [
{ {
@ -107,6 +107,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -48,7 +48,8 @@ define([
"./res/templates/library.html", "./res/templates/library.html",
"./res/templates/edit-object.html", "./res/templates/edit-object.html",
"./res/templates/edit-action-buttons.html", "./res/templates/edit-action-buttons.html",
"./res/templates/topbar-edit.html" "./res/templates/topbar-edit.html",
'legacyRegistry'
], function ( ], function (
EditActionController, EditActionController,
EditPanesController, EditPanesController,
@ -77,11 +78,11 @@ define([
libraryTemplate, libraryTemplate,
editObjectTemplate, editObjectTemplate,
editActionButtonsTemplate, editActionButtonsTemplate,
topbarEditTemplate topbarEditTemplate,
legacyRegistry
) { ) {
return {
name: "platform/commonUI/edit", legacyRegistry.register("platform/commonUI/edit", {
definition: {
"extensions": { "extensions": {
"controllers": [ "controllers": [
{ {
@ -348,6 +349,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -6,7 +6,7 @@ define([], function () {
SaveInProgressDialog.prototype.show = function () { SaveInProgressDialog.prototype.show = function () {
this.dialog = this.dialogService.showBlockingMessage({ this.dialog = this.dialogService.showBlockingMessage({
title: "Saving", title: "Saving...",
hint: "Do not navigate away from this page or close this browser tab while this message is displayed.", hint: "Do not navigate away from this page or close this browser tab while this message is displayed.",
unknownProgress: true, unknownProgress: true,
severity: "info", severity: "info",

View File

@ -23,16 +23,16 @@
define([ define([
"./src/FormatProvider", "./src/FormatProvider",
"./src/UTCTimeFormat", "./src/UTCTimeFormat",
"./src/DurationFormat" "./src/DurationFormat",
'legacyRegistry'
], function ( ], function (
FormatProvider, FormatProvider,
UTCTimeFormat, UTCTimeFormat,
DurationFormat DurationFormat,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/formats", {
name:"platform/commonUI/formats",
definition: {
"name": "Format Registry", "name": "Format Registry",
"description": "Provides a registry for formats, which allow parsing and formatting of values.", "description": "Provides a registry for formats, which allow parsing and formatting of values.",
"extensions": { "extensions": {
@ -74,6 +74,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -66,7 +66,8 @@ define([
"./res/templates/object-inspector.html", "./res/templates/object-inspector.html",
"./res/templates/controls/selector.html", "./res/templates/controls/selector.html",
"./res/templates/controls/datetime-picker.html", "./res/templates/controls/datetime-picker.html",
"./res/templates/controls/datetime-field.html" "./res/templates/controls/datetime-field.html",
'legacyRegistry'
], function ( ], function (
UrlService, UrlService,
PopupService, PopupService,
@ -113,12 +114,11 @@ define([
objectInspectorTemplate, objectInspectorTemplate,
selectorTemplate, selectorTemplate,
datetimePickerTemplate, datetimePickerTemplate,
datetimeFieldTemplate datetimeFieldTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/general", {
name:"platform/commonUI/general",
definition: {
"name": "General UI elements", "name": "General UI elements",
"description": "General UI elements, meant to be reused across modes", "description": "General UI elements, meant to be reused across modes",
"resources": "res", "resources": "res",
@ -524,6 +524,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -27,7 +27,8 @@ define([
"./res/info-table.html", "./res/info-table.html",
"./res/info-bubble.html", "./res/info-bubble.html",
"./res/bubble.html", "./res/bubble.html",
"./res/templates/info-button.html" "./res/templates/info-button.html",
'legacyRegistry'
], function ( ], function (
InfoGesture, InfoGesture,
InfoButtonGesture, InfoButtonGesture,
@ -35,12 +36,11 @@ define([
infoTableTemplate, infoTableTemplate,
infoBubbleTemplate, infoBubbleTemplate,
bubbleTemplate, bubbleTemplate,
infoButtonTemplate infoButtonTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/inspect", {
name:"platform/commonUI/inspect",
definition: {
"extensions": { "extensions": {
"templates": [ "templates": [
{ {
@ -112,6 +112,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -23,16 +23,16 @@
define([ define([
"./src/MCTDevice", "./src/MCTDevice",
"./src/AgentService", "./src/AgentService",
"./src/DeviceClassifier" "./src/DeviceClassifier",
'legacyRegistry'
], function ( ], function (
MCTDevice, MCTDevice,
AgentService, AgentService,
DeviceClassifier DeviceClassifier,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/mobile", {
name:"platform/commonUI/mobile",
definition: {
"extensions": { "extensions": {
"directives": [ "directives": [
{ {
@ -62,6 +62,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -24,17 +24,17 @@ define([
"./src/NotificationIndicatorController", "./src/NotificationIndicatorController",
"./src/NotificationIndicator", "./src/NotificationIndicator",
"./src/NotificationService", "./src/NotificationService",
"./res/notification-indicator.html" "./res/notification-indicator.html",
'legacyRegistry'
], function ( ], function (
NotificationIndicatorController, NotificationIndicatorController,
NotificationIndicator, NotificationIndicator,
NotificationService, NotificationService,
notificationIndicatorTemplate notificationIndicatorTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/notification", {
name:"platform/commonUI/notification",
definition: {
"extensions": { "extensions": {
"templates": [ "templates": [
{ {
@ -71,6 +71,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -22,15 +22,15 @@
define([ define([
'./src/InspectorController', './src/InspectorController',
'./src/EditableRegionPolicy' './src/EditableRegionPolicy',
'legacyRegistry'
], function ( ], function (
InspectorController, InspectorController,
EditableRegionPolicy EditableRegionPolicy,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/commonUI/regions", {
name:"platform/commonUI/regions",
definition: {
"extensions": { "extensions": {
"controllers": [ "controllers": [
{ {
@ -50,6 +50,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -25,18 +25,18 @@ define([
"./src/CompositionMutabilityPolicy", "./src/CompositionMutabilityPolicy",
"./src/CompositionModelPolicy", "./src/CompositionModelPolicy",
"./src/ComposeActionPolicy", "./src/ComposeActionPolicy",
"./src/PersistableCompositionPolicy" "./src/PersistableCompositionPolicy",
'legacyRegistry'
], function ( ], function (
CompositionPolicy, CompositionPolicy,
CompositionMutabilityPolicy, CompositionMutabilityPolicy,
CompositionModelPolicy, CompositionModelPolicy,
ComposeActionPolicy, ComposeActionPolicy,
PersistableCompositionPolicy PersistableCompositionPolicy,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/containment", {
name:"platform/containment",
definition: {
"extensions": { "extensions": {
"policies": [ "policies": [
{ {
@ -71,6 +71,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -49,7 +49,8 @@ define([
"./src/services/Now", "./src/services/Now",
"./src/services/Throttle", "./src/services/Throttle",
"./src/services/Topic", "./src/services/Topic",
"./src/services/Instantiate" "./src/services/Instantiate",
'legacyRegistry'
], function ( ], function (
DomainObjectProvider, DomainObjectProvider,
CoreCapabilityProvider, CoreCapabilityProvider,
@ -79,12 +80,11 @@ define([
Now, Now,
Throttle, Throttle,
Topic, Topic,
Instantiate Instantiate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/core", {
name:"platform/core",
definition: {
"name": "Open MCT Core", "name": "Open MCT Core",
"description": "Defines core concepts of Open MCT.", "description": "Defines core concepts of Open MCT.",
"sources": "src", "sources": "src",
@ -387,6 +387,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -102,14 +102,14 @@ define(
* @returns {Action[]} an array of matching actions * @returns {Action[]} an array of matching actions
* @memberof platform/core.ActionCapability# * @memberof platform/core.ActionCapability#
*/ */
ActionCapability.prototype.perform = function (context, flag) { ActionCapability.prototype.perform = function (context) {
// Alias to getActions(context)[0].perform, with a // Alias to getActions(context)[0].perform, with a
// check for empty arrays. // check for empty arrays.
var actions = this.getActions(context); var actions = this.getActions(context);
return this.$q.when( return this.$q.when(
(actions && actions.length > 0) ? (actions && actions.length > 0) ?
actions[0].perform(flag) : actions[0].perform() :
undefined undefined
); );
}; };

View File

@ -34,7 +34,8 @@ define([
"./src/services/MoveService", "./src/services/MoveService",
"./src/services/LinkService", "./src/services/LinkService",
"./src/services/CopyService", "./src/services/CopyService",
"./src/services/LocationService" "./src/services/LocationService",
'legacyRegistry'
], function ( ], function (
MoveAction, MoveAction,
CopyAction, CopyAction,
@ -49,12 +50,11 @@ define([
MoveService, MoveService,
LinkService, LinkService,
CopyService, CopyService,
LocationService LocationService,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/entanglement", {
name:"platform/entanglement",
definition: {
"name": "Entanglement", "name": "Entanglement",
"description": "Tools to assist you in entangling the world of WARP.", "description": "Tools to assist you in entangling the world of WARP.",
"configuration": {}, "configuration": {},
@ -197,6 +197,5 @@ define([
], ],
"licenses": [] "licenses": []
} }
} });
};
}); });

View File

@ -91,7 +91,7 @@ define(
.then(function () { .then(function () {
return object return object
.getCapability('action') .getCapability('action')
.perform('remove', true); .perform('remove');
}); });
}; };

View File

@ -227,11 +227,10 @@ define(
locationPromise.resolve(); locationPromise.resolve();
}); });
it("removes object from parent without user warning dialog", function () { it("removes object from parent", function () {
expect(actionCapability.perform) expect(actionCapability.perform)
.toHaveBeenCalledWith('remove', true); .toHaveBeenCalledWith('remove');
}); });
}); });
}); });
@ -248,9 +247,9 @@ define(
.toHaveBeenCalled(); .toHaveBeenCalled();
}); });
it("removes object from parent without user warning dialog", function () { it("removes object from parent", function () {
expect(actionCapability.perform) expect(actionCapability.perform)
.toHaveBeenCalledWith('remove', true); .toHaveBeenCalledWith('remove');
}); });
}); });

View File

@ -21,14 +21,14 @@
*****************************************************************************/ *****************************************************************************/
define([ define([
"./src/WorkerService" "./src/WorkerService",
'legacyRegistry'
], function ( ], function (
WorkerService WorkerService,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/execution", {
name:"platform/execution",
definition: {
"extensions": { "extensions": {
"services": [ "services": [
{ {
@ -41,6 +41,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -22,12 +22,11 @@
define([ define([
"./ExportService", "./ExportService",
"saveAs" "saveAs",
], function (ExportService, saveAs) { "legacyRegistry"
], function (ExportService, saveAs, legacyRegistry) {
return { legacyRegistry.register("platform/exporters", {
name:"platform/exporters",
definition: {
extensions: { extensions: {
services: [ services: [
{ {
@ -60,6 +59,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -35,7 +35,8 @@ define([
"./src/actions/StopTimerAction", "./src/actions/StopTimerAction",
"./src/actions/PauseTimerAction", "./src/actions/PauseTimerAction",
"./res/templates/clock.html", "./res/templates/clock.html",
"./res/templates/timer.html" "./res/templates/timer.html",
'legacyRegistry'
], function ( ], function (
MomentTimezone, MomentTimezone,
ClockIndicator, ClockIndicator,
@ -51,11 +52,10 @@ define([
StopTimerAction, StopTimerAction,
PauseTimerAction, PauseTimerAction,
clockTemplate, clockTemplate,
timerTemplate timerTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/features/clock", {
name:"platform/features/clock",
definition: {
"name": "Clocks/Timers", "name": "Clocks/Timers",
"descriptions": "Domain objects for displaying current & relative times.", "descriptions": "Domain objects for displaying current & relative times.",
"configuration": { "configuration": {
@ -316,6 +316,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -22,14 +22,14 @@
define([ define([
'./src/HyperlinkController', './src/HyperlinkController',
'legacyRegistry',
'./res/templates/hyperlink.html' './res/templates/hyperlink.html'
], function ( ], function (
HyperlinkController, HyperlinkController,
legacyRegistry,
hyperlinkTemplate hyperlinkTemplate
) { ) {
return { legacyRegistry.register("platform/features/hyperlink", {
name:"platform/features/hyperlink",
definition: {
"name": "Hyperlink", "name": "Hyperlink",
"description": "Insert a hyperlink to reference a link", "description": "Insert a hyperlink to reference a link",
"extensions": { "extensions": {
@ -115,6 +115,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -0,0 +1,85 @@
/*****************************************************************************
* 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/policies/ImageryViewPolicy",
"./src/controllers/ImageryController",
"./src/directives/MCTBackgroundImage",
"./res/templates/imagery.html",
'legacyRegistry'
], function (
ImageryViewPolicy,
ImageryController,
MCTBackgroundImage,
imageryTemplate,
legacyRegistry
) {
legacyRegistry.register("platform/features/imagery", {
"name": "Plot view for telemetry",
"extensions": {
"views": [
{
"name": "Imagery",
"key": "imagery",
"cssClass": "icon-image",
"template": imageryTemplate,
"priority": "preferred",
"needs": [
"telemetry"
],
"editable": false
}
],
"policies": [
{
"category": "view",
"implementation": ImageryViewPolicy,
"depends": [
"openmct"
]
}
],
"controllers": [
{
"key": "ImageryController",
"implementation": ImageryController,
"depends": [
"$scope",
"$window",
"$element",
"openmct"
]
}
],
"directives": [
{
"key": "mctBackgroundImage",
"implementation": MCTBackgroundImage,
"depends": [
"$document"
]
}
]
}
});
});

View File

@ -0,0 +1,58 @@
<div class="t-imagery c-imagery" ng-controller="ImageryController as imagery">
<mct-split-pane class='abs' anchor="bottom" alias="imagery">
<div class="split-pane-component has-local-controls l-image-main-wrapper l-flex-col">
<div class="h-local-controls h-local-controls--overlay-content c-local-controls--show-on-hover l-flex-row c-imagery__lc">
<span class="holder flex-elem grows c-imagery__lc__sliders">
<input class="icon-brightness" type="range"
min="0"
max="500"
ng-model="filters.brightness" />
<input class="icon-contrast" type="range"
min="0"
max="500"
ng-model="filters.contrast" />
</span>
<span class="holder flex-elem t-reset-btn-holder c-imagery__lc__reset-btn">
<a class="s-icon-button icon-reset t-btn-reset"
ng-click="filters = { brightness: 100, contrast: 100 }"></a>
</span>
</div>
<div class="l-image-main s-image-main flex-elem grows"
ng-class="{ paused: imagery.paused(), stale:false }">
<div class="image-main"
mct-background-image="imagery.getImageUrl()"
filters="filters">
</div>
</div>
<div class="l-image-main-controlbar flex-elem l-flex-row">
<div class="l-datetime-w flex-elem grows">
<a class="c-button show-thumbs sm hidden icon-thumbs-strip"
ng-click="showThumbsBubble = (showThumbsBubble) ? false:true"></a>
<span class="l-time">{{imagery.getTime()}}</span>
</div>
<div class="h-local-controls flex-elem">
<a class="c-button icon-pause pause-play"
ng-click="imagery.paused(!imagery.paused())"
ng-class="{ 'is-paused': imagery.paused() }"></a>
<a href=""
class="s-button l-mag s-mag vsm icon-reset"
ng-click="clipped = false"
ng-show="clipped === true"
title="Not all of image is visible; click to reset."></a>
</div>
</div>
</div>
<mct-splitter></mct-splitter>
<div class="split-pane-component l-image-thumbs-wrapper">
<div class="l-image-thumb-item" ng-class="{selected: image.selected}" ng-repeat="image in imageHistory track by $index"
ng-click="imagery.setSelectedImage(image)" ng-init="imagery.scrollToBottom()">
<img class="l-thumb"
ng-src={{imagery.getImageUrl(image)}}>
<div class="l-time">{{imagery.getTime(image)}}</div>
</div>
</div>
</mct-split-pane>
</div>

View File

@ -0,0 +1,284 @@
/*****************************************************************************
* 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 views of image telemetry.
* @namespace platform/features/imagery
*/
define(
[
'zepto',
'lodash'
],
function ($, _) {
/**
* Controller for the "Imagery" view of a domain object which
* provides image telemetry.
* @constructor
* @memberof platform/features/imagery
*/
function ImageryController($scope, $window, element, openmct) {
this.$scope = $scope;
this.$window = $window;
this.openmct = openmct;
this.date = "";
this.time = "";
this.zone = "";
this.imageUrl = "";
this.requestCount = 0;
this.scrollable = $(".l-image-thumbs-wrapper");
this.autoScroll = openmct.time.clock() ? true : false;
this.$scope.imageHistory = [];
this.$scope.filters = {
brightness: 100,
contrast: 100
};
this.subscribe = this.subscribe.bind(this);
this.stopListening = this.stopListening.bind(this);
this.updateValues = this.updateValues.bind(this);
this.updateHistory = this.updateHistory.bind(this);
this.onBoundsChange = this.onBoundsChange.bind(this);
this.onScroll = this.onScroll.bind(this);
this.setSelectedImage = this.setSelectedImage.bind(this);
this.subscribe(this.$scope.domainObject);
this.$scope.$on('$destroy', this.stopListening);
this.openmct.time.on('bounds', this.onBoundsChange);
this.scrollable.on('scroll', this.onScroll);
}
ImageryController.prototype.subscribe = function (domainObject) {
this.date = "";
this.imageUrl = "";
this.openmct.objects.get(domainObject.getId())
.then(function (object) {
this.domainObject = object;
var metadata = this.openmct
.telemetry
.getMetadata(this.domainObject);
this.timeKey = this.openmct.time.timeSystem().key;
this.timeFormat = this.openmct
.telemetry
.getValueFormatter(metadata.value(this.timeKey));
this.imageFormat = this.openmct
.telemetry
.getValueFormatter(metadata.valuesForHints(['image'])[0]);
this.unsubscribe = this.openmct.telemetry
.subscribe(this.domainObject, function (datum) {
this.updateHistory(datum);
this.updateValues(datum);
}.bind(this));
this.requestHistory(this.openmct.time.bounds());
}.bind(this));
};
ImageryController.prototype.requestHistory = function (bounds) {
this.requestCount++;
this.$scope.imageHistory = [];
var requestId = this.requestCount;
this.openmct.telemetry
.request(this.domainObject, bounds)
.then(function (values) {
if (this.requestCount > requestId) {
return Promise.resolve('Stale request');
}
values.forEach(function (datum) {
this.updateHistory(datum);
}, this);
this.updateValues(values[values.length - 1]);
}.bind(this));
};
ImageryController.prototype.stopListening = function () {
this.openmct.time.off('bounds', this.onBoundsChange);
this.scrollable.off('scroll', this.onScroll);
if (this.unsubscribe) {
this.unsubscribe();
delete this.unsubscribe;
}
};
/**
* Responds to bound change event be requesting new
* historical data if the bound change was manual.
* @private
* @param {object} [newBounds] new bounds object
* @param {boolean} [tick] true when change is automatic
*/
ImageryController.prototype.onBoundsChange = function (newBounds, tick) {
if (this.domainObject && !tick) {
this.requestHistory(newBounds);
}
};
/**
* Updates displayable values to match those of the most
* recently received datum.
* @param {object} [datum] the datum
* @private
*/
ImageryController.prototype.updateValues = function (datum) {
if (this.isPaused) {
this.nextDatum = datum;
return;
}
this.time = this.timeFormat.format(datum);
this.imageUrl = this.imageFormat.format(datum);
};
/**
* Appends given imagery datum to running history.
* @private
* @param {object} [datum] target telemetry datum
* @returns {boolean} falsy when a duplicate datum is given
*/
ImageryController.prototype.updateHistory = function (datum) {
if (!this.datumMatchesMostRecent(datum)) {
var index = _.sortedIndex(this.$scope.imageHistory, datum, this.timeFormat.format.bind(this.timeFormat));
this.$scope.imageHistory.splice(index, 0, datum);
return true;
} else {
return false;
}
};
/**
* Checks to see if the given datum is the same as the most recent in history.
* @private
* @param {object} [datum] target telemetry datum
* @returns {boolean} true if datum is most recent in history, false otherwise
*/
ImageryController.prototype.datumMatchesMostRecent = function (datum) {
if (this.$scope.imageHistory.length !== 0) {
var datumTime = this.timeFormat.format(datum);
var datumURL = this.imageFormat.format(datum);
var lastHistoryTime = this.timeFormat.format(this.$scope.imageHistory.slice(-1)[0]);
var lastHistoryURL = this.imageFormat.format(this.$scope.imageHistory.slice(-1)[0]);
return datumTime === lastHistoryTime && datumURL === lastHistoryURL;
}
return false;
};
ImageryController.prototype.onScroll = function (event) {
this.$window.requestAnimationFrame(function () {
var thumbnailWrapperHeight = this.scrollable[0].offsetHeight;
var thumbnailWrapperWidth = this.scrollable[0].offsetWidth;
if (this.scrollable[0].scrollLeft <
(this.scrollable[0].scrollWidth - this.scrollable[0].clientWidth) - (thumbnailWrapperWidth) ||
this.scrollable[0].scrollTop <
(this.scrollable[0].scrollHeight - this.scrollable[0].clientHeight) - (thumbnailWrapperHeight)) {
this.autoScroll = false;
} else {
this.autoScroll = true;
}
}.bind(this));
};
/**
* Force history imagery div to scroll to bottom.
*/
ImageryController.prototype.scrollToBottom = function () {
if (this.autoScroll) {
this.scrollable[0].scrollTop = this.scrollable[0].scrollHeight;
}
};
/**
* Get the time portion (hours, minutes, seconds) of the
* timestamp associated with the incoming image telemetry
* if no parameter is given, or of a provided datum.
* @param {object} [datum] target telemetry datum
* @returns {string} the time
*/
ImageryController.prototype.getTime = function (datum) {
return datum ?
this.timeFormat.format(datum) :
this.time;
};
/**
* Get the URL of the most recent image telemetry if no
* parameter is given, or of a provided datum.
* @param {object} [datum] target telemetry datum
* @returns {string} URL for telemetry image
*/
ImageryController.prototype.getImageUrl = function (datum) {
return datum ?
this.imageFormat.format(datum) :
this.imageUrl;
};
/**
* Getter-setter for paused state of the view (true means
* paused, false means not.)
* @param {boolean} [state] the state to set
* @returns {boolean} the current state
*/
ImageryController.prototype.paused = function (state) {
if (arguments.length > 0 && state !== this.isPaused) {
this.unselectAllImages();
this.isPaused = state;
if (this.nextDatum) {
this.updateValues(this.nextDatum);
delete this.nextDatum;
} else {
this.updateValues(this.$scope.imageHistory[this.$scope.imageHistory.length - 1]);
}
this.autoScroll = true;
}
return this.isPaused;
};
/**
* Set the selected image on the state for the large imagery div to use.
* @param {object} [image] the image object to get url from.
*/
ImageryController.prototype.setSelectedImage = function (image) {
this.imageUrl = this.getImageUrl(image);
this.time = this.getTime(image);
this.paused(true);
this.unselectAllImages();
image.selected = true;
};
/**
* Loop through the history imagery data to set all images to unselected.
*/
ImageryController.prototype.unselectAllImages = function () {
for (var i = 0; i < this.$scope.imageHistory.length; i++) {
this.$scope.imageHistory[i].selected = false;
}
};
return ImageryController;
}
);

View File

@ -0,0 +1,110 @@
/*****************************************************************************
* 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 () {
/**
* Defines the `mct-background-image` directive.
*
* Used as an attribute, this will set the `background-image`
* property to the URL given in its value, but only after that
* image has loaded; this avoids "flashing" as images change.
*
* If the value of `mct-background-image`is falsy, no image
* will be displayed (immediately.)
*
* Optionally, a `filters` attribute may be specified as an
* object with `brightness` and/or `contrast` properties,
* whose values are percentages. A value of 100 will make
* no changes to the image's brightness or contrast.
*
* @constructor
* @memberof platform/features/imagery
*/
function MCTBackgroundImage($document) {
function link(scope, element) {
// General strategy here:
// - Keep count of how many images have been requested; this
// counter will be used as an internal identifier or sorts
// for each image that loads.
// - As the src attribute changes, begin loading those images.
// - When images do load, update the background-image property
// of the element, but only if a more recently
// requested image has not already been loaded.
// The order in which URLs are passed in and the order
// in which images are actually loaded may be different, so
// some strategy like this is necessary to ensure that images
// do not display out-of-order.
var requested = 0, loaded = 0;
function updateFilters(filters) {
var styleValue = filters ?
Object.keys(filters).map(function (k) {
return k + "(" + filters[k] + "%)";
}).join(' ') :
"";
element.css('filter', styleValue);
element.css('webkitFilter', styleValue);
}
function nextImage(url) {
var myCounter = requested,
image;
function useImage() {
if (loaded <= myCounter) {
loaded = myCounter;
element.css('background-image', "url('" + url + "')");
}
}
if (!url) {
loaded = myCounter;
element.css('background-image', 'none');
} else {
image = $document[0].createElement('img');
image.src = url;
image.onload = useImage;
}
requested += 1;
}
scope.$watch('mctBackgroundImage', nextImage);
scope.$watchCollection('filters', updateFilters);
}
return {
restrict: "A",
scope: {
mctBackgroundImage: "=",
filters: "="
},
link: link
};
}
return MCTBackgroundImage;
}
);

View File

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government * Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *
@ -19,50 +19,41 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
import { TRIGGER } from "./constants";
export const evaluateResults = (results, trigger) => { define([
if (trigger && trigger === TRIGGER.XOR) { '../../../../../src/api/objects/object-utils'
return matchExact(results, 1); ], function (
} else if (trigger && trigger === TRIGGER.NOT) { objectUtils
return matchExact(results, 0); ) {
} else if (trigger && trigger === TRIGGER.ALL) { /**
return matchAll(results); * Policy preventing the Imagery view from being made available for
} else { * domain objects which do not have associated image telemetry.
return matchAny(results); * @implements {Policy.<View, DomainObject>}
} * @constructor
*/
function ImageryViewPolicy(openmct) {
this.openmct = openmct;
} }
function matchAll(results) { ImageryViewPolicy.prototype.hasImageTelemetry = function (domainObject) {
for (const result of results) { var newDO = objectUtils.toNewFormat(
if (!result) { domainObject.getModel(),
return false; domainObject.getId()
} );
var metadata = this.openmct.telemetry.getMetadata(newDO);
var values = metadata.valuesForHints(['image']);
return values.length >= 1;
};
ImageryViewPolicy.prototype.allow = function (view, domainObject) {
if (view.key === 'imagery' || view.key === 'historical-imagery') {
return this.hasImageTelemetry(domainObject);
} }
return true; return true;
} };
function matchAny(results) { return ImageryViewPolicy;
for (const result of results) { });
if (result) {
return true;
}
}
return false;
}
function matchExact(results, target) {
let matches = 0;
for (const result of results) {
if (result) {
matches++;
}
if (matches > target) {
return false;
}
}
return matches === target;
}

View File

@ -0,0 +1,271 @@
/*****************************************************************************
* 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(
[
"zepto",
"../../src/controllers/ImageryController"
],
function ($, ImageryController) {
var MOCK_ELEMENT_TEMPLATE =
'<div class="l-image-thumbs-wrapper"></div>';
xdescribe("The Imagery controller", function () {
var $scope,
openmct,
oldDomainObject,
newDomainObject,
unsubscribe,
metadata,
prefix,
controller,
requestPromise,
mockWindow,
mockElement;
beforeEach(function () {
$scope = jasmine.createSpyObj('$scope', ['$on', '$watch']);
oldDomainObject = jasmine.createSpyObj(
'domainObject',
['getId']
);
newDomainObject = { name: 'foo' };
oldDomainObject.getId.and.returnValue('testID');
openmct = {
objects: jasmine.createSpyObj('objectAPI', [
'get'
]),
time: jasmine.createSpyObj('timeAPI', [
'timeSystem',
'clock',
'on',
'off',
'bounds'
]),
telemetry: jasmine.createSpyObj('telemetryAPI', [
'subscribe',
'request',
'getValueFormatter',
'getMetadata'
])
};
metadata = jasmine.createSpyObj('metadata', [
'value',
'valuesForHints'
]);
metadata.value.and.returnValue("timestamp");
metadata.valuesForHints.and.returnValue(["value"]);
prefix = "formatted ";
unsubscribe = jasmine.createSpy('unsubscribe');
openmct.telemetry.subscribe.and.returnValue(unsubscribe);
openmct.time.timeSystem.and.returnValue({
key: 'testKey'
});
$scope.domainObject = oldDomainObject;
openmct.objects.get.and.returnValue(Promise.resolve(newDomainObject));
openmct.telemetry.getMetadata.and.returnValue(metadata);
openmct.telemetry.getValueFormatter.and.callFake(function (property) {
var formatter =
jasmine.createSpyObj("formatter-" + property, ['format']);
var isTime = (property === "timestamp");
formatter.format.and.callFake(function (datum) {
return (isTime ? prefix : "") + datum[property];
});
return formatter;
});
requestPromise = new Promise(function (resolve) {
setTimeout(function () {
resolve([{
timestamp: 1434600258123,
value: 'some/url'
}]);
}, 10);
});
openmct.telemetry.request.and.returnValue(requestPromise);
mockElement = $(MOCK_ELEMENT_TEMPLATE);
mockWindow = jasmine.createSpyObj('$window', ['requestAnimationFrame']);
mockWindow.requestAnimationFrame.and.callFake(function (f) {
return f();
});
controller = new ImageryController(
$scope,
mockWindow,
mockElement,
openmct
);
});
describe("when loaded", function () {
var callback,
boundsListener,
bounds;
beforeEach(function () {
return requestPromise.then(function () {
openmct.time.on.calls.all().forEach(function (call) {
if (call.args[0] === "bounds") {
boundsListener = call.args[1];
}
});
callback =
openmct.telemetry.subscribe.calls.mostRecent().args[1];
});
});
it("requests history", function () {
expect(openmct.telemetry.request).toHaveBeenCalledWith(
newDomainObject, bounds
);
expect(controller.getTime()).toEqual(prefix + 1434600258123);
expect(controller.getImageUrl()).toEqual('some/url');
});
it("exposes the latest telemetry values", function () {
callback({
timestamp: 1434600259456,
value: "some/other/url"
});
expect(controller.getTime()).toEqual(prefix + 1434600259456);
expect(controller.getImageUrl()).toEqual("some/other/url");
});
it("allows updates to be paused and unpaused", function () {
var newTimestamp = 1434600259456,
newUrl = "some/other/url",
initialTimestamp = controller.getTime(),
initialUrl = controller.getImageUrl();
expect(initialTimestamp).not.toBe(prefix + newTimestamp);
expect(initialUrl).not.toBe(newUrl);
expect(controller.paused()).toBeFalsy();
controller.paused(true);
expect(controller.paused()).toBeTruthy();
callback({ timestamp: newTimestamp, value: newUrl });
expect(controller.getTime()).toEqual(initialTimestamp);
expect(controller.getImageUrl()).toEqual(initialUrl);
controller.paused(false);
expect(controller.paused()).toBeFalsy();
expect(controller.getTime()).toEqual(prefix + newTimestamp);
expect(controller.getImageUrl()).toEqual(newUrl);
});
it("forwards large image view to latest image in history on un-pause", function () {
$scope.imageHistory = [
{ utc: 1434600258122, url: 'some/url1', selected: false},
{ utc: 1434600258123, url: 'some/url2', selected: false}
];
controller.paused(true);
controller.paused(false);
expect(controller.getImageUrl()).toEqual(controller.getImageUrl($scope.imageHistory[1]));
});
it("subscribes to telemetry", function () {
expect(openmct.telemetry.subscribe).toHaveBeenCalledWith(
newDomainObject,
jasmine.any(Function)
);
});
it("requests telemetry", function () {
expect(openmct.telemetry.request).toHaveBeenCalledWith(
newDomainObject,
bounds
);
});
it("unsubscribes and unlistens when scope is destroyed", function () {
expect(unsubscribe).not.toHaveBeenCalled();
$scope.$on.calls.all().forEach(function (call) {
if (call.args[0] === '$destroy') {
call.args[1]();
}
});
expect(unsubscribe).toHaveBeenCalled();
expect(openmct.time.off)
.toHaveBeenCalledWith('bounds', jasmine.any(Function));
});
it("listens for bounds event and responds to tick and manual change", function () {
var mockBounds = {start: 1434600000000, end: 1434600500000};
expect(openmct.time.on).toHaveBeenCalled();
openmct.telemetry.request.calls.reset();
boundsListener(mockBounds, true);
expect(openmct.telemetry.request).not.toHaveBeenCalled();
boundsListener(mockBounds, false);
expect(openmct.telemetry.request).toHaveBeenCalledWith(newDomainObject, mockBounds);
});
it ("doesnt append duplicate datum", function () {
var mockDatum = {value: 'image/url', timestamp: 1434700000000};
var mockDatum2 = {value: 'image/url', timestamp: 1434700000000};
var mockDatum3 = {value: 'image/url', url: 'someval', timestamp: 1434700000000};
expect(controller.updateHistory(mockDatum)).toBe(true);
expect(controller.updateHistory(mockDatum)).toBe(false);
expect(controller.updateHistory(mockDatum)).toBe(false);
expect(controller.updateHistory(mockDatum2)).toBe(false);
expect(controller.updateHistory(mockDatum3)).toBe(false);
});
describe("when user clicks on imagery thumbnail", function () {
var mockDatum = { utc: 1434600258123, url: 'some/url', selected: false};
it("pauses and adds selected class to imagery thumbnail", function () {
controller.setSelectedImage(mockDatum);
expect(controller.paused()).toBeTruthy();
expect(mockDatum.selected).toBeTruthy();
});
it("unselects previously selected image", function () {
$scope.imageHistory = [{ utc: 1434600258123, url: 'some/url', selected: true}];
controller.unselectAllImages();
expect($scope.imageHistory[0].selected).toBeFalsy();
});
it("updates larger image url and time", function () {
controller.setSelectedImage(mockDatum);
expect(controller.getImageUrl()).toEqual(controller.getImageUrl(mockDatum));
expect(controller.getTime()).toEqual(controller.timeFormat.format(mockDatum.utc));
});
});
});
it("initially shows an empty string for date/time", function () {
expect(controller.getTime()).toEqual("");
expect(controller.getImageUrl()).toEqual("");
});
});
}
);

View File

@ -0,0 +1,126 @@
/*****************************************************************************
* 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/directives/MCTBackgroundImage"],
function (MCTBackgroundImage) {
describe("The mct-background-image directive", function () {
var mockDocument,
mockScope,
mockElement,
testImage,
directive;
beforeEach(function () {
mockDocument = [
jasmine.createSpyObj('document', ['createElement'])
];
mockScope = jasmine.createSpyObj('scope', [
'$watch',
'$watchCollection'
]);
mockElement = jasmine.createSpyObj('element', ['css']);
testImage = {};
mockDocument[0].createElement.and.returnValue(testImage);
directive = new MCTBackgroundImage(mockDocument);
});
it("is applicable as an attribute", function () {
expect(directive.restrict).toEqual("A");
});
it("two-way-binds its own value", function () {
expect(directive.scope.mctBackgroundImage).toEqual("=");
});
describe("once linked", function () {
beforeEach(function () {
directive.link(mockScope, mockElement, {});
});
it("watches for changes to the URL", function () {
expect(mockScope.$watch).toHaveBeenCalledWith(
'mctBackgroundImage',
jasmine.any(Function)
);
});
it("updates images in-order, even when they load out-of-order", function () {
var firstOnload;
mockScope.$watch.calls.mostRecent().args[1]("some/url/0");
firstOnload = testImage.onload;
mockScope.$watch.calls.mostRecent().args[1]("some/url/1");
// Resolve in a different order
testImage.onload();
firstOnload();
// Should still have taken the more recent value
expect(mockElement.css.calls.mostRecent().args).toEqual([
"background-image",
"url('some/url/1')"
]);
});
it("clears the background image when undefined is passed in", function () {
mockScope.$watch.calls.mostRecent().args[1]("some/url/0");
testImage.onload();
mockScope.$watch.calls.mostRecent().args[1](undefined);
expect(mockElement.css.calls.mostRecent().args).toEqual([
"background-image",
"none"
]);
});
it("updates filters on change", function () {
var filters = { brightness: 123, contrast: 21 };
mockScope.$watchCollection.calls.all().forEach(function (call) {
if (call.args[0] === 'filters') {
call.args[1](filters);
}
});
expect(mockElement.css).toHaveBeenCalledWith(
'filter',
'brightness(123%) contrast(21%)'
);
});
it("clears filters when none are present", function () {
mockScope.$watchCollection.calls.all().forEach(function (call) {
if (call.args[0] === 'filters') {
call.args[1](undefined);
}
});
expect(mockElement.css)
.toHaveBeenCalledWith('filter', '');
});
});
});
}
);

View File

@ -0,0 +1,84 @@
/*****************************************************************************
* 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/policies/ImageryViewPolicy"],
function (ImageryViewPolicy) {
describe("Imagery view policy", function () {
var testView,
openmct,
mockDomainObject,
mockTelemetry,
mockMetadata,
policy;
beforeEach(function () {
testView = { key: "imagery" };
mockMetadata = jasmine.createSpyObj('metadata', [
"valuesForHints"
]);
mockDomainObject = jasmine.createSpyObj(
'domainObject',
['getId', 'getModel', 'getCapability']
);
mockTelemetry = jasmine.createSpyObj(
'telemetry',
['getMetadata']
);
mockDomainObject.getCapability.and.callFake(function (c) {
return c === 'telemetry' ? mockTelemetry : undefined;
});
mockDomainObject.getId.and.returnValue("some-id");
mockDomainObject.getModel.and.returnValue({ name: "foo" });
mockTelemetry.getMetadata.and.returnValue(mockMetadata);
mockMetadata.valuesForHints.and.returnValue(["bar"]);
openmct = { telemetry: mockTelemetry };
policy = new ImageryViewPolicy(openmct);
});
it("checks for hints indicating image telemetry", function () {
policy.allow(testView, mockDomainObject);
expect(mockMetadata.valuesForHints)
.toHaveBeenCalledWith(["image"]);
});
it("allows the imagery view for domain objects with image telemetry", function () {
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
});
it("disallows the imagery view for domain objects without image telemetry", function () {
mockMetadata.valuesForHints.and.returnValue([]);
expect(policy.allow(testView, mockDomainObject)).toBeFalsy();
});
it("allows other views", function () {
testView.key = "somethingElse";
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
});
});
}
);

View File

@ -1,8 +0,0 @@
# My Items plugin
Defines top-level folder named "My Items" to store user-created items. Enabled by default, this can be disabled in a
read-only deployment with no user-editable objects.
## Installation
```js
openmct.install(openmct.plugins.MyItems());
```

View File

@ -20,10 +20,13 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
define([], function () { define([
return { 'legacyRegistry'
name:"platform/features/my-items", ], function (
definition: { legacyRegistry
) {
legacyRegistry.register("platform/features/my-items", {
"name": "My Items", "name": "My Items",
"description": "Defines a root named My Items", "description": "Defines a root named My Items",
"extensions": { "extensions": {
@ -44,6 +47,5 @@ define([], function () {
} }
] ]
} }
} });
};
}); });

View File

@ -22,15 +22,15 @@
define([ define([
"./src/EmbeddedPageController", "./src/EmbeddedPageController",
"./res/iframe.html" "./res/iframe.html",
'legacyRegistry'
], function ( ], function (
EmbeddedPageController, EmbeddedPageController,
iframeTemplate iframeTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/features/pages", {
name:"platform/features/pages",
definition: {
"extensions": { "extensions": {
"types": [ "types": [
{ {
@ -72,6 +72,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -0,0 +1,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.
-->
<div class="l-iframe abs">
<iframe ng-controller="EmbeddedPageController as ctl"
ng-src="{{ctl.trust(model.url)}}">
</iframe>
</div>

View File

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government * Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *
@ -20,33 +20,36 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
export const getLatestTimestamp = ( /**
currentTimestamp, * This bundle adds the Web Page object type, which can be used to embed
compareTimestamp, * other web pages with layouts.
timeSystems, * @namespace platform/features/pages
currentTimeSystem */
) => { define(
let latest = { ...currentTimestamp }; [],
const compare = { ...compareTimestamp }; function () {
const key = currentTimeSystem.key;
if (!latest || !latest[key]) { /**
latest = updateLatestTimeStamp(compare, timeSystems) * Controller for embedded web pages; serves simply as a
* wrapper for `$sce` to mark pages as trusted.
* @constructor
* @memberof platform/features/pages
*/
function EmbeddedPageController($sce) {
this.$sce = $sce;
} }
if (compare[key] > latest[key]) { /**
latest = updateLatestTimeStamp(compare, timeSystems) * Alias of `$sce.trustAsResourceUrl`.
* @param {string} url the URL to trust
* @returns {string} the trusted URL
*/
EmbeddedPageController.prototype.trust = function (url) {
return this.$sce.trustAsResourceUrl(url);
};
return EmbeddedPageController;
} }
return latest; );
}
function updateLatestTimeStamp(timestamp, timeSystems) {
let latest = {};
timeSystems.forEach(timeSystem => {
latest[timeSystem.key] = timestamp[timeSystem.key];
});
return latest;
}

View File

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2020, United States Government * Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *
@ -20,35 +20,37 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
export const TRIGGER = { define(
ANY: 'any', ["../src/EmbeddedPageController"],
ALL: 'all', function (EmbeddedPageController) {
NOT: 'not',
XOR: 'xor'
};
export const TRIGGER_LABEL = { describe("The controller for embedded pages", function () {
'any': 'when any criteria are met', var mockSCE,
'all': 'when all criteria are met', controller;
'not': 'when no criteria are met',
'xor': 'when only one criteria is met'
};
export const STYLE_CONSTANTS = { beforeEach(function () {
isStyleInvisible: 'is-style-invisible', mockSCE = jasmine.createSpyObj(
borderColorTitle: 'Set border color', '$sce',
textColorTitle: 'Set text color', ["trustAsResourceUrl"]
backgroundColorTitle: 'Set background color', );
imagePropertiesTitle: 'Edit image properties',
visibilityHidden: 'Hidden',
visibilityVisible: 'Visible'
};
export const ERROR = { mockSCE.trustAsResourceUrl.and.callFake(function (v) {
'TELEMETRY_NOT_FOUND': { return v;
errorText: 'Telemetry not found for criterion' });
},
'CONDITION_NOT_FOUND': { controller = new EmbeddedPageController(mockSCE);
errorText: 'Condition not found' });
it("allows URLs to be marked as trusted", function () {
var testURL = "http://www.nasa.gov";
expect(controller.trust(testURL))
.toEqual(testURL);
expect(mockSCE.trustAsResourceUrl)
.toHaveBeenCalledWith(testURL);
});
});
} }
}; );

View File

@ -22,14 +22,15 @@
define([ define([
"./res/markup.html" "./res/markup.html",
'legacyRegistry'
], function ( ], function (
markupTemplate
markupTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/features/static-markup", {
name:"platform/features/static-markup",
definition: {
"extensions": { "extensions": {
"types": [ "types": [
{ {
@ -51,6 +52,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -21,13 +21,13 @@
*****************************************************************************/ *****************************************************************************/
define([ define([
"./res/templates/deprecated-timeline-message.html" "./res/templates/deprecated-timeline-message.html",
'legacyRegistry'
], function ( ], function (
deprecatedTimelineMessage deprecatedTimelineMessage,
legacyRegistry
) { ) {
return { legacyRegistry.register('platform/features/timeline', {
name: 'platform/features/timeline',
definition: {
extensions: { extensions: {
types: [ types: [
{ {
@ -47,6 +47,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -45,7 +45,8 @@ define([
"./res/templates/controls/dialog.html", "./res/templates/controls/dialog.html",
"./res/templates/controls/radio.html", "./res/templates/controls/radio.html",
"./res/templates/controls/file-input.html", "./res/templates/controls/file-input.html",
"./res/templates/controls/snap-view.html" "./res/templates/controls/snap-view.html",
'legacyRegistry'
], function ( ], function (
MCTForm, MCTForm,
MCTControl, MCTControl,
@ -71,12 +72,11 @@ define([
dialogTemplate, dialogTemplate,
radioTemplate, radioTemplate,
fileInputTemplate, fileInputTemplate,
snapViewTemplate snapViewTemplate,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/forms", {
name:"platform/forms",
definition: {
"name": "MCT Forms", "name": "MCT Forms",
"description": "Form generator; includes directive and some controls.", "description": "Form generator; includes directive and some controls.",
"extensions": { "extensions": {
@ -213,6 +213,5 @@ define([
] ]
} }
} });
};
}); });

View File

@ -20,11 +20,15 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
define([], function () { define([
return { 'legacyRegistry'
name:"platform/framework", ], function (
definition: {
legacyRegistry
) {
legacyRegistry.register("platform/framework", {
"name": "Open MCT Framework Component", "name": "Open MCT Framework Component",
"description": "Framework layer for Open MCT; interprets bundle definitions and serves as an intermediary between Require and Angular", "description": "Framework layer for Open MCT; interprets bundle definitions and serves as an intermediary between Require and Angular",
"libraries": "lib", "libraries": "lib",
@ -102,6 +106,5 @@ define([], function () {
} }
] ]
} }
} });
};
}); });

View File

@ -24,17 +24,17 @@ define([
"./src/IdentityAggregator", "./src/IdentityAggregator",
"./src/IdentityProvider", "./src/IdentityProvider",
"./src/IdentityCreationDecorator", "./src/IdentityCreationDecorator",
"./src/IdentityIndicator" "./src/IdentityIndicator",
'legacyRegistry'
], function ( ], function (
IdentityAggregator, IdentityAggregator,
IdentityProvider, IdentityProvider,
IdentityCreationDecorator, IdentityCreationDecorator,
IdentityIndicator IdentityIndicator,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/identity", {
name:"platform/identity",
definition: {
"extensions": { "extensions": {
"components": [ "components": [
{ {
@ -82,6 +82,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -1,14 +0,0 @@
# Import / Export Plugin
The Import/Export plugin allows objects to be exported as JSON files. This allows for sharing of objects between users
who are not using a shared persistence store. It also allows object trees to be backed up. Additionally, object trees
exported using this tool can then be exposed as read-only static root trees using the
[Static Root Plugin](../../src/plugins/staticRootPlugin/README.md).
Upon installation it will add two new context menu actions to allow import and export of objects. Initiating the Export
action on an object will produce a JSON file that includes the object and all of its composed children. Selecting Import
on an object will allow the user to import a previously exported object tree as a child of the selected object.
## Installation
```js
openmct.install(openmct.plugins.ImportExport())
```

View File

@ -72,8 +72,6 @@ define([
] ]
} }
}); });
openmct.legacyRegistry.enable('platform/import-export');
}; };
}; };
}); });

View File

@ -133,7 +133,7 @@ define(['lodash'], function (_) {
copyOfChild.location = parentId; copyOfChild.location = parentId;
parent.composition[index] = copyOfChild.identifier; parent.composition[index] = copyOfChild.identifier;
this.tree[newIdString] = copyOfChild; this.tree[newIdString] = copyOfChild;
this.tree[parentId].composition[index] = copyOfChild.identifier; this.tree[parentId].composition[index] = newIdString;
return copyOfChild; return copyOfChild;
}; };

View File

@ -136,10 +136,6 @@ define(['zepto', '../../../../src/api/objects/object-utils.js'], function ($, ob
return tree; return tree;
}; };
ImportAsJSONAction.prototype.getKeyString = function (identifier) {
return this.openmct.objects.makeKeyString(identifier);
};
/** /**
* Rewrites all instances of a given id in the tree with a newly generated * Rewrites all instances of a given id in the tree with a newly generated
* replacement to prevent collision. * replacement to prevent collision.

View File

@ -47,12 +47,7 @@ define(
uniqueId = 0; uniqueId = 0;
newObjects = []; newObjects = [];
openmct = { openmct = {
$injector: jasmine.createSpyObj('$injector', ['get']), $injector: jasmine.createSpyObj('$injector', ['get'])
objects: {
makeKeyString: function (identifier) {
return identifier.key;
}
}
}; };
mockInstantiate = jasmine.createSpy('instantiate').and.callFake( mockInstantiate = jasmine.createSpy('instantiate').and.callFake(
function (model, id) { function (model, id) {
@ -158,7 +153,7 @@ define(
body: JSON.stringify({ body: JSON.stringify({
"openmct": { "openmct": {
"infiniteParent": { "infiniteParent": {
"composition": [{key: "infinteChild", namespace: ""}], "composition": ["infinteChild"],
"name": "1", "name": "1",
"type": "folder", "type": "folder",
"modified": 1503598129176, "modified": 1503598129176,
@ -166,7 +161,7 @@ define(
"persisted": 1503598129176 "persisted": 1503598129176
}, },
"infinteChild": { "infinteChild": {
"composition": [{key: "infinteParent", namespace: ""}], "composition": ["infiniteParent"],
"name": "2", "name": "2",
"type": "folder", "type": "folder",
"modified": 1503598132428, "modified": 1503598132428,

View File

@ -21,14 +21,14 @@
*****************************************************************************/ *****************************************************************************/
define([ define([
"./src/PersistenceAggregator" "./src/PersistenceAggregator",
'legacyRegistry'
], function ( ], function (
PersistenceAggregator PersistenceAggregator,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/persistence/aggregator", {
name:"platform/persistence/aggregator",
definition: {
"extensions": { "extensions": {
"components": [ "components": [
{ {
@ -41,6 +41,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -1,8 +1,2 @@
# Couch DB Persistence Plugin This bundle implements a connection to an external CouchDB persistence
An adapter for using CouchDB for persistence of user-created objects. The plugin installation function takes the URL store in Open MCT.
for the CouchDB database as a parameter.
## Installation
```js
openmct.install(openmct.plugins.CouchDB('http://localhost:5984/openmct'))
```

View File

@ -22,15 +22,15 @@
define([ define([
"./src/CouchPersistenceProvider", "./src/CouchPersistenceProvider",
"./src/CouchIndicator" "./src/CouchIndicator",
'legacyRegistry'
], function ( ], function (
CouchPersistenceProvider, CouchPersistenceProvider,
CouchIndicator CouchIndicator,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/persistence/couch", {
name:"platform/persistence/couch",
definition: {
"name": "Couch Persistence", "name": "Couch Persistence",
"description": "Adapter to read and write objects using a CouchDB instance.", "description": "Adapter to read and write objects using a CouchDB instance.",
"extensions": { "extensions": {
@ -73,6 +73,5 @@ define([
} }
] ]
} }
} });
};
}); });

View File

@ -33,7 +33,7 @@ define(
var CONNECTED = { var CONNECTED = {
text: "Connected", text: "Connected",
glyphClass: "ok", glyphClass: "ok",
statusClass: "s-status-on", statusClass: "s-status-ok",
description: "Connected to the domain object database." description: "Connected to the domain object database."
}, },
DISCONNECTED = { DISCONNECTED = {

View File

@ -1,8 +1,2 @@
# Elasticsearch Persistence Provider This bundle implements a connection to an external ElasticSearch persistence
An adapter for using Elastic for persistence of user-created objects. The installation function takes the URL for an store in Open MCT.
Elasticsearch server as a parameter.
## Installation
```js
openmct.install(openmct.plugins.Elasticsearch('http://localhost:9200'))
```

View File

@ -23,16 +23,16 @@
define([ define([
"./src/ElasticPersistenceProvider", "./src/ElasticPersistenceProvider",
"./src/ElasticSearchProvider", "./src/ElasticSearchProvider",
"./src/ElasticIndicator" "./src/ElasticIndicator",
'legacyRegistry'
], function ( ], function (
ElasticPersistenceProvider, ElasticPersistenceProvider,
ElasticSearchProvider, ElasticSearchProvider,
ElasticIndicator ElasticIndicator,
legacyRegistry
) { ) {
return { legacyRegistry.register("platform/persistence/elastic", {
name:"platform/persistence/elastic",
definition: {
"name": "ElasticSearch Persistence", "name": "ElasticSearch Persistence",
"description": "Adapter to read and write objects using an ElasticSearch instance.", "description": "Adapter to read and write objects using an ElasticSearch instance.",
"extensions": { "extensions": {
@ -92,6 +92,5 @@ define([
} }
] ]
} }
} });
};
}); });

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