mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 02:29:24 +00:00
Compare commits
156 Commits
build-test
...
root-objec
Author | SHA1 | Date | |
---|---|---|---|
d635ea4cc9 | |||
6f2d8e6ce3 | |||
b802870f30 | |||
91d1681698 | |||
efd97de743 | |||
c4cd725c9a | |||
23e5efbb19 | |||
4e995c10da | |||
b5cf157c40 | |||
ac082e9f58 | |||
9f7799b44f | |||
cdf9c50b8a | |||
ffb3b302c7 | |||
278f48f65c | |||
4801dc4f32 | |||
9e8f845fbe | |||
b4d1cdaae8 | |||
f9d3af2724 | |||
37debefadc | |||
891fe0a36b | |||
4b6de59b03 | |||
6a5b902365 | |||
270f07ebd5 | |||
52500f6097 | |||
2fa8a8d61d | |||
69a6cd20af | |||
28eb268af1 | |||
045bb443cb | |||
c6ca912f2b | |||
78c7484d54 | |||
4d560086dd | |||
ef965ebdfd | |||
0b4a843617 | |||
7e7141a5a0 | |||
b3fd6c9b85 | |||
deb0511b43 | |||
e32f465f7a | |||
abc458cef4 | |||
2198a4780b | |||
b76d4b76cb | |||
9ebb013f22 | |||
5a4cba0226 | |||
f03bfdebb4 | |||
7c1550ced7 | |||
a09da30768 | |||
573a63d359 | |||
fd3be63805 | |||
ad8ed419de | |||
8b4f07c2e0 | |||
e667b22b3c | |||
9198effafe | |||
7d51d9c1eb | |||
de6eceb98b | |||
13ff0c368d | |||
9124f4f566 | |||
b7d2402434 | |||
d9baa94970 | |||
afeb89a51a | |||
07992f0b2a | |||
a5c4508578 | |||
a4fab3ce8a | |||
97d80f57cc | |||
41138a1731 | |||
a54a2f8f84 | |||
5bbe710552 | |||
f2d34d7c33 | |||
8fa1770885 | |||
7221dc1ac6 | |||
25bb9939d6 | |||
e7e12504f2 | |||
63bf856d89 | |||
e3dcd51f8d | |||
cb63f4eca1 | |||
3f60c3c0f1 | |||
16bb22e834 | |||
b1467548da | |||
baa7c0bc58 | |||
73b81e38e7 | |||
8b088b7a2c | |||
894da25461 | |||
79c4dc9272 | |||
87d63806b9 | |||
f0e7f8cfc0 | |||
db597e1e93 | |||
98db273f5d | |||
8a6f944655 | |||
bacad24811 | |||
8cc58946cf | |||
3338bc1000 | |||
80c20b3d05 | |||
0d9558b891 | |||
c29c3c386f | |||
e1d0c22071 | |||
7dee6344b0 | |||
731ab89561 | |||
9ceb3c5b1e | |||
6bd0246db6 | |||
bee3a9eedf | |||
e515d19acd | |||
dd13efe065 | |||
99aa5c7b7b | |||
b5dfbe268c | |||
a9b9107cc3 | |||
cfda4e4214 | |||
0a657de4b2 | |||
8153edb9cb | |||
22ca339fb9 | |||
7f8764560b | |||
4411bb0a2d | |||
4ecd264d93 | |||
16677c99c9 | |||
6ab468086a | |||
9d2991ee10 | |||
dadb6120c2 | |||
d9a94db59d | |||
6dd8d448df | |||
ef2db1edaf | |||
3748927e87 | |||
7e4aac028b | |||
8e54b8a819 | |||
9e5eddec9b | |||
c46e4c5dad | |||
f0dc928230 | |||
6f674930d9 | |||
8675fc3fa6 | |||
25434342f3 | |||
8044dfe726 | |||
cd6c7fdc5e | |||
7ff85dc396 | |||
fb4877924a | |||
4b13cbdb33 | |||
51c9328dfd | |||
31ac67b393 | |||
0399766ccd | |||
18ab034147 | |||
8a4bc2a463 | |||
771fb9c044 | |||
055cf2b118 | |||
e9cf337aac | |||
04a18248c7 | |||
d462db60de | |||
67ebcf4749 | |||
38dbf2ccab | |||
e9968e3649 | |||
d9fafd2956 | |||
b5aba7ce8f | |||
0db5648e10 | |||
83325da738 | |||
4d1b2f3456 | |||
6137700c82 | |||
91a1b3f31d | |||
357b25a76b | |||
bab53ad9bd | |||
d0d4579f13 | |||
8962b0c88b | |||
3876151a4b |
@ -2,7 +2,7 @@ version: 2
|
||||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: circleci/node:8-browsers
|
||||
- image: circleci/node:13-browsers
|
||||
environment:
|
||||
CHROME_BIN: "/usr/bin/google-chrome"
|
||||
steps:
|
||||
|
103
.eslintrc.js
103
.eslintrc.js
@ -120,6 +120,91 @@ module.exports = {
|
||||
"no-useless-computed-key": "error",
|
||||
// https://eslint.org/docs/rules/rest-spread-spacing
|
||||
"rest-spread-spacing": ["error"],
|
||||
// https://eslint.org/docs/rules/no-var
|
||||
"no-var": "error",
|
||||
// https://eslint.org/docs/rules/one-var
|
||||
"one-var": ["error", "never"],
|
||||
// https://eslint.org/docs/rules/default-case-last
|
||||
"default-case-last": "error",
|
||||
// https://eslint.org/docs/rules/default-param-last
|
||||
"default-param-last": "error",
|
||||
// https://eslint.org/docs/rules/grouped-accessor-pairs
|
||||
"grouped-accessor-pairs": "error",
|
||||
// https://eslint.org/docs/rules/no-constructor-return
|
||||
"no-constructor-return": "error",
|
||||
// https://eslint.org/docs/rules/array-callback-return
|
||||
"array-callback-return": "error",
|
||||
// https://eslint.org/docs/rules/no-invalid-this
|
||||
"no-invalid-this": "error", // Believe this one actually surfaces some bugs
|
||||
// https://eslint.org/docs/rules/func-style
|
||||
"func-style": ["error", "declaration"],
|
||||
// https://eslint.org/docs/rules/no-unused-expressions
|
||||
"no-unused-expressions": "error",
|
||||
// https://eslint.org/docs/rules/no-useless-concat
|
||||
"no-useless-concat": "error",
|
||||
// https://eslint.org/docs/rules/radix
|
||||
"radix": "error",
|
||||
// https://eslint.org/docs/rules/require-await
|
||||
"require-await": "error",
|
||||
// https://eslint.org/docs/rules/no-alert
|
||||
"no-alert": "error",
|
||||
// https://eslint.org/docs/rules/no-useless-constructor
|
||||
"no-useless-constructor": "error",
|
||||
// https://eslint.org/docs/rules/no-duplicate-imports
|
||||
"no-duplicate-imports": "error",
|
||||
|
||||
// https://eslint.org/docs/rules/no-implicit-coercion
|
||||
"no-implicit-coercion": "error",
|
||||
//https://eslint.org/docs/rules/no-unneeded-ternary
|
||||
"no-unneeded-ternary": "error",
|
||||
// https://eslint.org/docs/rules/semi
|
||||
"semi": ["error", "always"],
|
||||
// https://eslint.org/docs/rules/no-multi-spaces
|
||||
"no-multi-spaces": "error",
|
||||
// https://eslint.org/docs/rules/key-spacing
|
||||
"key-spacing": ["error", {
|
||||
"afterColon": true
|
||||
}],
|
||||
// https://eslint.org/docs/rules/keyword-spacing
|
||||
"keyword-spacing": ["error", {
|
||||
"before": true,
|
||||
"after": true
|
||||
}],
|
||||
// https://eslint.org/docs/rules/comma-spacing
|
||||
// Also requires one line code fix
|
||||
"comma-spacing": ["error", {
|
||||
"after": true
|
||||
}],
|
||||
//https://eslint.org/docs/rules/no-whitespace-before-property
|
||||
"no-whitespace-before-property": "error",
|
||||
// https://eslint.org/docs/rules/object-curly-newline
|
||||
"object-curly-newline": ["error", {"consistent": true, "multiline": true}],
|
||||
// https://eslint.org/docs/rules/object-property-newline
|
||||
"object-property-newline": "error",
|
||||
// https://eslint.org/docs/rules/brace-style
|
||||
"brace-style": "error",
|
||||
// https://eslint.org/docs/rules/no-multiple-empty-lines
|
||||
"no-multiple-empty-lines": ["error", {"max": 1}],
|
||||
// https://eslint.org/docs/rules/operator-linebreak
|
||||
"operator-linebreak": ["error", "before", {"overrides": {"=": "after"}}],
|
||||
// https://eslint.org/docs/rules/padding-line-between-statements
|
||||
"padding-line-between-statements":["error", {
|
||||
"blankLine": "always",
|
||||
"prev": "multiline-block-like",
|
||||
"next": "*"
|
||||
}, {
|
||||
"blankLine": "always",
|
||||
"prev": "*",
|
||||
"next": "return"
|
||||
}],
|
||||
// https://eslint.org/docs/rules/space-infix-ops
|
||||
"space-infix-ops": "error",
|
||||
// https://eslint.org/docs/rules/space-unary-ops
|
||||
"space-unary-ops": ["error", {"words": true, "nonwords": false}],
|
||||
// https://eslint.org/docs/rules/arrow-spacing
|
||||
"arrow-spacing": "error",
|
||||
// https://eslint.org/docs/rules/semi-spacing
|
||||
"semi-spacing": ["error", {"before": false, "after": true}],
|
||||
|
||||
"vue/html-indent": [
|
||||
"error",
|
||||
@ -151,28 +236,24 @@ module.exports = {
|
||||
}
|
||||
}],
|
||||
"vue/multiline-html-element-content-newline": "off",
|
||||
"vue/singleline-html-element-content-newline": "off"
|
||||
"vue/singleline-html-element-content-newline": "off",
|
||||
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["*Spec.js"],
|
||||
"files": LEGACY_FILES,
|
||||
"rules": {
|
||||
"no-unused-vars": [
|
||||
"warn",
|
||||
{
|
||||
"vars": "all",
|
||||
"args": "none",
|
||||
"varsIgnorePattern": "controller",
|
||||
|
||||
"varsIgnorePattern": "controller"
|
||||
}
|
||||
]
|
||||
}
|
||||
}, {
|
||||
"files": LEGACY_FILES,
|
||||
"rules": {
|
||||
// https://eslint.org/docs/rules/no-nested-ternary
|
||||
],
|
||||
"no-nested-ternary": "off",
|
||||
"no-var": "off"
|
||||
"no-var": "off",
|
||||
"one-var": "off"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -37,4 +37,7 @@ protractor/logs
|
||||
# npm-debug log
|
||||
npm-debug.log
|
||||
|
||||
# karma reports
|
||||
report.*.json
|
||||
|
||||
package-lock.json
|
||||
|
@ -136,7 +136,7 @@ this repository. This is verified by the command line build.
|
||||
|
||||
#### Code Guidelines
|
||||
|
||||
JavaScript sources in Open MCT should:
|
||||
The following guidelines are provided for anyone contributing source code to the Open MCT project:
|
||||
|
||||
1. Write clean code. Here’s a good summary - https://github.com/ryanmcdermott/clean-code-javascript.
|
||||
1. Include JSDoc for any exposed API (e.g. public methods, classes).
|
||||
@ -178,7 +178,7 @@ JavaScript sources in Open MCT should:
|
||||
code, and present these in the following order:
|
||||
* First, variable declarations and initialization.
|
||||
* Secondly, imperative statements.
|
||||
* Finally, the returned value. Functions should only have a single return statement.
|
||||
* Finally, the returned value. A single return statement at the end of the function should be used, except where an early return would improve code clarity.
|
||||
1. Avoid the use of "magic" values.
|
||||
eg.
|
||||
```JavaScript
|
||||
@ -189,7 +189,7 @@ JavaScript sources in Open MCT should:
|
||||
```JavaScript
|
||||
if (responseCode === 401)
|
||||
```
|
||||
1. Don’t use the ternary operator. Yes it's terse, but there's probably a clearer way of writing it.
|
||||
1. Use the ternary operator only for simple cases such as variable assignment. Nested ternaries should be avoided in all cases.
|
||||
1. Test specs should reside alongside the source code they test, not in a separate directory.
|
||||
1. Organize code by feature, not by type.
|
||||
eg.
|
||||
@ -226,9 +226,9 @@ typically from the author of the change and its reviewer.
|
||||
Automated testing shall occur whenever changes are merged into the main
|
||||
development branch and must be confirmed alongside any pull request.
|
||||
|
||||
Automated tests are typically unit tests which exercise individual software
|
||||
components. Tests are subject to code review along with the actual
|
||||
implementation, to ensure that tests are applicable and useful.
|
||||
Automated tests are tests which exercise plugins, API, and utility classes.
|
||||
Tests are subject to code review along with the actual implementation, to
|
||||
ensure that tests are applicable and useful.
|
||||
|
||||
Examples of useful tests:
|
||||
* Tests which replicate bugs (or their root causes) to verify their
|
||||
@ -238,8 +238,26 @@ Examples of useful tests:
|
||||
* Tests which verify expected interactions with other components in the
|
||||
system.
|
||||
|
||||
During automated testing, code coverage metrics will be reported. Line
|
||||
coverage must remain at or above 80%.
|
||||
#### Guidelines
|
||||
* 100% statement coverage is achievable and desirable.
|
||||
* Do blackbox testing. Test external behaviors, not internal details. Write tests that describe what your plugin is supposed to do. How it does this doesn't matter, so don't test it.
|
||||
* Unit test specs for plugins should be defined at the plugin level. Start with one test spec per plugin named pluginSpec.js, and as this test spec grows too big, break it up into multiple test specs that logically group related tests.
|
||||
* Unit tests for API or for utility functions and classes may be defined at a per-source file level.
|
||||
* Wherever possible only use and mock public API, builtin functions, and UI in your test specs. Do not directly invoke any private functions. ie. only call or mock functions and objects exposed by openmct.* (eg. openmct.telemetry, openmct.objectView, etc.), and builtin browser functions (fetch, requestAnimationFrame, setTimeout, etc.).
|
||||
* Where builtin functions have been mocked, be sure to clear them between tests.
|
||||
* Test at an appropriate level of isolation. Eg.
|
||||
* If you’re testing a view, you do not need to test the whole application UI, you can just fetch the view provider using the public API and render the view into an element that you have created.
|
||||
* You do not need to test that the view switcher works, there should be separate tests for that.
|
||||
* You do not need to test that telemetry providers work, you can mock openmct.telemetry.request() to feed test data to the view.
|
||||
* Use your best judgement when deciding on appropriate scope.
|
||||
* Automated tests for plugins should start by actually installing the plugin being tested, and then test that installing the plugin adds the desired features and behavior to Open MCT, observing the above rules.
|
||||
* All variables used in a test spec, including any instances of the Open MCT API should be declared inside of an appropriate block scope (not at the root level of the source file), and should be initialized in the relevant beforeEach block. `beforeEach` is preferable to `beforeAll` to avoid leaking of state between tests.
|
||||
* A `afterEach` or `afterAll` should be used to do any clean up necessary to prevent leakage of state between test specs. This can happen when functions on `window` are wrapped, or when the URL is changed. [A convenience function](https://github.com/nasa/openmct/blob/master/src/utils/testing.js#L59) is provided for resetting the URL and clearing builtin spies between tests.
|
||||
* If writing unit tests for legacy Angular code be sure to follow [best practices in order to avoid memory leaks](https://www.thecodecampus.de/blog/avoid-memory-leaks-angularjs-unit-tests/).
|
||||
|
||||
#### Examples
|
||||
* [Example of an automated test spec for an object view plugin](https://github.com/nasa/openmct/blob/master/src/plugins/telemetryTable/pluginSpec.js)
|
||||
* [Example of an automated test spec for API](https://github.com/nasa/openmct/blob/master/src/api/time/TimeAPISpec.js)
|
||||
|
||||
### Commit Message Standards
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# 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, Copyright (c) 2014-2020, United States Government as represented by the Administrator of the National Aeronautics and Space Administration. All rights reserved.
|
||||
|
||||
Open MCT is licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
||||
|
||||
|
@ -125,3 +125,22 @@ A release is not closed until both categories have been performed on
|
||||
the latest snapshot of the software, _and_ no issues labelled as
|
||||
["blocker" or "critical"](https://github.com/nasa/openmctweb/blob/master/CONTRIBUTING.md#issue-reporting)
|
||||
remain open.
|
||||
|
||||
### Testathons
|
||||
Testathons can be used as a means of performing per-sprint and per-release testing.
|
||||
|
||||
#### Timing
|
||||
For per-sprint testing, a testathon is typically performed at the beginning of the third week of a sprint, and again later that week to verify any fixes. For per-release testing, a testathon is typically performed prior to any formal testing processes that are applicable to that release.
|
||||
|
||||
#### Process
|
||||
|
||||
1. Prior to the scheduled testathon, a list will be compiled of all issues that are closed and unverified.
|
||||
2. For each issue, testers should review the associated PR for testing instructions. See the contributing guide for instructions on [pull requests](https://github.com/nasa/openmct/blob/master/CONTRIBUTING.md#merging).
|
||||
3. As each issue is verified via testing, any team members testing it should leave a comment on that issue indicating that it has been verified fixed.
|
||||
4. If a bug is found that relates to an issue being tested, notes should be included on the associated issue, and the issue should be reopened. Bug notes should include reproduction steps.
|
||||
5. For any bugs that are not obviously related to any of the issues under test, a new issue should be created with details about the bug, including reproduction steps. If unsure about whether a bug relates to an issue being tested, just create a new issue.
|
||||
6. At the end of the testathon, triage will take place, where all tested issues will be reviewed.
|
||||
7. If verified fixed, an issue will remain closed, and will have the “unverified” label removed.
|
||||
8. For any bugs found, a severity will be assigned.
|
||||
9. A second testathon will be scheduled for later in the week that will aim to address all issues identified as blockers, as well as any other issues scoped by the team during triage.
|
||||
10. Any issues that were not tested will remain "unverified" and will be picked up in the next testathon.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/EventTelemetryProvider"
|
||||
@ -29,7 +28,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/eventGenerator",
|
||||
name: "example/eventGenerator",
|
||||
definition: {
|
||||
"name": "Event Message Generator",
|
||||
"description": "For development use. Creates sample event message data that mimics a live data stream.",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define */
|
||||
|
||||
/**
|
||||
* Module defining EventTelemetry.
|
||||
@ -44,13 +43,14 @@ define(
|
||||
};
|
||||
|
||||
generatorData.getDomainValue = function (i, domain) {
|
||||
return i * interval +
|
||||
(domain !== 'delta' ? firstObservedTime : 0);
|
||||
return i * interval
|
||||
+ (domain !== 'delta' ? firstObservedTime : 0);
|
||||
};
|
||||
|
||||
generatorData.getRangeValue = function (i, range) {
|
||||
var domainDelta = this.getDomainValue(i) - firstObservedTime,
|
||||
ind = i % messages.length;
|
||||
|
||||
return messages[ind] + " - [" + domainDelta.toString() + "]";
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,Promise*/
|
||||
|
||||
/**
|
||||
* Module defining EventTelemetryProvider. Created by chacskaylo on 06/18/2015.
|
||||
@ -57,6 +56,7 @@ define(
|
||||
results.forEach(function (result) {
|
||||
packaged[result.key] = result.telemetry;
|
||||
});
|
||||
|
||||
// Format as expected (sources -> keys -> telemetry)
|
||||
return { eventGenerator: packaged };
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([], function () {
|
||||
'use strict';
|
||||
@ -76,13 +75,14 @@ define([], function () {
|
||||
copyRangesToRow(row, i);
|
||||
rows.push(row);
|
||||
}
|
||||
|
||||
exportService.exportCSV(rows, { headers: headers });
|
||||
});
|
||||
};
|
||||
|
||||
ExportTelemetryAsCSVAction.appliesTo = function (context) {
|
||||
return context.domainObject &&
|
||||
context.domainObject.hasCapability("telemetry");
|
||||
return context.domainObject
|
||||
&& context.domainObject.hasCapability("telemetry");
|
||||
};
|
||||
|
||||
return ExportTelemetryAsCSVAction;
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
'./ExportTelemetryAsCSVAction'
|
||||
@ -27,7 +26,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/export",
|
||||
name: "example/export",
|
||||
definition: {
|
||||
"name": "Example of using CSV Export",
|
||||
"extensions": {
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/ExampleFormController"
|
||||
@ -29,7 +28,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/forms",
|
||||
name: "example/forms",
|
||||
definition: {
|
||||
"name": "Declarative Forms example",
|
||||
"sources": "src",
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,window*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -80,7 +79,7 @@ define(
|
||||
control: "button",
|
||||
csslass: "icon-save",
|
||||
click: function () {
|
||||
window.alert("Save");
|
||||
console.log("Save");
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -88,7 +87,7 @@ define(
|
||||
csslass: "icon-x",
|
||||
description: "Button B",
|
||||
click: function () {
|
||||
window.alert("Cancel");
|
||||
console.log("Cancel");
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -97,7 +96,7 @@ define(
|
||||
description: "Button C",
|
||||
disabled: true,
|
||||
click: function () {
|
||||
window.alert("Delete");
|
||||
console.log("Delete");
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -152,10 +151,22 @@ define(
|
||||
name: "Choose something",
|
||||
control: "select",
|
||||
options: [
|
||||
{ name: "Hats", value: "hats" },
|
||||
{ name: "Bats", value: "bats" },
|
||||
{ name: "Cats", value: "cats" },
|
||||
{ name: "Mats", value: "mats" }
|
||||
{
|
||||
name: "Hats",
|
||||
value: "hats"
|
||||
},
|
||||
{
|
||||
name: "Bats",
|
||||
value: "bats"
|
||||
},
|
||||
{
|
||||
name: "Cats",
|
||||
value: "cats"
|
||||
},
|
||||
{
|
||||
name: "Mats",
|
||||
value: "mats"
|
||||
}
|
||||
],
|
||||
key: "aChoice"
|
||||
},
|
||||
@ -164,10 +175,22 @@ define(
|
||||
control: "select",
|
||||
required: true,
|
||||
options: [
|
||||
{ name: "Hats", value: "hats" },
|
||||
{ name: "Bats", value: "bats" },
|
||||
{ name: "Cats", value: "cats" },
|
||||
{ name: "Mats", value: "mats" }
|
||||
{
|
||||
name: "Hats",
|
||||
value: "hats"
|
||||
},
|
||||
{
|
||||
name: "Bats",
|
||||
value: "bats"
|
||||
},
|
||||
{
|
||||
name: "Cats",
|
||||
value: "cats"
|
||||
},
|
||||
{
|
||||
name: "Mats",
|
||||
value: "mats"
|
||||
}
|
||||
],
|
||||
key: "aRequiredChoice"
|
||||
}
|
||||
|
@ -28,9 +28,20 @@ define([
|
||||
domain: 2
|
||||
}
|
||||
},
|
||||
// Need to enable "LocalTimeSystem" plugin to make use of this
|
||||
// {
|
||||
// key: "local",
|
||||
// name: "Time",
|
||||
// format: "local-format",
|
||||
// source: "utc",
|
||||
// hints: {
|
||||
// domain: 3
|
||||
// }
|
||||
// },
|
||||
{
|
||||
key: "sin",
|
||||
name: "Sine",
|
||||
unit: "Hz",
|
||||
formatString: '%0.2f',
|
||||
hints: {
|
||||
range: 1
|
||||
@ -39,6 +50,7 @@ define([
|
||||
{
|
||||
key: "cos",
|
||||
name: "Cosine",
|
||||
unit: "deg",
|
||||
formatString: '%0.2f',
|
||||
hints: {
|
||||
range: 2
|
||||
@ -61,6 +73,15 @@ define([
|
||||
domain: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "local",
|
||||
name: "Time",
|
||||
format: "utc",
|
||||
source: "utc",
|
||||
hints: {
|
||||
domain: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "state",
|
||||
source: "value",
|
||||
@ -89,14 +110,14 @@ define([
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function GeneratorMetadataProvider() {
|
||||
|
||||
}
|
||||
|
||||
GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) {
|
||||
return METADATA_BY_TYPE.hasOwnProperty(domainObject.type);
|
||||
return Object.prototype.hasOwnProperty.call(METADATA_BY_TYPE, domainObject.type);
|
||||
};
|
||||
|
||||
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
|
||||
|
@ -62,18 +62,22 @@ define([
|
||||
var workerRequest = {};
|
||||
|
||||
props.forEach(function (prop) {
|
||||
if (domainObject.telemetry && domainObject.telemetry.hasOwnProperty(prop)) {
|
||||
if (domainObject.telemetry && Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)) {
|
||||
workerRequest[prop] = domainObject.telemetry[prop];
|
||||
}
|
||||
if (request && request.hasOwnProperty(prop)) {
|
||||
|
||||
if (request && Object.prototype.hasOwnProperty.call(request, prop)) {
|
||||
workerRequest[prop] = request[prop];
|
||||
}
|
||||
if (!workerRequest.hasOwnProperty(prop)) {
|
||||
|
||||
if (!Object.prototype.hasOwnProperty.call(workerRequest, prop)) {
|
||||
workerRequest[prop] = REQUEST_DEFAULTS[prop];
|
||||
}
|
||||
|
||||
workerRequest[prop] = Number(workerRequest[prop]);
|
||||
});
|
||||
workerRequest.name = domainObject.name;
|
||||
|
||||
return workerRequest;
|
||||
};
|
||||
|
||||
@ -81,11 +85,13 @@ define([
|
||||
var workerRequest = this.makeWorkerRequest(domainObject, request);
|
||||
workerRequest.start = request.start;
|
||||
workerRequest.end = request.end;
|
||||
|
||||
return this.workerInterface.request(workerRequest);
|
||||
};
|
||||
|
||||
GeneratorProvider.prototype.subscribe = function (domainObject, callback) {
|
||||
var workerRequest = this.makeWorkerRequest(domainObject, {});
|
||||
|
||||
return this.workerInterface.subscribe(workerRequest, callback);
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
|
||||
@ -78,12 +77,15 @@ define([
|
||||
if (datum[range] > RED[range]) {
|
||||
return LIMITS.rh;
|
||||
}
|
||||
|
||||
if (datum[range] < -RED[range]) {
|
||||
return LIMITS.rl;
|
||||
}
|
||||
|
||||
if (datum[range] > YELLOW[range]) {
|
||||
return LIMITS.yh;
|
||||
}
|
||||
|
||||
if (datum[range] < -YELLOW[range]) {
|
||||
return LIMITS.yl;
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ define([
|
||||
var interval = setInterval(function () {
|
||||
var now = Date.now();
|
||||
var datum = pointForTimestamp(now, duration, domainObject.name);
|
||||
datum.value += "";
|
||||
datum.value = String(datum.value);
|
||||
callback(datum);
|
||||
}, duration);
|
||||
|
||||
@ -57,7 +57,6 @@ define([
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
StateGeneratorProvider.prototype.supportsRequest = function (domainObject, options) {
|
||||
return domainObject.type === 'example.state-generator';
|
||||
};
|
||||
@ -69,11 +68,13 @@ define([
|
||||
if (options.strategy === 'latest' || options.size === 1) {
|
||||
start = end;
|
||||
}
|
||||
|
||||
var data = [];
|
||||
while (start <= end && data.length < 5000) {
|
||||
data.push(pointForTimestamp(start, duration, domainObject.name));
|
||||
start += duration;
|
||||
}
|
||||
|
||||
return Promise.resolve(data);
|
||||
};
|
||||
|
||||
|
@ -72,13 +72,16 @@ define([
|
||||
});
|
||||
var messageId;
|
||||
|
||||
let self = this;
|
||||
function callback(message) {
|
||||
if (message.error) {
|
||||
deferred.reject(message.error);
|
||||
} else {
|
||||
deferred.resolve(message.data);
|
||||
}
|
||||
delete this.callbacks[messageId];
|
||||
|
||||
delete self.callbacks[messageId];
|
||||
|
||||
}
|
||||
|
||||
messageId = this.dispatch('request', request, callback.bind(this));
|
||||
@ -101,8 +104,5 @@ define([
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
return WorkerInterface;
|
||||
});
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2017, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -20,8 +20,6 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/*global self*/
|
||||
|
||||
(function () {
|
||||
|
||||
var FIFTEEN_MINUTES = 15 * 60 * 1000;
|
||||
@ -64,13 +62,14 @@
|
||||
data: {
|
||||
name: data.name,
|
||||
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),
|
||||
cos: cos(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness)
|
||||
}
|
||||
});
|
||||
nextStep += step;
|
||||
}
|
||||
|
||||
return nextStep;
|
||||
}
|
||||
|
||||
@ -87,6 +86,7 @@
|
||||
if (request.end === undefined) {
|
||||
request.end = Date.now();
|
||||
}
|
||||
|
||||
if (request.start === undefined) {
|
||||
request.start = request.end - FIFTEEN_MINUTES;
|
||||
}
|
||||
@ -110,11 +110,12 @@
|
||||
data.push({
|
||||
name: request.name,
|
||||
utc: nextStep,
|
||||
yesterday: nextStep - 60*60*24*1000,
|
||||
yesterday: nextStep - 60 * 60 * 24 * 1000,
|
||||
sin: sin(nextStep, period, amplitude, offset, phase, randomness),
|
||||
cos: cos(nextStep, period, amplitude, offset, phase, randomness)
|
||||
});
|
||||
}
|
||||
|
||||
self.postMessage({
|
||||
id: message.id,
|
||||
data: data
|
||||
@ -122,13 +123,13 @@
|
||||
}
|
||||
|
||||
function cos(timestamp, period, amplitude, offset, phase, randomness) {
|
||||
return amplitude *
|
||||
Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
||||
return amplitude
|
||||
* Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
||||
}
|
||||
|
||||
function sin(timestamp, period, amplitude, offset, phase, randomness) {
|
||||
return amplitude *
|
||||
Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
||||
return amplitude
|
||||
* Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
|
||||
}
|
||||
|
||||
function sendError(error, message) {
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./GeneratorProvider",
|
||||
@ -56,7 +55,7 @@ define([
|
||||
initialize: function (object) {
|
||||
object.telemetry = {
|
||||
duration: 5
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/ExampleIdentityService"
|
||||
@ -29,7 +28,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/identity",
|
||||
name: "example/identity",
|
||||
definition: {
|
||||
"extensions": {
|
||||
"components": [
|
||||
|
@ -19,32 +19,35 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
var DEFAULT_IDENTITY = { key: "user", name: "Example User" },
|
||||
var DEFAULT_IDENTITY = {
|
||||
key: "user",
|
||||
name: "Example User"
|
||||
},
|
||||
DIALOG_STRUCTURE = {
|
||||
name: "Identify Yourself",
|
||||
sections: [{ rows: [
|
||||
{
|
||||
name: "User ID",
|
||||
control: "textfield",
|
||||
key: "key",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "Human name",
|
||||
control: "textfield",
|
||||
key: "name",
|
||||
required: true
|
||||
}
|
||||
]}]
|
||||
sections: [{
|
||||
rows: [
|
||||
{
|
||||
name: "User ID",
|
||||
control: "textfield",
|
||||
key: "key",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "Human name",
|
||||
control: "textfield",
|
||||
key: "name",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
}]
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Example implementation of an identity service. This prompts the
|
||||
* user to enter a name and user ID; in a more realistic
|
||||
@ -77,14 +80,14 @@ define(
|
||||
*/
|
||||
ExampleIdentityProvider.prototype.returnUser = function (user) {
|
||||
return this.user = user;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
ExampleIdentityProvider.prototype.returnUndefined = function () {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
|
||||
return ExampleIdentityProvider;
|
||||
}
|
||||
|
@ -85,28 +85,28 @@ define([
|
||||
data.push(pointForTimestamp(start, domainObject.name));
|
||||
start += 5000;
|
||||
}
|
||||
|
||||
return Promise.resolve(data);
|
||||
}
|
||||
};
|
||||
|
||||
var ladProvider = {
|
||||
supportsRequest: function (domainObject, options) {
|
||||
return domainObject.type === 'example.imagery' &&
|
||||
options.strategy === 'latest';
|
||||
return domainObject.type === 'example.imagery'
|
||||
&& options.strategy === 'latest';
|
||||
},
|
||||
request: function (domainObject, options) {
|
||||
return Promise.resolve([pointForTimestamp(Date.now(), domainObject.name)]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return function install(openmct) {
|
||||
openmct.types.addType('example.imagery', {
|
||||
key: 'example.imagery',
|
||||
name: 'Example Imagery',
|
||||
cssClass: 'icon-image',
|
||||
description: 'For development use. Creates example imagery ' +
|
||||
'data that mimics a live imagery stream.',
|
||||
description: 'For development use. Creates example imagery '
|
||||
+ 'data that mimics a live imagery stream.',
|
||||
creatable: true,
|
||||
initialize: function (object) {
|
||||
object.telemetry = {
|
||||
@ -140,7 +140,7 @@ define([
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -19,13 +19,12 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([], function () {
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/mobile",
|
||||
name: "example/mobile",
|
||||
definition: {
|
||||
"name": "Mobile",
|
||||
"description": "Allows elements with pertinence to mobile usage and development",
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/RemsTelemetryServerAdapter",
|
||||
@ -31,14 +30,15 @@ define([
|
||||
RemsTelemetryProvider
|
||||
) {
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/msl",
|
||||
name: "example/msl",
|
||||
definition: {
|
||||
"name" : "Mars Science Laboratory Data Adapter",
|
||||
"extensions" : {
|
||||
"name": "Mars Science Laboratory Data Adapter",
|
||||
"extensions": {
|
||||
"types": [
|
||||
{
|
||||
"name":"Mars Science Laboratory",
|
||||
"name": "Mars Science Laboratory",
|
||||
"key": "msl.curiosity",
|
||||
"cssClass": "icon-object"
|
||||
},
|
||||
@ -89,7 +89,7 @@ define([
|
||||
],
|
||||
"services": [
|
||||
{
|
||||
"key":"rems.adapter",
|
||||
"key": "rems.adapter",
|
||||
"implementation": RemsTelemetryServerAdapter,
|
||||
"depends": ["$http", "$log", "REMS_WS_URL"]
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -38,7 +37,7 @@ define(
|
||||
"identifier": "msl",
|
||||
"instruments": [
|
||||
{
|
||||
"name":"rems",
|
||||
"name": "rems",
|
||||
"identifier": "rems",
|
||||
"measurements": [
|
||||
{
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
function () {
|
||||
@ -81,6 +80,7 @@ define(
|
||||
(dictionary.instruments || []).forEach(function (instrument) {
|
||||
addInstrument(instrument, "msl:curiosity");
|
||||
});
|
||||
|
||||
return models;
|
||||
}
|
||||
|
||||
@ -90,6 +90,7 @@ define(
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return RemsTelemetryModelProvider;
|
||||
}
|
||||
);
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define */
|
||||
define (
|
||||
['./RemsTelemetrySeries'],
|
||||
function (RemsTelemetrySeries) {
|
||||
@ -74,6 +73,7 @@ define (
|
||||
RemsTelemetryProvider.prototype.subscribe = function (callback, requests) {
|
||||
return function () {};
|
||||
};
|
||||
|
||||
RemsTelemetryProvider.prototype.unsubscribe = function (callback, requests) {
|
||||
return function () {};
|
||||
};
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define */
|
||||
define(
|
||||
function () {
|
||||
"use strict";
|
||||
@ -57,6 +56,7 @@ define(
|
||||
RemsTelemetrySeries.prototype.getPointCount = function () {
|
||||
return this.data.length;
|
||||
};
|
||||
|
||||
/**
|
||||
* The domain value at the given index. The Rems telemetry data is
|
||||
* time ordered, so the domain value is the time stamp of each data
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
/*jslint es5: true */
|
||||
|
||||
define(
|
||||
@ -95,28 +94,32 @@ define(
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
function fallbackToLocal() {
|
||||
self.$log.warn("Loading REMS data failed, probably due to" +
|
||||
" cross origin policy. Falling back to local data");
|
||||
self.$log.warn("Loading REMS data failed, probably due to"
|
||||
+ " cross origin policy. Falling back to local data");
|
||||
|
||||
return self.$http.get(self.localDataURI);
|
||||
}
|
||||
|
||||
//Filter results to match request parameters
|
||||
function filterResults(results) {
|
||||
return results.filter(function (result) {
|
||||
return result.date >= (request.start || Number.MIN_VALUE) &&
|
||||
result.date <= (request.end || Number.MAX_VALUE);
|
||||
return result.date >= (request.start || Number.MIN_VALUE)
|
||||
&& result.date <= (request.end || Number.MAX_VALUE);
|
||||
});
|
||||
}
|
||||
|
||||
function packageAndResolve(results) {
|
||||
return {id: id, values: results};
|
||||
return {
|
||||
id: id,
|
||||
values: results
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
return (this.promise = this.promise || this.$http.get(this.REMS_WS_URL))
|
||||
.catch(fallbackToLocal)
|
||||
.then(processResponse)
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/DialogLaunchController",
|
||||
@ -39,7 +38,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/notifications",
|
||||
name: "example/notifications",
|
||||
definition: {
|
||||
"extensions": {
|
||||
"templates": [
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -91,7 +90,6 @@ define(
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Demonstrates launching an error dialog
|
||||
*/
|
||||
@ -132,9 +130,9 @@ define(
|
||||
var dialog,
|
||||
model = {
|
||||
title: "Info Dialog Example",
|
||||
actionText: "This is an example of a blocking info" +
|
||||
" dialog. This dialog can be used to draw the user's" +
|
||||
" attention to an event.",
|
||||
actionText: "This is an example of a blocking info"
|
||||
+ " dialog. This dialog can be used to draw the user's"
|
||||
+ " attention to an event.",
|
||||
severity: "info",
|
||||
primaryOption: {
|
||||
label: "OK",
|
||||
@ -153,6 +151,7 @@ define(
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return DialogLaunchController;
|
||||
}
|
||||
);
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,window*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -42,9 +41,11 @@ define(
|
||||
DialogLaunchIndicator.prototype.getGlyphClass = function () {
|
||||
return 'ok';
|
||||
};
|
||||
|
||||
DialogLaunchIndicator.prototype.getText = function () {
|
||||
return "Launch test dialog";
|
||||
};
|
||||
|
||||
DialogLaunchIndicator.prototype.getDescription = function () {
|
||||
return "Launch test dialog";
|
||||
};
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -48,7 +47,8 @@ define(
|
||||
"Eros turpis, pulvinar turpis eros eu",
|
||||
"Lundium nascetur a, lectus montes ac, parturient in natoque, duis risus risus pulvinar pid rhoncus, habitasse auctor natoque!"
|
||||
];
|
||||
return actionTexts[Math.floor(Math.random()*3)];
|
||||
|
||||
return actionTexts[Math.floor(Math.random() * 3)];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -61,6 +61,7 @@ define(
|
||||
severity: "error"
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Launch a new notification with a severity of 'Alert'.
|
||||
*/
|
||||
@ -73,7 +74,6 @@ define(
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Launch a new notification with a progress bar that is updated
|
||||
* periodically, tracking an ongoing process.
|
||||
@ -93,10 +93,10 @@ define(
|
||||
* @param notification
|
||||
*/
|
||||
function incrementProgress() {
|
||||
progress = Math.min(100, Math.floor(progress + Math.random() * 30))
|
||||
let progressText = ["Estimated time" +
|
||||
" remaining:" +
|
||||
" about ", 60 - Math.floor((progress / 100) * 60), " seconds"].join(" ");
|
||||
progress = Math.min(100, Math.floor(progress + Math.random() * 30));
|
||||
let progressText = ["Estimated time"
|
||||
+ " remaining:"
|
||||
+ " about ", 60 - Math.floor((progress / 100) * 60), " seconds"].join(" ");
|
||||
notification.progress(progress, progressText);
|
||||
|
||||
if (progress < 100) {
|
||||
@ -120,6 +120,7 @@ define(
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return NotificationLaunchController;
|
||||
}
|
||||
);
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define,window*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -42,9 +41,11 @@ define(
|
||||
NotificationLaunchIndicator.prototype.getGlyphClass = function () {
|
||||
return 'ok';
|
||||
};
|
||||
|
||||
NotificationLaunchIndicator.prototype.getText = function () {
|
||||
return "Launch notification";
|
||||
};
|
||||
|
||||
NotificationLaunchIndicator.prototype.getDescription = function () {
|
||||
return "Launch notification";
|
||||
};
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/BrowserPersistenceProvider"
|
||||
@ -29,7 +28,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/persistence",
|
||||
name: "example/persistence",
|
||||
definition: {
|
||||
"extensions": {
|
||||
"components": [
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
/**
|
||||
* Stubbed implementation of a persistence provider,
|
||||
@ -30,8 +29,6 @@ define(
|
||||
function () {
|
||||
'use strict';
|
||||
|
||||
|
||||
|
||||
function BrowserPersistenceProvider($q, SPACE) {
|
||||
var spaces = SPACE ? [SPACE] : [],
|
||||
caches = {},
|
||||
@ -51,6 +48,7 @@ define(
|
||||
},
|
||||
listObjects: function (space) {
|
||||
var cache = caches[space];
|
||||
|
||||
return promises.as(
|
||||
cache ? Object.keys(cache) : null
|
||||
);
|
||||
@ -68,6 +66,7 @@ define(
|
||||
},
|
||||
readObject: function (space, key) {
|
||||
var cache = caches[space];
|
||||
|
||||
return promises.as(
|
||||
cache ? cache[key] : null
|
||||
);
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/ExamplePolicy"
|
||||
@ -29,7 +28,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/policy",
|
||||
name: "example/policy",
|
||||
definition: {
|
||||
"name": "Example Policy",
|
||||
"description": "Provides an example of using policies to prohibit actions.",
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -37,6 +36,7 @@ define(
|
||||
model = (domainObject && domainObject.getModel()) || {},
|
||||
name = model.name || "",
|
||||
metadata = action.getMetadata() || {};
|
||||
|
||||
return metadata.key !== 'remove' || name.indexOf('foo') < 0;
|
||||
}
|
||||
};
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/WatchIndicator",
|
||||
@ -31,7 +30,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/profiling",
|
||||
name: "example/profiling",
|
||||
definition: {
|
||||
"extensions": {
|
||||
"indicators": [
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define([
|
||||
"./src/ScratchPersistenceProvider"
|
||||
@ -29,7 +28,7 @@ define([
|
||||
"use strict";
|
||||
|
||||
return {
|
||||
name:"example/scratchpad",
|
||||
name: "example/scratchpad",
|
||||
definition: {
|
||||
"extensions": {
|
||||
"roots": [
|
||||
|
@ -20,8 +20,6 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
/*global define,window*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
@ -54,13 +52,14 @@ define(
|
||||
if (space === 'scratch') {
|
||||
this.table[key] = JSON.stringify(value);
|
||||
}
|
||||
|
||||
return this.$q.when(space === 'scratch');
|
||||
};
|
||||
|
||||
ScratchPersistenceProvider.prototype.readObject = function (space, key) {
|
||||
return this.$q.when(
|
||||
(space === 'scratch' && this.table[key]) ?
|
||||
JSON.parse(this.table[key]) : undefined
|
||||
(space === 'scratch' && this.table[key])
|
||||
? JSON.parse(this.table[key]) : undefined
|
||||
);
|
||||
};
|
||||
|
||||
@ -68,6 +67,7 @@ define(
|
||||
if (space === 'scratch') {
|
||||
delete this.table[key];
|
||||
}
|
||||
|
||||
return this.$q.when(space === 'scratch');
|
||||
};
|
||||
|
||||
|
@ -7,9 +7,9 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
msg: 'Hello world!'
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -17,6 +17,7 @@ function SimpleVuePlugin() {
|
||||
},
|
||||
view: function (domainObject) {
|
||||
var vm;
|
||||
|
||||
return {
|
||||
show: function (container) {
|
||||
vm = new Vue(HelloWorld);
|
||||
@ -29,7 +30,7 @@ function SimpleVuePlugin() {
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default SimpleVuePlugin
|
||||
export default SimpleVuePlugin;
|
||||
|
@ -22,31 +22,111 @@ define([
|
||||
menusTemplate
|
||||
) {
|
||||
return {
|
||||
name:"example/styleguide",
|
||||
name: "example/styleguide",
|
||||
definition: {
|
||||
"name": "Open MCT Style Guide",
|
||||
"description": "Examples and documentation illustrating UI styles in use in Open MCT.",
|
||||
"extensions":
|
||||
{
|
||||
"types": [
|
||||
{ "key": "styleguide.intro", "name": "Introduction", "cssClass": "icon-page", "description": "Introduction and overview to the style guide" },
|
||||
{ "key": "styleguide.standards", "name": "Standards", "cssClass": "icon-page", "description": "" },
|
||||
{ "key": "styleguide.colors", "name": "Colors", "cssClass": "icon-page", "description": "" },
|
||||
{ "key": "styleguide.status", "name": "status", "cssClass": "icon-page", "description": "Limits, telemetry paused, etc." },
|
||||
{ "key": "styleguide.glyphs", "name": "Glyphs", "cssClass": "icon-page", "description": "Glyphs overview" },
|
||||
{ "key": "styleguide.controls", "name": "Controls", "cssClass": "icon-page", "description": "Buttons, selects, HTML controls" },
|
||||
{ "key": "styleguide.input", "name": "Text Inputs", "cssClass": "icon-page", "description": "Various text inputs" },
|
||||
{ "key": "styleguide.menus", "name": "Menus", "cssClass": "icon-page", "description": "Context menus, dropdowns" }
|
||||
{
|
||||
"key": "styleguide.intro",
|
||||
"name": "Introduction",
|
||||
"cssClass": "icon-page",
|
||||
"description": "Introduction and overview to the style guide"
|
||||
},
|
||||
{
|
||||
"key": "styleguide.standards",
|
||||
"name": "Standards",
|
||||
"cssClass": "icon-page",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"key": "styleguide.colors",
|
||||
"name": "Colors",
|
||||
"cssClass": "icon-page",
|
||||
"description": ""
|
||||
},
|
||||
{
|
||||
"key": "styleguide.status",
|
||||
"name": "status",
|
||||
"cssClass": "icon-page",
|
||||
"description": "Limits, telemetry paused, etc."
|
||||
},
|
||||
{
|
||||
"key": "styleguide.glyphs",
|
||||
"name": "Glyphs",
|
||||
"cssClass": "icon-page",
|
||||
"description": "Glyphs overview"
|
||||
},
|
||||
{
|
||||
"key": "styleguide.controls",
|
||||
"name": "Controls",
|
||||
"cssClass": "icon-page",
|
||||
"description": "Buttons, selects, HTML controls"
|
||||
},
|
||||
{
|
||||
"key": "styleguide.input",
|
||||
"name": "Text Inputs",
|
||||
"cssClass": "icon-page",
|
||||
"description": "Various text inputs"
|
||||
},
|
||||
{
|
||||
"key": "styleguide.menus",
|
||||
"name": "Menus",
|
||||
"cssClass": "icon-page",
|
||||
"description": "Context menus, dropdowns"
|
||||
}
|
||||
],
|
||||
"views": [
|
||||
{ "key": "styleguide.intro", "type": "styleguide.intro", "template": introTemplate, "editable": false },
|
||||
{ "key": "styleguide.standards", "type": "styleguide.standards", "template": standardsTemplate, "editable": false },
|
||||
{ "key": "styleguide.colors", "type": "styleguide.colors", "template": colorsTemplate, "editable": false },
|
||||
{ "key": "styleguide.status", "type": "styleguide.status", "template": statusTemplate, "editable": false },
|
||||
{ "key": "styleguide.glyphs", "type": "styleguide.glyphs", "template": glyphsTemplate, "editable": false },
|
||||
{ "key": "styleguide.controls", "type": "styleguide.controls", "template": controlsTemplate, "editable": false },
|
||||
{ "key": "styleguide.input", "type": "styleguide.input", "template": inputTemplate, "editable": false },
|
||||
{ "key": "styleguide.menus", "type": "styleguide.menus", "template": menusTemplate, "editable": false }
|
||||
{
|
||||
"key": "styleguide.intro",
|
||||
"type": "styleguide.intro",
|
||||
"template": introTemplate,
|
||||
"editable": false
|
||||
},
|
||||
{
|
||||
"key": "styleguide.standards",
|
||||
"type": "styleguide.standards",
|
||||
"template": standardsTemplate,
|
||||
"editable": false
|
||||
},
|
||||
{
|
||||
"key": "styleguide.colors",
|
||||
"type": "styleguide.colors",
|
||||
"template": colorsTemplate,
|
||||
"editable": false
|
||||
},
|
||||
{
|
||||
"key": "styleguide.status",
|
||||
"type": "styleguide.status",
|
||||
"template": statusTemplate,
|
||||
"editable": false
|
||||
},
|
||||
{
|
||||
"key": "styleguide.glyphs",
|
||||
"type": "styleguide.glyphs",
|
||||
"template": glyphsTemplate,
|
||||
"editable": false
|
||||
},
|
||||
{
|
||||
"key": "styleguide.controls",
|
||||
"type": "styleguide.controls",
|
||||
"template": controlsTemplate,
|
||||
"editable": false
|
||||
},
|
||||
{
|
||||
"key": "styleguide.input",
|
||||
"type": "styleguide.input",
|
||||
"template": inputTemplate,
|
||||
"editable": false
|
||||
},
|
||||
{
|
||||
"key": "styleguide.menus",
|
||||
"type": "styleguide.menus",
|
||||
"template": menusTemplate,
|
||||
"editable": false
|
||||
}
|
||||
],
|
||||
"roots": [
|
||||
{
|
||||
@ -56,7 +136,7 @@ define([
|
||||
"models": [
|
||||
{
|
||||
"id": "styleguide:home",
|
||||
"priority" : "preferred",
|
||||
"priority": "preferred",
|
||||
"model": {
|
||||
"type": "folder",
|
||||
"name": "Style Guide Home",
|
||||
@ -73,7 +153,7 @@ define([
|
||||
},
|
||||
{
|
||||
"id": "styleguide:ui-elements",
|
||||
"priority" : "preferred",
|
||||
"priority": "preferred",
|
||||
"model": {
|
||||
"type": "folder",
|
||||
"name": "UI Elements",
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -30,14 +29,46 @@ define(
|
||||
var pages = {};
|
||||
|
||||
// Add pages
|
||||
pages.intro = { name: "Introduction", type: "styleguide.intro", location: "styleguide:home" };
|
||||
pages.standards = { name: "Standards", type: "styleguide.standards", location: "styleguide:home" };
|
||||
pages.colors = { name: "Colors", type: "styleguide.colors", location: "styleguide:home" };
|
||||
pages.glyphs = { name: "Glyphs", type: "styleguide.glyphs", location: "styleguide:home" };
|
||||
pages.status = { name: "Status Indication", type: "styleguide.status", location: "styleguide:home" };
|
||||
pages.controls = { name: "Controls", type: "styleguide.controls", location: "styleguide:ui-elements" };
|
||||
pages.input = { name: "Text Inputs", type: "styleguide.input", location: "styleguide:ui-elements" };
|
||||
pages.menus = { name: "Menus", type: "styleguide.menus", location: "styleguide:ui-elements" };
|
||||
pages.intro = {
|
||||
name: "Introduction",
|
||||
type: "styleguide.intro",
|
||||
location: "styleguide:home"
|
||||
};
|
||||
pages.standards = {
|
||||
name: "Standards",
|
||||
type: "styleguide.standards",
|
||||
location: "styleguide:home"
|
||||
};
|
||||
pages.colors = {
|
||||
name: "Colors",
|
||||
type: "styleguide.colors",
|
||||
location: "styleguide:home"
|
||||
};
|
||||
pages.glyphs = {
|
||||
name: "Glyphs",
|
||||
type: "styleguide.glyphs",
|
||||
location: "styleguide:home"
|
||||
};
|
||||
pages.status = {
|
||||
name: "Status Indication",
|
||||
type: "styleguide.status",
|
||||
location: "styleguide:home"
|
||||
};
|
||||
pages.controls = {
|
||||
name: "Controls",
|
||||
type: "styleguide.controls",
|
||||
location: "styleguide:ui-elements"
|
||||
};
|
||||
pages.input = {
|
||||
name: "Text Inputs",
|
||||
type: "styleguide.input",
|
||||
location: "styleguide:ui-elements"
|
||||
};
|
||||
pages.menus = {
|
||||
name: "Menus",
|
||||
type: "styleguide.menus",
|
||||
location: "styleguide:ui-elements"
|
||||
};
|
||||
|
||||
return {
|
||||
getModels: function () {
|
||||
@ -46,6 +77,6 @@ define(
|
||||
};
|
||||
}
|
||||
|
||||
return ExampleStyleGuideModelProvider
|
||||
return ExampleStyleGuideModelProvider;
|
||||
}
|
||||
);
|
||||
|
45
index.html
45
index.html
@ -34,8 +34,8 @@
|
||||
<body>
|
||||
</body>
|
||||
<script>
|
||||
const FIVE_MINUTES = 5 * 60 * 1000;
|
||||
const THIRTY_MINUTES = 30 * 60 * 1000;
|
||||
const THIRTY_SECONDS = 30 * 1000;
|
||||
const THIRTY_MINUTES = THIRTY_SECONDS * 60;
|
||||
|
||||
[
|
||||
'example/eventGenerator'
|
||||
@ -63,7 +63,39 @@
|
||||
bounds: {
|
||||
start: Date.now() - THIRTY_MINUTES,
|
||||
end: Date.now()
|
||||
}
|
||||
},
|
||||
// commonly used bounds can be stored in history
|
||||
// bounds (start and end) can accept either a milliseconds number
|
||||
// or a callback function returning a milliseconds number
|
||||
// a function is useful for invoking Date.now() at exact moment of preset selection
|
||||
presets: [
|
||||
{
|
||||
label: 'Last Day',
|
||||
bounds: {
|
||||
start: () => Date.now() - 1000 * 60 * 60 * 24,
|
||||
end: () => Date.now()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Last 2 hours',
|
||||
bounds: {
|
||||
start: () => Date.now() - 1000 * 60 * 60 * 2,
|
||||
end: () => Date.now()
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Last hour',
|
||||
bounds: {
|
||||
start: () => Date.now() - 1000 * 60 * 60,
|
||||
end: () => Date.now()
|
||||
}
|
||||
}
|
||||
],
|
||||
// maximum recent bounds to retain in conductor history
|
||||
records: 10,
|
||||
// maximum duration between start and end bounds
|
||||
// for utc-based time systems this is in milliseconds
|
||||
limit: 1000 * 60 * 60 * 24
|
||||
},
|
||||
{
|
||||
name: "Realtime",
|
||||
@ -71,7 +103,7 @@
|
||||
clock: 'local',
|
||||
clockOffsets: {
|
||||
start: - THIRTY_MINUTES,
|
||||
end: FIVE_MINUTES
|
||||
end: THIRTY_SECONDS
|
||||
}
|
||||
}
|
||||
]
|
||||
@ -81,7 +113,10 @@
|
||||
openmct.install(openmct.plugins.LADTable());
|
||||
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
|
||||
openmct.install(openmct.plugins.ObjectMigration());
|
||||
openmct.install(openmct.plugins.ClearData(['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked']));
|
||||
openmct.install(openmct.plugins.ClearData(
|
||||
['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked'],
|
||||
{indicator: true}
|
||||
));
|
||||
openmct.start();
|
||||
</script>
|
||||
</html>
|
||||
|
3
indexTest.js
Normal file
3
indexTest.js
Normal file
@ -0,0 +1,3 @@
|
||||
const testsContext = require.context('.', true, /\/(src|platform)\/.*Spec.js$/);
|
||||
|
||||
testsContext.keys().forEach(testsContext);
|
@ -23,7 +23,7 @@
|
||||
/*global module,process*/
|
||||
|
||||
const devMode = process.env.NODE_ENV !== 'production';
|
||||
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'ChromeHeadless'];
|
||||
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'FirefoxHeadless'];
|
||||
const coverageEnabled = process.env.COVERAGE === 'true';
|
||||
const reporters = ['progress', 'html'];
|
||||
|
||||
@ -52,12 +52,16 @@ module.exports = (config) => {
|
||||
basePath: '',
|
||||
frameworks: ['jasmine'],
|
||||
files: [
|
||||
'platform/**/*Spec.js',
|
||||
'src/**/*Spec.js'
|
||||
'indexTest.js'
|
||||
],
|
||||
port: 9876,
|
||||
reporters: reporters,
|
||||
browsers: browsers,
|
||||
client: {
|
||||
jasmine: {
|
||||
random: false
|
||||
}
|
||||
},
|
||||
customLaunchers: {
|
||||
ChromeDebugging: {
|
||||
base: 'Chrome',
|
||||
@ -82,19 +86,20 @@ module.exports = (config) => {
|
||||
reports: ['html', 'lcovonly', 'text-summary'],
|
||||
thresholds: {
|
||||
global: {
|
||||
lines: 62
|
||||
lines: 64
|
||||
}
|
||||
}
|
||||
},
|
||||
preprocessors: {
|
||||
'platform/**/*Spec.js': ['webpack', 'sourcemap'],
|
||||
'src/**/*Spec.js': ['webpack', 'sourcemap']
|
||||
'indexTest.js': ['webpack', 'sourcemap']
|
||||
},
|
||||
webpack: webpackConfig,
|
||||
webpackMiddleware: {
|
||||
stats: 'errors-only',
|
||||
logLevel: 'warn'
|
||||
},
|
||||
singleRun: true
|
||||
concurrency: 1,
|
||||
singleRun: true,
|
||||
browserNoActivityTimeout: 400000
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -32,6 +32,6 @@ if (document.currentScript) {
|
||||
|
||||
const MCT = require('./src/MCT');
|
||||
|
||||
var openmct = new MCT();
|
||||
const openmct = new MCT();
|
||||
|
||||
module.exports = openmct;
|
||||
|
39
package.json
39
package.json
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "openmct",
|
||||
"version": "1.0.0-snapshot",
|
||||
"version": "1.3.0-SNAPSHOT",
|
||||
"description": "The Open MCT core platform",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"angular": "1.7.9",
|
||||
"angular": ">=1.8.0",
|
||||
"angular-route": "1.4.14",
|
||||
"babel-eslint": "8.2.6",
|
||||
"babel-eslint": "10.0.3",
|
||||
"comma-separated-values": "^3.6.4",
|
||||
"concurrently": "^3.6.1",
|
||||
"copy-webpack-plugin": "^4.5.2",
|
||||
@ -22,7 +22,7 @@
|
||||
"d3-selection": "1.3.x",
|
||||
"d3-time": "1.0.x",
|
||||
"d3-time-format": "2.1.x",
|
||||
"eslint": "5.2.0",
|
||||
"eslint": "7.0.0",
|
||||
"eslint-plugin-vue": "^6.0.0",
|
||||
"eslint-plugin-you-dont-need-lodash-underscore": "^6.10.0",
|
||||
"eventemitter3": "^1.2.0",
|
||||
@ -39,27 +39,28 @@
|
||||
"istanbul-instrumenter-loader": "^3.0.1",
|
||||
"jasmine-core": "^3.1.0",
|
||||
"jsdoc": "^3.3.2",
|
||||
"karma": "^2.0.3",
|
||||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-cli": "^1.0.1",
|
||||
"karma-coverage": "^1.1.2",
|
||||
"karma-coverage-istanbul-reporter": "^2.1.1",
|
||||
"karma-html-reporter": "^0.2.7",
|
||||
"karma-jasmine": "^1.1.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^3.0.0",
|
||||
"karma": "5.1.1",
|
||||
"karma-chrome-launcher": "3.1.0",
|
||||
"karma-firefox-launcher": "1.3.0",
|
||||
"karma-cli": "2.0.0",
|
||||
"karma-coverage": "2.0.3",
|
||||
"karma-coverage-istanbul-reporter": "3.0.3",
|
||||
"karma-html-reporter": "0.2.7",
|
||||
"karma-jasmine": "3.3.1",
|
||||
"karma-sourcemap-loader": "0.3.7",
|
||||
"karma-webpack": "4.0.2",
|
||||
"location-bar": "^3.0.1",
|
||||
"lodash": "^4.17.12",
|
||||
"markdown-toc": "^0.11.7",
|
||||
"marked": "^0.3.5",
|
||||
"mini-css-extract-plugin": "^0.4.1",
|
||||
"minimist": "^1.1.1",
|
||||
"minimist": "^1.2.5",
|
||||
"moment": "2.25.3",
|
||||
"moment-duration-format": "^2.2.2",
|
||||
"moment-timezone": "0.5.28",
|
||||
"node-bourbon": "^4.2.3",
|
||||
"node-sass": "^4.9.2",
|
||||
"painterro": "^0.2.65",
|
||||
"node-sass": "^4.14.1",
|
||||
"painterro": "^1.0.35",
|
||||
"printj": "^1.2.1",
|
||||
"raw-loader": "^0.5.1",
|
||||
"request": "^2.69.0",
|
||||
@ -84,10 +85,10 @@
|
||||
"build:prod": "cross-env NODE_ENV=production webpack",
|
||||
"build:dev": "webpack",
|
||||
"build:watch": "webpack --watch",
|
||||
"test": "karma start --single-run",
|
||||
"test": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --single-run",
|
||||
"test:debug": "cross-env NODE_ENV=debug karma start --no-single-run",
|
||||
"test:coverage": "./scripts/test-coverage.sh",
|
||||
"test:watch": "karma start --no-single-run",
|
||||
"test:coverage": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" COVERAGE=true karma start --single-run",
|
||||
"test:watch": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --no-single-run",
|
||||
"verify": "concurrently 'npm:test' 'npm:lint'",
|
||||
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
|
||||
"otherdoc": "node docs/gendocs.js --in docs/src --out dist/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'",
|
||||
|
@ -47,7 +47,7 @@ define([
|
||||
) {
|
||||
|
||||
return {
|
||||
name:"platform/commonUI/about",
|
||||
name: "platform/commonUI/about",
|
||||
definition: {
|
||||
"name": "About Open MCT",
|
||||
"extensions": {
|
||||
|
@ -20,7 +20,6 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Implements Open MCT's About dialog.
|
||||
* @namespace platform/commonUI/about
|
||||
|
@ -25,14 +25,20 @@ define(
|
||||
function (AboutController) {
|
||||
|
||||
describe("The About controller", function () {
|
||||
var testVersions,
|
||||
mockWindow,
|
||||
controller;
|
||||
let testVersions;
|
||||
let mockWindow;
|
||||
let controller;
|
||||
|
||||
beforeEach(function () {
|
||||
testVersions = [
|
||||
{ name: "Some name", value: "1.2.3" },
|
||||
{ name: "Some other name", value: "3.2.1" }
|
||||
{
|
||||
name: "Some name",
|
||||
value: "1.2.3"
|
||||
},
|
||||
{
|
||||
name: "Some other name",
|
||||
value: "3.2.1"
|
||||
}
|
||||
];
|
||||
mockWindow = jasmine.createSpyObj("$window", ["open"]);
|
||||
controller = new AboutController(testVersions, mockWindow);
|
||||
@ -50,8 +56,6 @@ define(
|
||||
controller.openLicenses();
|
||||
expect(mockWindow.open).toHaveBeenCalledWith("#/licenses");
|
||||
});
|
||||
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ define([
|
||||
) {
|
||||
|
||||
return {
|
||||
name:"platform/commonUI/browse",
|
||||
name: "platform/commonUI/browse",
|
||||
definition: {
|
||||
"extensions": {
|
||||
"routes": [
|
||||
|
@ -46,6 +46,7 @@ define(
|
||||
NavigateAction.prototype.perform = function () {
|
||||
if (this.navigationService.shouldNavigate()) {
|
||||
this.navigationService.setNavigation(this.domainObject, true);
|
||||
|
||||
return Promise.resolve({});
|
||||
}
|
||||
|
||||
|
@ -69,8 +69,10 @@ define(
|
||||
NavigationService.prototype.setNavigation = function (domainObject, force) {
|
||||
if (force) {
|
||||
this.doNavigation(domainObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (this.navigated === domainObject) {
|
||||
return true;
|
||||
}
|
||||
@ -81,6 +83,7 @@ define(
|
||||
}
|
||||
|
||||
this.doNavigation(domainObject);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -120,6 +123,7 @@ define(
|
||||
*/
|
||||
NavigationService.prototype.shouldNavigate = function () {
|
||||
var doNotNavigate = this.shouldWarnBeforeNavigate();
|
||||
|
||||
return !doNotNavigate || this.$window.confirm(doNotNavigate);
|
||||
};
|
||||
|
||||
@ -135,6 +139,7 @@ define(
|
||||
*/
|
||||
NavigationService.prototype.checkBeforeNavigation = function (checkFn) {
|
||||
this.checks.push(checkFn);
|
||||
|
||||
return function removeCheck() {
|
||||
this.checks = this.checks.filter(function (fn) {
|
||||
return checkFn !== fn;
|
||||
@ -172,6 +177,7 @@ define(
|
||||
if (reasons.length) {
|
||||
return reasons.join('\n');
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
@ -186,6 +192,7 @@ define(
|
||||
if (shouldWarnBeforeNavigate) {
|
||||
return shouldWarnBeforeNavigate;
|
||||
}
|
||||
|
||||
if (this.oldUnload) {
|
||||
return this.oldUnload.apply(undefined, [].slice.apply(arguments));
|
||||
}
|
||||
|
@ -40,6 +40,7 @@ define([], function () {
|
||||
|
||||
function getParent(domainObject) {
|
||||
var context = domainObject.getCapability('context');
|
||||
|
||||
return context.getParent();
|
||||
}
|
||||
|
||||
|
@ -53,6 +53,7 @@ define([
|
||||
|
||||
it("sets navigation if it is allowed", function () {
|
||||
mockNavigationService.shouldNavigate.and.returnValue(true);
|
||||
|
||||
return action.perform()
|
||||
.then(function () {
|
||||
expect(mockNavigationService.setNavigation)
|
||||
@ -63,6 +64,7 @@ define([
|
||||
it("does not set navigation if it is not allowed", function () {
|
||||
mockNavigationService.shouldNavigate.and.returnValue(false);
|
||||
var onSuccess = jasmine.createSpy('onSuccess');
|
||||
|
||||
return action.perform()
|
||||
.then(onSuccess, function () {
|
||||
expect(onSuccess).not.toHaveBeenCalled();
|
||||
|
@ -79,7 +79,6 @@ define(
|
||||
navigationService.addListener(callback);
|
||||
navigationService.removeListener(callback);
|
||||
|
||||
|
||||
navigationService.setNavigation(testObject);
|
||||
expect(callback).not.toHaveBeenCalled();
|
||||
});
|
||||
|
@ -70,6 +70,7 @@ define([
|
||||
jasmine.createSpy('throttled-' + mockThrottledFns.length);
|
||||
mockThrottledFn.and.callFake(fn);
|
||||
mockThrottledFns.push(mockThrottledFn);
|
||||
|
||||
return mockThrottledFn;
|
||||
});
|
||||
mockTopic.and.returnValue(mockMutationTopic);
|
||||
@ -81,7 +82,7 @@ define([
|
||||
}[c];
|
||||
});
|
||||
mockDomainObject.hasCapability.and.callFake(function (c) {
|
||||
return !!mockDomainObject.getCapability(c);
|
||||
return Boolean(mockDomainObject.getCapability(c));
|
||||
});
|
||||
mockParentObject.getCapability.and.callFake(function (c) {
|
||||
return {
|
||||
@ -102,7 +103,6 @@ define([
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
it("listens for mutation with a throttled function", function () {
|
||||
expect(mockMutationTopic.listen)
|
||||
.toHaveBeenCalledWith(jasmine.any(Function));
|
||||
@ -129,8 +129,8 @@ define([
|
||||
});
|
||||
|
||||
[false, true].forEach(function (isEditRoot) {
|
||||
var caseName = isEditRoot ?
|
||||
"that are being edited" : "that are not being edited";
|
||||
var caseName = isEditRoot
|
||||
? "that are being edited" : "that are not being edited";
|
||||
|
||||
function itNavigatesAsExpected() {
|
||||
if (isOrphan && !isEditRoot) {
|
||||
|
@ -45,7 +45,7 @@ define([
|
||||
) {
|
||||
|
||||
return {
|
||||
name:"platform/commonUI/dialog",
|
||||
name: "platform/commonUI/dialog",
|
||||
definition: {
|
||||
"extensions": {
|
||||
"services": [
|
||||
|
@ -31,13 +31,13 @@
|
||||
</mct-form>
|
||||
</div>
|
||||
<div class="c-overlay__button-bar">
|
||||
<a class='c-button c-button--major'
|
||||
<button class='c-button c-button--major'
|
||||
ng-class="{ disabled: !createForm.$valid }"
|
||||
ng-click="ngModel.confirm()">
|
||||
OK
|
||||
</a>
|
||||
<a class='c-button '
|
||||
</button>
|
||||
<button class='c-button '
|
||||
ng-click="ngModel.cancel()">
|
||||
Cancel
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -31,13 +31,13 @@
|
||||
</mct-include>
|
||||
</div>
|
||||
<div class="c-overlay__button-bar">
|
||||
<a ng-repeat="option in ngModel.dialog.options"
|
||||
<button ng-repeat="option in ngModel.dialog.options"
|
||||
href=''
|
||||
class="s-button lg"
|
||||
title="{{option.description}}"
|
||||
ng-click="ngModel.confirm(option.key)"
|
||||
ng-class="{ major: $first, subtle: !$first }">
|
||||
{{option.name}}
|
||||
</a>
|
||||
</button>
|
||||
</div>
|
||||
</mct-container>
|
||||
|
@ -24,7 +24,7 @@
|
||||
<div class="c-overlay__outer">
|
||||
<button ng-click="ngModel.cancel()"
|
||||
ng-if="ngModel.cancel"
|
||||
class="c-click-icon c-overlay__close-button icon-x-in-circle"></button>
|
||||
class="c-click-icon c-overlay__close-button icon-x"></button>
|
||||
<div class="c-overlay__contents" ng-transclude></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -28,7 +28,6 @@ define(
|
||||
// the a specific template that can be included via mct-include
|
||||
var TEMPLATE = '<mct-include ng-model="overlay" key="key" ng-class="typeClass"></mct-include>';
|
||||
|
||||
|
||||
/**
|
||||
* The OverlayService is responsible for pre-pending templates to
|
||||
* the body of the document, which is useful for displaying templates
|
||||
@ -53,6 +52,7 @@ define(
|
||||
this.findBody = function () {
|
||||
return $document.find('body');
|
||||
};
|
||||
|
||||
this.newScope = function () {
|
||||
return $rootScope.$new();
|
||||
};
|
||||
|
@ -129,8 +129,8 @@ define(
|
||||
);
|
||||
});
|
||||
|
||||
it("invokes the overlay service with the correct parameters when" +
|
||||
" a blocking dialog is requested", function () {
|
||||
it("invokes the overlay service with the correct parameters when"
|
||||
+ " a blocking dialog is requested", function () {
|
||||
var dialogModel = {};
|
||||
expect(dialogService.showBlockingMessage(dialogModel)).not.toBe(false);
|
||||
expect(mockOverlayService.createOverlay).toHaveBeenCalledWith(
|
||||
|
@ -48,7 +48,7 @@ define(
|
||||
mockScope = jasmine.createSpyObj("scope", ["$destroy"]);
|
||||
mockTimeout = function (callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
mockDocument.find.and.returnValue(mockBody);
|
||||
mockCompile.and.returnValue(mockTemplate);
|
||||
|
@ -56,6 +56,7 @@ define(
|
||||
//navigate back to parent because nothing to show.
|
||||
return domainObject.getCapability("location").getOriginal().then(function (original) {
|
||||
parent = original.getCapability("context").getParent();
|
||||
|
||||
return parent.getCapability("action").perform("navigate");
|
||||
});
|
||||
}
|
||||
@ -78,9 +79,10 @@ define(
|
||||
*/
|
||||
CancelAction.appliesTo = function (context) {
|
||||
var domainObject = (context || {}).domainObject;
|
||||
return domainObject !== undefined &&
|
||||
domainObject.hasCapability('editor') &&
|
||||
domainObject.getCapability('editor').isEditContextRoot();
|
||||
|
||||
return domainObject !== undefined
|
||||
&& domainObject.hasCapability('editor')
|
||||
&& domainObject.getCapability('editor').isEditContextRoot();
|
||||
};
|
||||
|
||||
return CancelAction;
|
||||
|
@ -91,9 +91,9 @@ define(
|
||||
|
||||
// Only allow editing of types that support it and are not already
|
||||
// being edited
|
||||
return type && type.hasFeature('creation') &&
|
||||
domainObject.hasCapability('editor') &&
|
||||
!domainObject.getCapability('editor').isEditContextRoot();
|
||||
return type && type.hasFeature('creation')
|
||||
&& domainObject.hasCapability('editor')
|
||||
&& !domainObject.getCapability('editor').isEditContextRoot();
|
||||
};
|
||||
|
||||
return EditAction;
|
||||
|
@ -24,7 +24,6 @@ define(
|
||||
[],
|
||||
function () {
|
||||
|
||||
|
||||
/**
|
||||
* Add one domain object to another's composition.
|
||||
* @constructor
|
||||
@ -42,8 +41,9 @@ define(
|
||||
|
||||
// Link these objects
|
||||
function doLink() {
|
||||
var composition = self.domainObject &&
|
||||
self.domainObject.getCapability('composition');
|
||||
var composition = self.domainObject
|
||||
&& self.domainObject.getCapability('composition');
|
||||
|
||||
return composition && composition.add(self.selectedObject);
|
||||
}
|
||||
|
||||
|
@ -81,10 +81,15 @@ define(
|
||||
* context.
|
||||
*/
|
||||
PropertiesAction.appliesTo = function (context) {
|
||||
|
||||
var domainObject = (context || {}).domainObject,
|
||||
type = domainObject && domainObject.getCapability('type'),
|
||||
creatable = type && type.hasFeature('creation');
|
||||
|
||||
if (domainObject && domainObject.model && domainObject.model.locked) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only allow creatable types to be edited
|
||||
return domainObject && creatable;
|
||||
};
|
||||
@ -94,4 +99,3 @@ define(
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
@ -51,6 +51,7 @@ define(
|
||||
// Property definition is same as form row definition
|
||||
var row = JSON.parse(JSON.stringify(property.getDefinition()));
|
||||
row.key = index;
|
||||
|
||||
return row;
|
||||
}).filter(function (row) {
|
||||
// Only show properties which are editable
|
||||
|
@ -86,10 +86,11 @@ define(
|
||||
*/
|
||||
SaveAction.appliesTo = function (context) {
|
||||
var domainObject = (context || {}).domainObject;
|
||||
return domainObject !== undefined &&
|
||||
domainObject.hasCapability('editor') &&
|
||||
domainObject.getCapability('editor').isEditContextRoot() &&
|
||||
domainObject.getModel().persisted !== undefined;
|
||||
|
||||
return domainObject !== undefined
|
||||
&& domainObject.hasCapability('editor')
|
||||
&& domainObject.getCapability('editor').isEditContextRoot()
|
||||
&& domainObject.getModel().persisted !== undefined;
|
||||
};
|
||||
|
||||
return SaveAction;
|
||||
|
@ -20,7 +20,6 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
define([
|
||||
'../creation/CreateWizard',
|
||||
'./SaveInProgressDialog'
|
||||
@ -50,6 +49,7 @@ function (
|
||||
this.injectObjectService = function () {
|
||||
this.objectService = $injector.get("objectService");
|
||||
};
|
||||
|
||||
this.dialogService = dialogService;
|
||||
this.copyService = copyService;
|
||||
this.notificationService = notificationService;
|
||||
@ -75,15 +75,10 @@ function (
|
||||
if (!this.objectService) {
|
||||
this.injectObjectService();
|
||||
}
|
||||
|
||||
return this.objectService;
|
||||
};
|
||||
|
||||
function resolveWith(object) {
|
||||
return function () {
|
||||
return object;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Save changes and conclude editing.
|
||||
*
|
||||
@ -101,7 +96,6 @@ function (
|
||||
SaveAsAction.prototype.save = function () {
|
||||
var self = this,
|
||||
domainObject = this.domainObject,
|
||||
copyService = this.copyService,
|
||||
dialog = new SaveInProgressDialog(this.dialogService),
|
||||
toUndirty = [];
|
||||
|
||||
@ -118,11 +112,13 @@ function (
|
||||
|
||||
function showBlockingDialog(object) {
|
||||
dialog.show();
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
function hideBlockingDialog(object) {
|
||||
dialog.hide();
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
@ -136,18 +132,22 @@ function (
|
||||
return fetchObject(object.getModel().location);
|
||||
}
|
||||
|
||||
function allowClone(objectToClone) {
|
||||
var allowed =
|
||||
(objectToClone.getId() === domainObject.getId()) ||
|
||||
objectToClone.getCapability('location').isOriginal();
|
||||
if (allowed) {
|
||||
toUndirty.push(objectToClone);
|
||||
}
|
||||
return allowed;
|
||||
function saveObject(parent) {
|
||||
return self.openmct.editor.save().then(() => {
|
||||
// Force mutation for search indexing
|
||||
return parent;
|
||||
});
|
||||
}
|
||||
|
||||
function cloneIntoParent(parent) {
|
||||
return copyService.perform(domainObject, parent, allowClone);
|
||||
function addSavedObjectToParent(parent) {
|
||||
return parent.getCapability("composition")
|
||||
.add(domainObject)
|
||||
.then(function (addedObject) {
|
||||
return parent.getCapability("persistence").persist()
|
||||
.then(function () {
|
||||
return addedObject;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function undirty(object) {
|
||||
@ -156,30 +156,22 @@ function (
|
||||
|
||||
function undirtyOriginals(object) {
|
||||
return Promise.all(toUndirty.map(undirty))
|
||||
.then(resolveWith(object));
|
||||
.then(() => {
|
||||
return object;
|
||||
});
|
||||
}
|
||||
|
||||
function saveAfterClone(clonedObject) {
|
||||
return this.openmct.editor.save().then(() => {
|
||||
// Force mutation for search indexing
|
||||
return clonedObject;
|
||||
})
|
||||
}
|
||||
|
||||
function finishEditing(clonedObject) {
|
||||
return fetchObject(clonedObject.getId())
|
||||
}
|
||||
|
||||
function indexForSearch(savedObject) {
|
||||
savedObject.useCapability('mutation', (model) => {
|
||||
function indexForSearch(addedObject) {
|
||||
addedObject.useCapability('mutation', (model) => {
|
||||
return model;
|
||||
});
|
||||
|
||||
return savedObject;
|
||||
return addedObject;
|
||||
}
|
||||
|
||||
function onSuccess(object) {
|
||||
self.notificationService.info("Save Succeeded");
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
@ -188,6 +180,7 @@ function (
|
||||
if (reason !== "user canceled") {
|
||||
self.notificationService.error("Save Failed");
|
||||
}
|
||||
|
||||
throw reason;
|
||||
}
|
||||
|
||||
@ -195,17 +188,18 @@ function (
|
||||
.then(doWizardSave)
|
||||
.then(showBlockingDialog)
|
||||
.then(getParent)
|
||||
.then(cloneIntoParent)
|
||||
.then(saveObject)
|
||||
.then(addSavedObjectToParent)
|
||||
.then(undirtyOriginals)
|
||||
.then(saveAfterClone)
|
||||
.then(finishEditing)
|
||||
.then((addedObject) => {
|
||||
return fetchObject(addedObject.getId());
|
||||
})
|
||||
.then(indexForSearch)
|
||||
.then(hideBlockingDialog)
|
||||
.then(onSuccess)
|
||||
.catch(onFailure);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Check if this action is applicable in a given context.
|
||||
* This will ensure that a domain object is present in the context,
|
||||
@ -214,10 +208,11 @@ function (
|
||||
*/
|
||||
SaveAsAction.appliesTo = function (context) {
|
||||
var domainObject = (context || {}).domainObject;
|
||||
return domainObject !== undefined &&
|
||||
domainObject.hasCapability('editor') &&
|
||||
domainObject.getCapability('editor').isEditContextRoot() &&
|
||||
domainObject.getModel().persisted === undefined;
|
||||
|
||||
return domainObject !== undefined
|
||||
&& domainObject.hasCapability('editor')
|
||||
&& domainObject.getCapability('editor').isEditContextRoot()
|
||||
&& domainObject.getModel().persisted === undefined;
|
||||
};
|
||||
|
||||
return SaveAsAction;
|
||||
|
@ -83,6 +83,7 @@ define(
|
||||
*/
|
||||
EditorCapability.prototype.save = function () {
|
||||
console.warn('DEPRECATED: cannot save via edit capability, use openmct.editor instead.');
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
@ -95,6 +96,7 @@ define(
|
||||
*/
|
||||
EditorCapability.prototype.finish = function () {
|
||||
console.warn('DEPRECATED: cannot finish via edit capability, use openmct.editor instead.');
|
||||
|
||||
return Promise.resolve();
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['./TransactionalPersistenceCapability'],
|
||||
@ -56,9 +55,10 @@ define(
|
||||
|
||||
capabilities.persistence = function (domainObject) {
|
||||
var original =
|
||||
(typeof persistenceCapability === 'function') ?
|
||||
persistenceCapability(domainObject) :
|
||||
persistenceCapability;
|
||||
(typeof persistenceCapability === 'function')
|
||||
? persistenceCapability(domainObject)
|
||||
: persistenceCapability;
|
||||
|
||||
return new TransactionalPersistenceCapability(
|
||||
self.$q,
|
||||
self.transactionService,
|
||||
@ -66,6 +66,7 @@ define(
|
||||
domainObject
|
||||
);
|
||||
};
|
||||
|
||||
return capabilities;
|
||||
};
|
||||
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
@ -64,6 +63,7 @@ define(
|
||||
wrappedPersistence.persist.bind(wrappedPersistence),
|
||||
wrappedPersistence.refresh.bind(wrappedPersistence)
|
||||
);
|
||||
|
||||
//Need to return a promise from this function
|
||||
return this.$q.when(true);
|
||||
} else {
|
||||
@ -74,6 +74,7 @@ define(
|
||||
TransactionalPersistenceCapability.prototype.refresh = function () {
|
||||
this.transactionManager
|
||||
.clearTransactionsFor(this.domainObject.getId());
|
||||
|
||||
return this.persistenceCapability.refresh();
|
||||
};
|
||||
|
||||
|
@ -48,9 +48,9 @@ define(
|
||||
// Maintain all "conclude-editing" and "save" actions in the
|
||||
// present context.
|
||||
function updateActions() {
|
||||
$scope.saveActions = $scope.action ?
|
||||
$scope.action.getActions(SAVE_ACTION_CONTEXT) :
|
||||
[];
|
||||
$scope.saveActions = $scope.action
|
||||
? $scope.action.getActions(SAVE_ACTION_CONTEXT)
|
||||
: [];
|
||||
|
||||
$scope.saveActionsAsMenuOptions = $scope.saveActions.map(actionToMenuOption);
|
||||
|
||||
@ -58,9 +58,9 @@ define(
|
||||
clickedAction.perform();
|
||||
};
|
||||
|
||||
$scope.otherEditActions = $scope.action ?
|
||||
$scope.action.getActions(OTHERS_ACTION_CONTEXT) :
|
||||
[];
|
||||
$scope.otherEditActions = $scope.action
|
||||
? $scope.action.getActions(OTHERS_ACTION_CONTEXT)
|
||||
: [];
|
||||
|
||||
// Required because Angular does not allow 'bind'
|
||||
// in expressions.
|
||||
|
@ -30,11 +30,11 @@ define(
|
||||
|
||||
function cancelEditing(domainObject) {
|
||||
var navigatedObject = domainObject,
|
||||
editorCapability = navigatedObject &&
|
||||
navigatedObject.getCapability("editor");
|
||||
editorCapability = navigatedObject
|
||||
&& navigatedObject.getCapability("editor");
|
||||
|
||||
return editorCapability &&
|
||||
editorCapability.finish();
|
||||
return editorCapability
|
||||
&& editorCapability.finish();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -35,8 +35,8 @@ define(
|
||||
// Update root object based on represented object
|
||||
function updateRoot(domainObject) {
|
||||
var root = self.rootDomainObject,
|
||||
context = domainObject &&
|
||||
domainObject.getCapability('context'),
|
||||
context = domainObject
|
||||
&& domainObject.getCapability('context'),
|
||||
newRoot = context && context.getTrueRoot(),
|
||||
oldId = root && root.getId(),
|
||||
newId = newRoot && newRoot.getId();
|
||||
@ -51,6 +51,7 @@ define(
|
||||
// Update root when represented object changes
|
||||
$scope.$watch('domainObject', updateRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the root-level domain object, as reported by the
|
||||
* represented domain object.
|
||||
|
@ -104,7 +104,6 @@ define(
|
||||
// We will disable this.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Metadata associated with a Create action.
|
||||
* @typedef {ActionMetadata} CreateActionMetadata
|
||||
|
@ -38,9 +38,9 @@ define(
|
||||
function CreateMenuController($scope) {
|
||||
// Update the set of Create actions
|
||||
function refreshActions() {
|
||||
$scope.createActions = $scope.action ?
|
||||
$scope.action.getActions('create') :
|
||||
[];
|
||||
$scope.createActions = $scope.action
|
||||
? $scope.action.getActions('create')
|
||||
: [];
|
||||
}
|
||||
|
||||
// Listen for new instances of the represented object's
|
||||
|
@ -56,10 +56,11 @@ define(
|
||||
*/
|
||||
CreateWizard.prototype.getFormStructure = function (includeLocation) {
|
||||
var sections = [],
|
||||
domainObject = this.domainObject;
|
||||
domainObject = this.domainObject,
|
||||
self = this;
|
||||
|
||||
function validateLocation(parent) {
|
||||
return parent && this.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter'));
|
||||
return parent && self.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter'));
|
||||
}
|
||||
|
||||
sections.push({
|
||||
@ -114,6 +115,7 @@ define(
|
||||
this.domainObject.useCapability("mutation", function () {
|
||||
return formModel;
|
||||
});
|
||||
|
||||
return this.domainObject;
|
||||
};
|
||||
|
||||
|
@ -73,12 +73,13 @@ define(
|
||||
// as a child contained by that parent.
|
||||
function addToComposition() {
|
||||
var compositionCapability = parent.getCapability('composition'),
|
||||
addResult = compositionCapability &&
|
||||
compositionCapability.add(newObject);
|
||||
addResult = compositionCapability
|
||||
&& compositionCapability.add(newObject);
|
||||
|
||||
return self.$q.when(addResult).then(function (result) {
|
||||
if (!result) {
|
||||
self.$log.error("Could not modify " + parent.getId());
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@ -92,6 +93,7 @@ define(
|
||||
// what space to create the new object's model in.
|
||||
if (!persistence || !newObjectPersistence) {
|
||||
self.$log.warn(NON_PERSISTENT_WARNING);
|
||||
|
||||
return self.$q.reject(new Error(NON_PERSISTENT_WARNING));
|
||||
}
|
||||
|
||||
@ -99,8 +101,6 @@ define(
|
||||
return newObjectPersistence.persist().then(addToComposition);
|
||||
};
|
||||
|
||||
|
||||
|
||||
return CreationService;
|
||||
}
|
||||
);
|
||||
|
@ -38,8 +38,8 @@ define(
|
||||
// * treeModel: The model for the embedded tree representation,
|
||||
// used for bi-directional object selection.
|
||||
function setLocatingObject(domainObject, priorObject) {
|
||||
var context = domainObject &&
|
||||
domainObject.getCapability("context"),
|
||||
var context = domainObject
|
||||
&& domainObject.getCapability("context"),
|
||||
contextRoot = context && context.getRoot();
|
||||
|
||||
if (contextRoot && contextRoot !== $scope.rootObject) {
|
||||
@ -65,11 +65,12 @@ define(
|
||||
$scope.ngModel[$scope.field] = domainObject;
|
||||
|
||||
// Restrict which locations can be selected
|
||||
if (domainObject &&
|
||||
$scope.structure &&
|
||||
$scope.structure.validate) {
|
||||
if (domainObject
|
||||
&& $scope.structure
|
||||
&& $scope.structure.validate) {
|
||||
if (!$scope.structure.validate(domainObject)) {
|
||||
setLocatingObject(priorObject, undefined);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -78,7 +79,7 @@ define(
|
||||
if ($scope.ngModelController) {
|
||||
$scope.ngModelController.$setValidity(
|
||||
'composition',
|
||||
!!$scope.treeModel.selectedObject
|
||||
Boolean($scope.treeModel.selectedObject)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -36,8 +36,6 @@ define(
|
||||
}
|
||||
|
||||
EditPersistableObjectsPolicy.prototype.allow = function (action, context) {
|
||||
var identifier;
|
||||
var provider;
|
||||
var domainObject = context.domainObject;
|
||||
var key = action.getMetadata().key;
|
||||
var category = (context || {}).category;
|
||||
@ -46,9 +44,9 @@ define(
|
||||
// is also invoked during the create process which should be allowed,
|
||||
// because it may be saved elsewhere
|
||||
if ((key === 'edit' && category === 'view-control') || key === 'properties') {
|
||||
identifier = objectUtils.parseKeyString(domainObject.getId());
|
||||
provider = this.openmct.objects.getProvider(identifier);
|
||||
return provider.save !== undefined;
|
||||
let newStyleObject = objectUtils.toNewFormat(domainObject, domainObject.getId());
|
||||
|
||||
return this.openmct.objects.isPersistable(newStyleObject);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -74,6 +74,7 @@ define(
|
||||
model.configuration = model.configuration || {};
|
||||
model.configuration[this.key] = configuration;
|
||||
}
|
||||
|
||||
domainObject.useCapability('mutation', function () {
|
||||
return model;
|
||||
});
|
||||
|
@ -41,6 +41,7 @@ define(['./Transaction'], function (Transaction) {
|
||||
Transaction.prototype.commit.bind(this),
|
||||
Transaction.prototype.cancel.bind(this)
|
||||
);
|
||||
|
||||
return Promise.resolve(true);
|
||||
};
|
||||
|
||||
|
@ -41,8 +41,12 @@ define([], function () {
|
||||
* pair of callbacks from the transaction
|
||||
*/
|
||||
Transaction.prototype.add = function (commit, cancel) {
|
||||
var callback = { commit: commit, cancel: cancel };
|
||||
var callback = {
|
||||
commit: commit,
|
||||
cancel: cancel
|
||||
};
|
||||
this.callbacks.push(callback);
|
||||
|
||||
return function () {
|
||||
this.callbacks = this.callbacks.filter(function (c) {
|
||||
return c !== callback;
|
||||
@ -91,6 +95,5 @@ define([], function () {
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
return Transaction;
|
||||
});
|
||||
|
@ -50,7 +50,7 @@ define([], function () {
|
||||
* @returns {boolean} true if callbacks have been added
|
||||
*/
|
||||
TransactionManager.prototype.isScheduled = function (id) {
|
||||
return !!this.clearTransactionFns[id];
|
||||
return Boolean(this.clearTransactionFns[id]);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -77,6 +77,7 @@ define([], function () {
|
||||
return promiseFn().then(nextFn);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear any existing persistence calls for object with given ID. This ensures only the most recent persistence
|
||||
* call is executed. This should prevent stale objects being persisted and overwriting fresh ones.
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global define*/
|
||||
define(
|
||||
['./Transaction', './NestedTransaction'],
|
||||
function (Transaction, NestedTransaction) {
|
||||
@ -48,9 +47,9 @@ define(
|
||||
* #cancel} are called
|
||||
*/
|
||||
TransactionService.prototype.startTransaction = function () {
|
||||
var transaction = this.isActive() ?
|
||||
new NestedTransaction(this.transactions[0]) :
|
||||
new Transaction(this.$log);
|
||||
var transaction = this.isActive()
|
||||
? new NestedTransaction(this.transactions[0])
|
||||
: new Transaction(this.$log);
|
||||
|
||||
this.transactions.push(transaction);
|
||||
};
|
||||
@ -99,13 +98,16 @@ define(
|
||||
if (!transaction) {
|
||||
return Promise.reject();
|
||||
}
|
||||
|
||||
if (!this.isActive()) {
|
||||
return transaction.commit()
|
||||
.then(function (r) {
|
||||
this.cacheService.flush();
|
||||
|
||||
return r;
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
return transaction.commit();
|
||||
};
|
||||
|
||||
@ -119,6 +121,7 @@ define(
|
||||
*/
|
||||
TransactionService.prototype.cancel = function () {
|
||||
var transaction = this.transactions.pop();
|
||||
|
||||
return transaction ? transaction.cancel() : Promise.reject();
|
||||
};
|
||||
|
||||
|
@ -102,7 +102,7 @@ define(
|
||||
});
|
||||
|
||||
mockDomainObject.hasCapability.and.callFake(function (name) {
|
||||
return !!capabilities[name];
|
||||
return Boolean(capabilities[name]);
|
||||
});
|
||||
|
||||
capabilities.editor.finish.and.returnValue(mockPromise(true));
|
||||
@ -123,8 +123,8 @@ define(
|
||||
expect(CancelAction.appliesTo(actionContext)).toBeFalsy();
|
||||
});
|
||||
|
||||
it("invokes the editor capability's cancel functionality when" +
|
||||
" performed", function () {
|
||||
it("invokes the editor capability's cancel functionality when"
|
||||
+ " performed", function () {
|
||||
mockDomainObject.getModel.and.returnValue({persisted: 1});
|
||||
//Return true from navigate action
|
||||
capabilities.action.perform.and.returnValue(mockPromise(true));
|
||||
|
@ -93,7 +93,6 @@ define(
|
||||
action = new EditAndComposeAction(actionContext);
|
||||
});
|
||||
|
||||
|
||||
it("adds to the parent's composition when performed", function () {
|
||||
action.perform();
|
||||
expect(mockComposition.add)
|
||||
@ -106,8 +105,8 @@ define(
|
||||
expect(mockEditAction.perform).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("Does not enable edit mode for objects that do not have an" +
|
||||
" edit action", function () {
|
||||
it("Does not enable edit mode for objects that do not have an"
|
||||
+ " edit action", function () {
|
||||
mockActionCapability.getActions.and.returnValue([]);
|
||||
action.perform();
|
||||
expect(mockEditAction.perform).not.toHaveBeenCalled();
|
||||
|
@ -64,7 +64,10 @@ define(
|
||||
return true;
|
||||
}
|
||||
};
|
||||
context = { someKey: "some value", domainObject: object };
|
||||
context = {
|
||||
someKey: "some value",
|
||||
domainObject: object
|
||||
};
|
||||
dialogService = {
|
||||
getUserInput: function () {
|
||||
return mockPromise(input);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/actions/SaveAction"],
|
||||
@ -138,6 +137,7 @@ define(
|
||||
it("notifies if saving succeeded", function () {
|
||||
var mockCallback = jasmine.createSpy("callback");
|
||||
mockEditorCapability.save.and.returnValue(Promise.resolve());
|
||||
|
||||
return action.perform().then(mockCallback).then(function () {
|
||||
expect(mockNotificationService.info).toHaveBeenCalled();
|
||||
expect(mockNotificationService.error).not.toHaveBeenCalled();
|
||||
@ -147,6 +147,7 @@ define(
|
||||
it("notifies if saving failed", function () {
|
||||
var mockCallback = jasmine.createSpy("callback");
|
||||
mockEditorCapability.save.and.returnValue(Promise.reject("some failure reason"));
|
||||
|
||||
return action.perform().then(mockCallback).then(function () {
|
||||
expect(mockNotificationService.error).toHaveBeenCalled();
|
||||
expect(mockNotificationService.info).not.toHaveBeenCalled();
|
||||
|
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global describe,it,expect,beforeEach,jasmine*/
|
||||
|
||||
define(
|
||||
["../../src/actions/SaveAndStopEditingAction"],
|
||||
@ -97,7 +96,6 @@ define(
|
||||
action = new SaveAndStopEditingAction(dialogService, notificationService, actionContext);
|
||||
});
|
||||
|
||||
|
||||
it("only applies to domain object with an editor capability", function () {
|
||||
expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(true);
|
||||
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
||||
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
@ -19,7 +19,6 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
/*global describe,it,expect,beforeEach,jasmine,spyOn*/
|
||||
|
||||
define(
|
||||
["../../src/actions/SaveAsAction"],
|
||||
@ -42,15 +41,15 @@ define(
|
||||
function noop() {}
|
||||
|
||||
function mockPromise(value) {
|
||||
return (value || {}).then ? value :
|
||||
{
|
||||
return (value || {}).then ? value
|
||||
: {
|
||||
then: function (callback) {
|
||||
return mockPromise(callback(value));
|
||||
},
|
||||
catch: function (callback) {
|
||||
return mockPromise(callback(value));
|
||||
}
|
||||
} ;
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
@ -67,7 +66,10 @@ define(
|
||||
mockDomainObject.getCapability.and.callFake(function (capability) {
|
||||
return capabilities[capability];
|
||||
});
|
||||
mockDomainObject.getModel.and.returnValue({location: 'a', persisted: undefined});
|
||||
mockDomainObject.getModel.and.returnValue({
|
||||
location: 'a',
|
||||
persisted: undefined
|
||||
});
|
||||
mockDomainObject.getId.and.returnValue(0);
|
||||
|
||||
mockClonedObject = jasmine.createSpyObj(
|
||||
@ -168,8 +170,8 @@ define(
|
||||
expect(SaveAsAction.appliesTo(actionContext)).toBe(false);
|
||||
});
|
||||
|
||||
it("only applies to domain object that has not already been" +
|
||||
" persisted", function () {
|
||||
it("only applies to domain object that has not already been"
|
||||
+ " persisted", function () {
|
||||
expect(SaveAsAction.appliesTo(actionContext)).toBe(true);
|
||||
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user