Compare commits

...

42 Commits

Author SHA1 Message Date
Shefali Joshi
a5c61ec1b7 Merge branch 'master' into couchdb-tests 2020-08-10 09:58:09 -07:00
Andrew Henry
7e7141a5a0 Fixes to enable testing again (#3275)
* Updated library versions
* Use Karma alternative spec loading
* Fixed memory leak in URLTimeSettingsSynchronizer
* Introduce mock DataTransfer object to fix issue with firefox headless
* make resetApplicationState return a promise
* Remove BeforeAll
* Do not throw an error if root returns no children
* Adding missing parameters to ES tests
* Fixed TransactionService bug
* bump test coverage up to 64%
2020-08-10 09:47:04 -07:00
Joshi
f6ecabb053 Trying chrome 2020-08-07 14:47:22 -07:00
Joshi
831f207b10 Running tests on circleci 2020-08-07 14:37:52 -07:00
Joshi
42e474ca60 Merge branch 'couchdb-persistence' of https://github.com/nasa/openmct into couchdb-persistence 2020-08-05 15:21:17 -07:00
Joshi
d767932be2 Fixes tests 2020-08-05 15:20:50 -07:00
Shefali Joshi
0238a86be5 Merge branch 'master' into couchdb-persistence 2020-08-04 14:44:23 -07:00
Joshi
7abbd7cb20 Merge branch 'couchdb-persistence' of https://github.com/nasa/openmct into couchdb-persistence 2020-08-04 11:36:20 -07:00
Joshi
6e2b12b00d Since we're persisting the object to the store before adding it to the parent, there is no need to save it during copyTask as this will trigger a create of the object twice. 2020-08-04 11:35:17 -07:00
Shefali Joshi
e32f465f7a Display layout plugin test coverage to 20% or more (#3158)
* Display layout plugin test coverage to 20% or more
Resolves #3157

* Changes address original issue? Yes
* Unit tests included and/or updated with changes? Yes
* Command line build passes? Yes
* Changes have been smoke-tested? Yes
* Testing instructions included? Yes

* Add disable-dev-shm-usage flag to ChromeHeadless launcher config in karma

* Adding disable dev shm usage flag to chromeheadless launcher and setting log level to debug

* Adding np activity timeout to 60000

* Adding no-sandbox flag for headless chrome

* Run tests without headless chrome to see if that fixes the fonts issue

* Fix typo

* Trying chrome headless with increased memory

* Reset karma.conf back to master

* Trying karma chrome launcher 3.1.0

* Revert to master code for package.json and karma.conf.js

* Trying node 12 browsers

* Revert back to node:13 browsers

* Revert to 10.2.1-browsers circle ci node browsers variant image for docker

* Rebuild node-sass for node 10.x

* Upgrading to 13.14.0 node

* Remove node options

* Don't restore cache before npm install

* Comment out tests with setTimeout

* Trying node 8-browsers

* Try firefox headless

* Firefox version typo

* Revert focused tests

* Exclude setTimeout tests

* Increase browser connectivity timeout

* Trying large timeout with Chromeheadless

* Going back to Firefox and setting browser timeout to 1.5 mins

* Fixes linting issues

* Fix broken tests and add some null checks in the code

* Change double quotes to single quotes
2020-08-03 13:41:57 -07:00
David Tsay
abc458cef4 [Time conductor] Better persistence handling for history (#3246) 2020-08-03 11:56:29 -07:00
Joshi
6a2520f39b Fixes linting issues 2020-08-03 11:08:28 -07:00
Joshi
5b7a011069 Merge branch 'master' of https://github.com/nasa/openmct into couchdb-persistence 2020-08-03 11:07:04 -07:00
Shefali Joshi
b76d4b76cb Merge pull request #3228 from nasa/telemetry-table-config-updates
Update TelemetryTable config to allow disable multiselect
2020-07-31 14:41:49 -07:00
Shefali Joshi
5a4cba0226 Merge branch 'master' into telemetry-table-config-updates 2020-07-31 14:23:12 -07:00
Jamie V
f03bfdebb4 [Telemetry Tables][Plots] Display units where applicable (#3198)
* added unit columns in telemetry tables

* added unit column hiding in telemetry tables, added units to lad tables and sets

* added units to plots and plot legends
2020-07-31 13:13:58 -07:00
Andrew Henry
a09da30768 New eslint rules auto fix (#3058)
* no-implicit-coercion and no-unneeded-ternary

* End every line with a semicolon

* Spacing and formatting

* Enabled semi-spacing

* Applies npm run lint:fix to code after master merge

* Fix merge issues

* Switched operator-linebreak to 'before'

Co-authored-by: Joshi <simplyrender@gmail.com>
2020-07-31 12:11:03 -07:00
Nikhil
573a63d359 [Snapshots] Are holding on to outdated domainObjects when clicking on preview #3078 (#3240)
* [Snapshots] Are holding on to outdated domainObjects when clicking on preview #3078

* #3250 :  [Preview] Preview window should not have any context menu actions

* cleanup: removed redundant code
2020-07-29 16:33:39 -07:00
Shefali Joshi
d216117b30 Merge branch 'master' into couchdb-persistence 2020-07-28 16:43:54 -07:00
Joshi
5c520bfce9 Removes fdescribe 2020-07-28 16:43:08 -07:00
Joshi
cba9670823 [WIP] Hacking the GET api to fallback to the DomainObjectProvider to retrieve cached objects when they don't yet exist in CouchDB 2020-07-28 15:33:19 -07:00
Joshi
27651e9eaa Queue up the promise returned in addition to the model to persist 2020-07-28 15:30:31 -07:00
Deep Tailor
e667b22b3c remove modified and persisted keys from duplicates (#3241) 2020-07-28 11:05:55 -07:00
Joshi
f096d54dd0 Added queuing of requests 2020-07-28 10:23:27 -07:00
Jamie V
7d51d9c1eb parsing datum itself rather than specific key of datum, let telemetry api do the work (#3235) 2020-07-24 13:34:26 -07:00
Deep Tailor
13ff0c368d Merge branch 'master' into telemetry-table-config-updates 2020-07-24 10:46:02 -07:00
David Tsay
9124f4f566 allow table row to control object path for context menu actions (#3232)
Need for changes in VISTA
2020-07-24 10:41:36 -07:00
Andrew Henry
8258f21f7b Remove references to legacy couch adapter 2020-07-23 17:47:00 -07:00
Andrew Henry
44bfcf33ef Removed placeholder provider 2020-07-23 17:45:49 -07:00
Andrew Henry
669415d362 Removed commented code 2020-07-23 17:45:01 -07:00
Andrew Henry
8601ec441f Remove comments 2020-07-23 17:44:05 -07:00
Andrew Henry
9a57a20404 Use new couch provider 2020-07-23 17:43:10 -07:00
Andrew Henry
1a3bff9813 Fixed some issues in CouchObjectProvider 2020-07-23 17:39:34 -07:00
Andrew Henry
baa5f21640 Added legacy persistence service adapter 2020-07-23 17:39:02 -07:00
Joshi
af9dceee3c [WIP] CouchDB object provider 2020-07-23 16:02:10 -07:00
Mandlik, Nikhil K. (ARC-TI)[KBR Wyle Services, LLC]
b7d2402434 Update TelemetryTable config to allow disable multiselect. 2020-07-23 14:11:44 -07:00
Charles Hacskaylo
d9baa94970 UI enhancement fixes 2 (#3225)
- Fixed incorrect CSS naming: `c-frame-edit__move` changed to
 `c-frame__move-bar`;
 - Fixed `display: contents` that was erroneously applied to
 `u-angular-object-view-wrapper` and preventing styling from being
 applied to plots, renamed class to `.l-angular-ov-wrapper`;
 - Removed commented CSS;
2020-07-22 20:20:17 -07:00
Shefali Joshi
afeb89a51a [VIPEROMCT-16] Creates a closure for telemetryObject so that requests can resolve correctly even if the telemetryObject is destroyed (#3210)
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-07-22 15:22:31 -07:00
johnriedel
07992f0b2a [Tabs View] add ability to remove tabs from tabs view interface (#3147) (#3148)
* add ability to remove tabs from tabs view interface (#3147)

* an "X" on each tab is visible in edit mode

* replaced custom removeDialog with openmct.overlays.dialog

* Minor mods to markup and CSS

- Changed tab from button to div to allow a cleaner approach to the
nested close button;
- Changed close "icon-x" span to a button and added `c-click-icon` style
tag;
- Tweaked class naming to simplify and align with a more functional/
descriptive approach;

* use ES6 arrow func to avoid self=this

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-07-22 15:17:35 -07:00
Deep Tailor
a5c4508578 add minified vue to production (#3183)
Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
2020-07-22 14:47:46 -07:00
Charles Hacskaylo
a4fab3ce8a UI enhancement fixes (#3222)
- Added min-width and min-height to Display Layout lines to allow
 easier selection and move when line is purely vertical or horizontal;
 - Fixed spacing, size and icon of overlay close button;
2020-07-22 11:35:06 -07:00
Charles Hacskaylo
97d80f57cc UI enhancements (#3217)
* UI enhancements for #3176

- Large overlay now displays fullscreen;

* UI enhancements for #3176

- Adding new ".is-in-small-container" CSS - VERY WIP!
- TODO: fix table implementation;

* UI fixes for NIRVSS client #170

- Hide table header filter inputs when table is in small container;

* UI fixes for NIRVSS client #170

- Fixing legends and plot layout when small, and within a stacked plot;
- Add new `hideLegendWhenSmall` property;
- Remove 'hidden' from plot legend position options;
- Reduced opacity of tabular headers in Espresso theme;
- VERY, VERY WIP right now!

* UI fixes for NIRVSS client #170

- Fixing legends and plot layout when small, and within a stacked plot;
- Cleanups, indention, removed commented CSS;
- Tightened up spacing in plot Y axis;

* UI enhancements for #3176

- Move local controls for plots and imagery, prevent overlapping with
 view large button when in a hidden frame in a layout;
 - Finesse local control styling for increased legibility;
 - Move l-state-indicators to avoid overlap with repositioned local
 controls, finesse styling;

* UI enhancements for #3176

- Tweak large overlay close button for better visual alignment;

* UI enhancements for #3176

- Significant improvements to lines in Display Layouts;
- Increased border-width for lines and boxes;
- Code enhanced for proper handling of horizontal and
vertical lines - but still isn't working properly;
- Renamed box-view.scss to box-and-line-views.scss;
- VERY WIP!

* Fixed incorrect grid array reference

* UI enhancements for #3176

- Fixed final issue with Display Layout line drawing object, thank you
@deeptailor!;

* UI enhancements for #3176

- Contrast enhancements and markup normalization for `c-object-label`
elements in main view, Layout frames, Inspector and overlay;
- Enhanced `l-overlay-large` layout;
- Tightened up margins and spacing in plots;
- Refined `is-paused` styling in Telemetry Tables;
- Now hide Telemetry Tables 'Export Data' button if rows are selected,
which use a separate export button;
- Layout frames now hide button's text labels when small;
- Layout frames spacing tightened up and improved;

* UI enhancements for #3176

- Tweak Snow theme constants;

* UI enhancements for #3176

- Fixed ObjectFrame getOverlayElement method, added a wrapper div
around the viewed object to properly control resulting layout in the
overlay;
- Simplified preview CSS to remove background, border and padding;
- Layout tweaks to add space between scrollbar and thumbs in Imagery
view;
- Removed dev "-info" element in LineView.vue;

* UI enhancements for #3176

- Improved styling for 'edit lock' button;

* UI enhancements for #3176

- Show Display Layout frame "-move" bar on hover, rather than select, to
 make it easier to select items with hidden frames, and only show -move
  bar's drag grippy when that frame is selected;
- `pointer-events: none` applied to table's body and plot's plot areas
when placed in a Layout and being edited, prevents distracting
interactions (plot zoom/pan, table row selection) when selecting and
moving elements in a Layout;
- Refined hover styles for c-button to use $filterHov, simplified and
normalized hover styling;
- Converted a number of old `<a>` tags to `<buttons>` to normalize
styling and use the appropriate control;
- Edit lock button is now colored when locked;

* Fix linting issue

* Minor tweaks

- Tweaked control positioning;

Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
2020-07-21 21:01:38 -07:00
789 changed files with 6384 additions and 2760 deletions

View File

@@ -11,12 +11,12 @@ jobs:
name: Update npm name: Update npm
command: 'sudo npm install -g npm@latest' command: 'sudo npm install -g npm@latest'
- restore_cache: - restore_cache:
key: dependency-cache-13-{{ checksum "package.json" }} key: dependency-cache-{{ checksum "package.json" }}
- run: - run:
name: Installing dependencies (npm install) name: Installing dependencies (npm install)
command: npm install command: npm install
- save_cache: - save_cache:
key: dependency-cache-13-{{ checksum "package.json" }} key: dependency-cache-{{ checksum "package.json" }}
paths: paths:
- node_modules - node_modules
- run: - run:

View File

@@ -121,6 +121,59 @@ module.exports = {
// https://eslint.org/docs/rules/rest-spread-spacing // https://eslint.org/docs/rules/rest-spread-spacing
"rest-spread-spacing": ["error"], "rest-spread-spacing": ["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": [ "vue/html-indent": [
"error", "error",
4, 4,

View File

@@ -29,7 +29,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/eventGenerator", name: "example/eventGenerator",
definition: { definition: {
"name": "Event Message Generator", "name": "Event Message Generator",
"description": "For development use. Creates sample event message data that mimics a live data stream.", "description": "For development use. Creates sample event message data that mimics a live data stream.",

View File

@@ -44,13 +44,14 @@ define(
}; };
generatorData.getDomainValue = function (i, domain) { generatorData.getDomainValue = function (i, domain) {
return i * interval + return i * interval
(domain !== 'delta' ? firstObservedTime : 0); + (domain !== 'delta' ? firstObservedTime : 0);
}; };
generatorData.getRangeValue = function (i, range) { generatorData.getRangeValue = function (i, range) {
var domainDelta = this.getDomainValue(i) - firstObservedTime, var domainDelta = this.getDomainValue(i) - firstObservedTime,
ind = i % messages.length; ind = i % messages.length;
return messages[ind] + " - [" + domainDelta.toString() + "]"; return messages[ind] + " - [" + domainDelta.toString() + "]";
}; };

View File

@@ -57,6 +57,7 @@ define(
results.forEach(function (result) { results.forEach(function (result) {
packaged[result.key] = result.telemetry; packaged[result.key] = result.telemetry;
}); });
// Format as expected (sources -> keys -> telemetry) // Format as expected (sources -> keys -> telemetry)
return { eventGenerator: packaged }; return { eventGenerator: packaged };
} }

View File

@@ -76,13 +76,14 @@ define([], function () {
copyRangesToRow(row, i); copyRangesToRow(row, i);
rows.push(row); rows.push(row);
} }
exportService.exportCSV(rows, { headers: headers }); exportService.exportCSV(rows, { headers: headers });
}); });
}; };
ExportTelemetryAsCSVAction.appliesTo = function (context) { ExportTelemetryAsCSVAction.appliesTo = function (context) {
return context.domainObject && return context.domainObject
context.domainObject.hasCapability("telemetry"); && context.domainObject.hasCapability("telemetry");
}; };
return ExportTelemetryAsCSVAction; return ExportTelemetryAsCSVAction;

View File

@@ -27,7 +27,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/export", name: "example/export",
definition: { definition: {
"name": "Example of using CSV Export", "name": "Example of using CSV Export",
"extensions": { "extensions": {

View File

@@ -29,7 +29,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/forms", name: "example/forms",
definition: { definition: {
"name": "Declarative Forms example", "name": "Declarative Forms example",
"sources": "src", "sources": "src",

View File

@@ -152,10 +152,22 @@ define(
name: "Choose something", name: "Choose something",
control: "select", control: "select",
options: [ options: [
{ name: "Hats", value: "hats" }, {
{ name: "Bats", value: "bats" }, name: "Hats",
{ name: "Cats", value: "cats" }, value: "hats"
{ name: "Mats", value: "mats" } },
{
name: "Bats",
value: "bats"
},
{
name: "Cats",
value: "cats"
},
{
name: "Mats",
value: "mats"
}
], ],
key: "aChoice" key: "aChoice"
}, },
@@ -164,10 +176,22 @@ define(
control: "select", control: "select",
required: true, required: true,
options: [ options: [
{ name: "Hats", value: "hats" }, {
{ name: "Bats", value: "bats" }, name: "Hats",
{ name: "Cats", value: "cats" }, value: "hats"
{ name: "Mats", value: "mats" } },
{
name: "Bats",
value: "bats"
},
{
name: "Cats",
value: "cats"
},
{
name: "Mats",
value: "mats"
}
], ],
key: "aRequiredChoice" key: "aRequiredChoice"
} }

View File

@@ -41,6 +41,7 @@ define([
{ {
key: "sin", key: "sin",
name: "Sine", name: "Sine",
unit: "Hz",
formatString: '%0.2f', formatString: '%0.2f',
hints: { hints: {
range: 1 range: 1
@@ -49,6 +50,7 @@ define([
{ {
key: "cos", key: "cos",
name: "Cosine", name: "Cosine",
unit: "deg",
formatString: '%0.2f', formatString: '%0.2f',
hints: { hints: {
range: 2 range: 2
@@ -108,7 +110,7 @@ define([
} }
] ]
} }
} };
function GeneratorMetadataProvider() { function GeneratorMetadataProvider() {

View File

@@ -65,15 +65,19 @@ define([
if (domainObject.telemetry && domainObject.telemetry.hasOwnProperty(prop)) { if (domainObject.telemetry && domainObject.telemetry.hasOwnProperty(prop)) {
workerRequest[prop] = domainObject.telemetry[prop]; workerRequest[prop] = domainObject.telemetry[prop];
} }
if (request && request.hasOwnProperty(prop)) { if (request && request.hasOwnProperty(prop)) {
workerRequest[prop] = request[prop]; workerRequest[prop] = request[prop];
} }
if (!workerRequest.hasOwnProperty(prop)) { if (!workerRequest.hasOwnProperty(prop)) {
workerRequest[prop] = REQUEST_DEFAULTS[prop]; workerRequest[prop] = REQUEST_DEFAULTS[prop];
} }
workerRequest[prop] = Number(workerRequest[prop]); workerRequest[prop] = Number(workerRequest[prop]);
}); });
workerRequest.name = domainObject.name; workerRequest.name = domainObject.name;
return workerRequest; return workerRequest;
}; };
@@ -81,11 +85,13 @@ define([
var workerRequest = this.makeWorkerRequest(domainObject, request); var workerRequest = this.makeWorkerRequest(domainObject, request);
workerRequest.start = request.start; workerRequest.start = request.start;
workerRequest.end = request.end; workerRequest.end = request.end;
return this.workerInterface.request(workerRequest); return this.workerInterface.request(workerRequest);
}; };
GeneratorProvider.prototype.subscribe = function (domainObject, callback) { GeneratorProvider.prototype.subscribe = function (domainObject, callback) {
var workerRequest = this.makeWorkerRequest(domainObject, {}); var workerRequest = this.makeWorkerRequest(domainObject, {});
return this.workerInterface.subscribe(workerRequest, callback); return this.workerInterface.subscribe(workerRequest, callback);
}; };

View File

@@ -78,12 +78,15 @@ define([
if (datum[range] > RED[range]) { if (datum[range] > RED[range]) {
return LIMITS.rh; return LIMITS.rh;
} }
if (datum[range] < -RED[range]) { if (datum[range] < -RED[range]) {
return LIMITS.rl; return LIMITS.rl;
} }
if (datum[range] > YELLOW[range]) { if (datum[range] > YELLOW[range]) {
return LIMITS.yh; return LIMITS.yh;
} }
if (datum[range] < -YELLOW[range]) { if (datum[range] < -YELLOW[range]) {
return LIMITS.yl; return LIMITS.yl;
} }

View File

@@ -48,7 +48,7 @@ define([
var interval = setInterval(function () { var interval = setInterval(function () {
var now = Date.now(); var now = Date.now();
var datum = pointForTimestamp(now, duration, domainObject.name); var datum = pointForTimestamp(now, duration, domainObject.name);
datum.value += ""; datum.value = String(datum.value);
callback(datum); callback(datum);
}, duration); }, duration);
@@ -57,7 +57,6 @@ define([
}; };
}; };
StateGeneratorProvider.prototype.supportsRequest = function (domainObject, options) { StateGeneratorProvider.prototype.supportsRequest = function (domainObject, options) {
return domainObject.type === 'example.state-generator'; return domainObject.type === 'example.state-generator';
}; };
@@ -69,11 +68,13 @@ define([
if (options.strategy === 'latest' || options.size === 1) { if (options.strategy === 'latest' || options.size === 1) {
start = end; start = end;
} }
var data = []; var data = [];
while (start <= end && data.length < 5000) { while (start <= end && data.length < 5000) {
data.push(pointForTimestamp(start, duration, domainObject.name)); data.push(pointForTimestamp(start, duration, domainObject.name));
start += duration; start += duration;
} }
return Promise.resolve(data); return Promise.resolve(data);
}; };

View File

@@ -78,6 +78,7 @@ define([
} else { } else {
deferred.resolve(message.data); deferred.resolve(message.data);
} }
delete this.callbacks[messageId]; delete this.callbacks[messageId];
} }
@@ -101,8 +102,5 @@ define([
}.bind(this); }.bind(this);
}; };
return WorkerInterface; return WorkerInterface;
}); });

View File

@@ -64,13 +64,14 @@
data: { data: {
name: data.name, name: data.name,
utc: nextStep, utc: nextStep,
yesterday: nextStep - 60*60*24*1000, yesterday: nextStep - 60 * 60 * 24 * 1000,
sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness), sin: sin(nextStep, data.period, data.amplitude, data.offset, data.phase, data.randomness),
cos: cos(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; nextStep += step;
} }
return nextStep; return nextStep;
} }
@@ -87,6 +88,7 @@
if (request.end === undefined) { if (request.end === undefined) {
request.end = Date.now(); request.end = Date.now();
} }
if (request.start === undefined) { if (request.start === undefined) {
request.start = request.end - FIFTEEN_MINUTES; request.start = request.end - FIFTEEN_MINUTES;
} }
@@ -110,11 +112,12 @@
data.push({ data.push({
name: request.name, name: request.name,
utc: nextStep, utc: nextStep,
yesterday: nextStep - 60*60*24*1000, yesterday: nextStep - 60 * 60 * 24 * 1000,
sin: sin(nextStep, period, amplitude, offset, phase, randomness), sin: sin(nextStep, period, amplitude, offset, phase, randomness),
cos: cos(nextStep, period, amplitude, offset, phase, randomness) cos: cos(nextStep, period, amplitude, offset, phase, randomness)
}); });
} }
self.postMessage({ self.postMessage({
id: message.id, id: message.id,
data: data data: data
@@ -122,13 +125,13 @@
} }
function cos(timestamp, period, amplitude, offset, phase, randomness) { function cos(timestamp, period, amplitude, offset, phase, randomness) {
return amplitude * return amplitude
Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset; * Math.cos(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
} }
function sin(timestamp, period, amplitude, offset, phase, randomness) { function sin(timestamp, period, amplitude, offset, phase, randomness) {
return amplitude * return amplitude
Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset; * Math.sin(phase + (timestamp / period / 1000 * Math.PI * 2)) + (amplitude * Math.random() * randomness) + offset;
} }
function sendError(error, message) { function sendError(error, message) {

View File

@@ -56,7 +56,7 @@ define([
initialize: function (object) { initialize: function (object) {
object.telemetry = { object.telemetry = {
duration: 5 duration: 5
} };
} }
}); });

View File

@@ -29,7 +29,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/identity", name: "example/identity",
definition: { definition: {
"extensions": { "extensions": {
"components": [ "components": [

View File

@@ -25,26 +25,30 @@ define(
function () { function () {
"use strict"; "use strict";
var DEFAULT_IDENTITY = { key: "user", name: "Example User" }, var DEFAULT_IDENTITY = {
key: "user",
name: "Example User"
},
DIALOG_STRUCTURE = { DIALOG_STRUCTURE = {
name: "Identify Yourself", name: "Identify Yourself",
sections: [{ rows: [ sections: [{
{ rows: [
name: "User ID", {
control: "textfield", name: "User ID",
key: "key", control: "textfield",
required: true key: "key",
}, required: true
{ },
name: "Human name", {
control: "textfield", name: "Human name",
key: "name", control: "textfield",
required: true key: "name",
} required: true
]}] }
]
}]
}; };
/** /**
* Example implementation of an identity service. This prompts the * Example implementation of an identity service. This prompts the
* user to enter a name and user ID; in a more realistic * user to enter a name and user ID; in a more realistic
@@ -77,14 +81,14 @@ define(
*/ */
ExampleIdentityProvider.prototype.returnUser = function (user) { ExampleIdentityProvider.prototype.returnUser = function (user) {
return this.user = user; return this.user = user;
} };
/** /**
* @private * @private
*/ */
ExampleIdentityProvider.prototype.returnUndefined = function () { ExampleIdentityProvider.prototype.returnUndefined = function () {
return undefined; return undefined;
} };
return ExampleIdentityProvider; return ExampleIdentityProvider;
} }

View File

@@ -85,28 +85,28 @@ define([
data.push(pointForTimestamp(start, domainObject.name)); data.push(pointForTimestamp(start, domainObject.name));
start += 5000; start += 5000;
} }
return Promise.resolve(data); return Promise.resolve(data);
} }
}; };
var ladProvider = { var ladProvider = {
supportsRequest: function (domainObject, options) { supportsRequest: function (domainObject, options) {
return domainObject.type === 'example.imagery' && return domainObject.type === 'example.imagery'
options.strategy === 'latest'; && options.strategy === 'latest';
}, },
request: function (domainObject, options) { request: function (domainObject, options) {
return Promise.resolve([pointForTimestamp(Date.now(), domainObject.name)]); return Promise.resolve([pointForTimestamp(Date.now(), domainObject.name)]);
} }
}; };
return function install(openmct) { return function install(openmct) {
openmct.types.addType('example.imagery', { openmct.types.addType('example.imagery', {
key: 'example.imagery', key: 'example.imagery',
name: 'Example Imagery', name: 'Example Imagery',
cssClass: 'icon-image', cssClass: 'icon-image',
description: 'For development use. Creates example imagery ' + description: 'For development use. Creates example imagery '
'data that mimics a live imagery stream.', + 'data that mimics a live imagery stream.',
creatable: true, creatable: true,
initialize: function (object) { initialize: function (object) {
object.telemetry = { object.telemetry = {
@@ -140,7 +140,7 @@ define([
} }
} }
] ]
} };
} }
}); });

View File

@@ -25,7 +25,7 @@ define([], function () {
"use strict"; "use strict";
return { return {
name:"example/mobile", name: "example/mobile",
definition: { definition: {
"name": "Mobile", "name": "Mobile",
"description": "Allows elements with pertinence to mobile usage and development", "description": "Allows elements with pertinence to mobile usage and development",

View File

@@ -31,14 +31,15 @@ define([
RemsTelemetryProvider RemsTelemetryProvider
) { ) {
"use strict"; "use strict";
return { return {
name:"example/msl", name: "example/msl",
definition: { definition: {
"name" : "Mars Science Laboratory Data Adapter", "name": "Mars Science Laboratory Data Adapter",
"extensions" : { "extensions": {
"types": [ "types": [
{ {
"name":"Mars Science Laboratory", "name": "Mars Science Laboratory",
"key": "msl.curiosity", "key": "msl.curiosity",
"cssClass": "icon-object" "cssClass": "icon-object"
}, },
@@ -89,7 +90,7 @@ define([
], ],
"services": [ "services": [
{ {
"key":"rems.adapter", "key": "rems.adapter",
"implementation": RemsTelemetryServerAdapter, "implementation": RemsTelemetryServerAdapter,
"depends": ["$http", "$log", "REMS_WS_URL"] "depends": ["$http", "$log", "REMS_WS_URL"]
} }

View File

@@ -38,7 +38,7 @@ define(
"identifier": "msl", "identifier": "msl",
"instruments": [ "instruments": [
{ {
"name":"rems", "name": "rems",
"identifier": "rems", "identifier": "rems",
"measurements": [ "measurements": [
{ {

View File

@@ -81,6 +81,7 @@ define(
(dictionary.instruments || []).forEach(function (instrument) { (dictionary.instruments || []).forEach(function (instrument) {
addInstrument(instrument, "msl:curiosity"); addInstrument(instrument, "msl:curiosity");
}); });
return models; return models;
} }
@@ -90,6 +91,7 @@ define(
} }
}; };
} }
return RemsTelemetryModelProvider; return RemsTelemetryModelProvider;
} }
); );

View File

@@ -74,6 +74,7 @@ define (
RemsTelemetryProvider.prototype.subscribe = function (callback, requests) { RemsTelemetryProvider.prototype.subscribe = function (callback, requests) {
return function () {}; return function () {};
}; };
RemsTelemetryProvider.prototype.unsubscribe = function (callback, requests) { RemsTelemetryProvider.prototype.unsubscribe = function (callback, requests) {
return function () {}; return function () {};
}; };

View File

@@ -57,6 +57,7 @@ define(
RemsTelemetrySeries.prototype.getPointCount = function () { RemsTelemetrySeries.prototype.getPointCount = function () {
return this.data.length; return this.data.length;
}; };
/** /**
* The domain value at the given index. The Rems telemetry data is * 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 * time ordered, so the domain value is the time stamp of each data

View File

@@ -95,28 +95,32 @@ define(
}); });
} }
}); });
return data; return data;
} }
function fallbackToLocal() { function fallbackToLocal() {
self.$log.warn("Loading REMS data failed, probably due to" + self.$log.warn("Loading REMS data failed, probably due to"
" cross origin policy. Falling back to local data"); + " cross origin policy. Falling back to local data");
return self.$http.get(self.localDataURI); return self.$http.get(self.localDataURI);
} }
//Filter results to match request parameters //Filter results to match request parameters
function filterResults(results) { function filterResults(results) {
return results.filter(function (result) { return results.filter(function (result) {
return result.date >= (request.start || Number.MIN_VALUE) && return result.date >= (request.start || Number.MIN_VALUE)
result.date <= (request.end || Number.MAX_VALUE); && result.date <= (request.end || Number.MAX_VALUE);
}); });
} }
function packageAndResolve(results) { 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)) return (this.promise = this.promise || this.$http.get(this.REMS_WS_URL))
.catch(fallbackToLocal) .catch(fallbackToLocal)
.then(processResponse) .then(processResponse)

View File

@@ -39,7 +39,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/notifications", name: "example/notifications",
definition: { definition: {
"extensions": { "extensions": {
"templates": [ "templates": [

View File

@@ -91,7 +91,6 @@ define(
} }
}; };
/* /*
Demonstrates launching an error dialog Demonstrates launching an error dialog
*/ */
@@ -132,9 +131,9 @@ define(
var dialog, var dialog,
model = { model = {
title: "Info Dialog Example", title: "Info Dialog Example",
actionText: "This is an example of a blocking info" + actionText: "This is an example of a blocking info"
" dialog. This dialog can be used to draw the user's" + + " dialog. This dialog can be used to draw the user's"
" attention to an event.", + " attention to an event.",
severity: "info", severity: "info",
primaryOption: { primaryOption: {
label: "OK", label: "OK",
@@ -153,6 +152,7 @@ define(
}; };
} }
return DialogLaunchController; return DialogLaunchController;
} }
); );

View File

@@ -42,9 +42,11 @@ define(
DialogLaunchIndicator.prototype.getGlyphClass = function () { DialogLaunchIndicator.prototype.getGlyphClass = function () {
return 'ok'; return 'ok';
}; };
DialogLaunchIndicator.prototype.getText = function () { DialogLaunchIndicator.prototype.getText = function () {
return "Launch test dialog"; return "Launch test dialog";
}; };
DialogLaunchIndicator.prototype.getDescription = function () { DialogLaunchIndicator.prototype.getDescription = function () {
return "Launch test dialog"; return "Launch test dialog";
}; };

View File

@@ -48,7 +48,8 @@ define(
"Eros turpis, pulvinar turpis eros eu", "Eros turpis, pulvinar turpis eros eu",
"Lundium nascetur a, lectus montes ac, parturient in natoque, duis risus risus pulvinar pid rhoncus, habitasse auctor natoque!" "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 +62,7 @@ define(
severity: "error" severity: "error"
}); });
}; };
/** /**
* Launch a new notification with a severity of 'Alert'. * Launch a new notification with a severity of 'Alert'.
*/ */
@@ -73,7 +75,6 @@ define(
}); });
}; };
/** /**
* Launch a new notification with a progress bar that is updated * Launch a new notification with a progress bar that is updated
* periodically, tracking an ongoing process. * periodically, tracking an ongoing process.
@@ -93,10 +94,10 @@ define(
* @param notification * @param notification
*/ */
function incrementProgress() { function incrementProgress() {
progress = Math.min(100, Math.floor(progress + Math.random() * 30)) progress = Math.min(100, Math.floor(progress + Math.random() * 30));
let progressText = ["Estimated time" + let progressText = ["Estimated time"
" remaining:" + + " remaining:"
" about ", 60 - Math.floor((progress / 100) * 60), " seconds"].join(" "); + " about ", 60 - Math.floor((progress / 100) * 60), " seconds"].join(" ");
notification.progress(progress, progressText); notification.progress(progress, progressText);
if (progress < 100) { if (progress < 100) {
@@ -120,6 +121,7 @@ define(
}; };
} }
return NotificationLaunchController; return NotificationLaunchController;
} }
); );

View File

@@ -42,9 +42,11 @@ define(
NotificationLaunchIndicator.prototype.getGlyphClass = function () { NotificationLaunchIndicator.prototype.getGlyphClass = function () {
return 'ok'; return 'ok';
}; };
NotificationLaunchIndicator.prototype.getText = function () { NotificationLaunchIndicator.prototype.getText = function () {
return "Launch notification"; return "Launch notification";
}; };
NotificationLaunchIndicator.prototype.getDescription = function () { NotificationLaunchIndicator.prototype.getDescription = function () {
return "Launch notification"; return "Launch notification";
}; };

View File

@@ -29,7 +29,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/persistence", name: "example/persistence",
definition: { definition: {
"extensions": { "extensions": {
"components": [ "components": [

View File

@@ -30,8 +30,6 @@ define(
function () { function () {
'use strict'; 'use strict';
function BrowserPersistenceProvider($q, SPACE) { function BrowserPersistenceProvider($q, SPACE) {
var spaces = SPACE ? [SPACE] : [], var spaces = SPACE ? [SPACE] : [],
caches = {}, caches = {},
@@ -51,6 +49,7 @@ define(
}, },
listObjects: function (space) { listObjects: function (space) {
var cache = caches[space]; var cache = caches[space];
return promises.as( return promises.as(
cache ? Object.keys(cache) : null cache ? Object.keys(cache) : null
); );
@@ -68,6 +67,7 @@ define(
}, },
readObject: function (space, key) { readObject: function (space, key) {
var cache = caches[space]; var cache = caches[space];
return promises.as( return promises.as(
cache ? cache[key] : null cache ? cache[key] : null
); );

View File

@@ -29,7 +29,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/policy", name: "example/policy",
definition: { definition: {
"name": "Example Policy", "name": "Example Policy",
"description": "Provides an example of using policies to prohibit actions.", "description": "Provides an example of using policies to prohibit actions.",

View File

@@ -37,6 +37,7 @@ define(
model = (domainObject && domainObject.getModel()) || {}, model = (domainObject && domainObject.getModel()) || {},
name = model.name || "", name = model.name || "",
metadata = action.getMetadata() || {}; metadata = action.getMetadata() || {};
return metadata.key !== 'remove' || name.indexOf('foo') < 0; return metadata.key !== 'remove' || name.indexOf('foo') < 0;
} }
}; };

View File

@@ -31,7 +31,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/profiling", name: "example/profiling",
definition: { definition: {
"extensions": { "extensions": {
"indicators": [ "indicators": [

View File

@@ -29,7 +29,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/scratchpad", name: "example/scratchpad",
definition: { definition: {
"extensions": { "extensions": {
"roots": [ "roots": [

View File

@@ -54,13 +54,14 @@ define(
if (space === 'scratch') { if (space === 'scratch') {
this.table[key] = JSON.stringify(value); this.table[key] = JSON.stringify(value);
} }
return this.$q.when(space === 'scratch'); return this.$q.when(space === 'scratch');
}; };
ScratchPersistenceProvider.prototype.readObject = function (space, key) { ScratchPersistenceProvider.prototype.readObject = function (space, key) {
return this.$q.when( return this.$q.when(
(space === 'scratch' && this.table[key]) ? (space === 'scratch' && this.table[key])
JSON.parse(this.table[key]) : undefined ? JSON.parse(this.table[key]) : undefined
); );
}; };
@@ -68,6 +69,7 @@ define(
if (space === 'scratch') { if (space === 'scratch') {
delete this.table[key]; delete this.table[key];
} }
return this.$q.when(space === 'scratch'); return this.$q.when(space === 'scratch');
}; };

View File

@@ -7,9 +7,9 @@ export default {
data() { data() {
return { return {
msg: 'Hello world!' msg: 'Hello world!'
} };
} }
} };
</script> </script>
<style> <style>

View File

@@ -17,6 +17,7 @@ function SimpleVuePlugin() {
}, },
view: function (domainObject) { view: function (domainObject) {
var vm; var vm;
return { return {
show: function (container) { show: function (container) {
vm = new Vue(HelloWorld); vm = new Vue(HelloWorld);
@@ -29,7 +30,7 @@ function SimpleVuePlugin() {
} }
}); });
} };
} }
export default SimpleVuePlugin export default SimpleVuePlugin;

View File

@@ -22,31 +22,111 @@ define([
menusTemplate menusTemplate
) { ) {
return { return {
name:"example/styleguide", name: "example/styleguide",
definition: { definition: {
"name": "Open MCT Style Guide", "name": "Open MCT Style Guide",
"description": "Examples and documentation illustrating UI styles in use in Open MCT.", "description": "Examples and documentation illustrating UI styles in use in Open MCT.",
"extensions": "extensions":
{ {
"types": [ "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.intro",
{ "key": "styleguide.colors", "name": "Colors", "cssClass": "icon-page", "description": "" }, "name": "Introduction",
{ "key": "styleguide.status", "name": "status", "cssClass": "icon-page", "description": "Limits, telemetry paused, etc." }, "cssClass": "icon-page",
{ "key": "styleguide.glyphs", "name": "Glyphs", "cssClass": "icon-page", "description": "Glyphs overview" }, "description": "Introduction and overview to the style guide"
{ "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.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": [ "views": [
{ "key": "styleguide.intro", "type": "styleguide.intro", "template": introTemplate, "editable": false }, {
{ "key": "styleguide.standards", "type": "styleguide.standards", "template": standardsTemplate, "editable": false }, "key": "styleguide.intro",
{ "key": "styleguide.colors", "type": "styleguide.colors", "template": colorsTemplate, "editable": false }, "type": "styleguide.intro",
{ "key": "styleguide.status", "type": "styleguide.status", "template": statusTemplate, "editable": false }, "template": introTemplate,
{ "key": "styleguide.glyphs", "type": "styleguide.glyphs", "template": glyphsTemplate, "editable": false }, "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.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": [ "roots": [
{ {
@@ -56,7 +136,7 @@ define([
"models": [ "models": [
{ {
"id": "styleguide:home", "id": "styleguide:home",
"priority" : "preferred", "priority": "preferred",
"model": { "model": {
"type": "folder", "type": "folder",
"name": "Style Guide Home", "name": "Style Guide Home",
@@ -73,7 +153,7 @@ define([
}, },
{ {
"id": "styleguide:ui-elements", "id": "styleguide:ui-elements",
"priority" : "preferred", "priority": "preferred",
"model": { "model": {
"type": "folder", "type": "folder",
"name": "UI Elements", "name": "UI Elements",

View File

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

3
indexTest.js Normal file
View File

@@ -0,0 +1,3 @@
const testsContext = require.context('.', true, /\/(src|platform)\/.*Spec.js$/);
testsContext.keys().forEach(testsContext);

View File

@@ -23,7 +23,7 @@
/*global module,process*/ /*global module,process*/
const devMode = process.env.NODE_ENV !== 'production'; const devMode = process.env.NODE_ENV !== 'production';
const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'FirefoxHeadless']; const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'ChromeHeadless'];
const coverageEnabled = process.env.COVERAGE === 'true'; const coverageEnabled = process.env.COVERAGE === 'true';
const reporters = ['progress', 'html']; const reporters = ['progress', 'html'];
@@ -52,12 +52,16 @@ module.exports = (config) => {
basePath: '', basePath: '',
frameworks: ['jasmine'], frameworks: ['jasmine'],
files: [ files: [
'platform/**/*Spec.js', 'indexTest.js'
'src/**/*Spec.js'
], ],
port: 9876, port: 9876,
reporters: reporters, reporters: reporters,
browsers: browsers, browsers: browsers,
client: {
jasmine: {
random: false
}
},
customLaunchers: { customLaunchers: {
ChromeDebugging: { ChromeDebugging: {
base: 'Chrome', base: 'Chrome',
@@ -66,7 +70,7 @@ module.exports = (config) => {
} }
}, },
colors: true, colors: true,
logLevel: config.LOG_INFO, logLevel: config.LOG_DEBUG,
autoWatch: true, autoWatch: true,
// HTML test reporting. // HTML test reporting.
htmlReporter: { htmlReporter: {
@@ -82,20 +86,20 @@ module.exports = (config) => {
reports: ['html', 'lcovonly', 'text-summary'], reports: ['html', 'lcovonly', 'text-summary'],
thresholds: { thresholds: {
global: { global: {
lines: 62 lines: 64
} }
} }
}, },
preprocessors: { preprocessors: {
'platform/**/*Spec.js': ['webpack', 'sourcemap'], 'indexTest.js': ['webpack', 'sourcemap']
'src/**/*Spec.js': ['webpack', 'sourcemap']
}, },
webpack: webpackConfig, webpack: webpackConfig,
webpackMiddleware: { webpackMiddleware: {
stats: 'errors-only', stats: 'errors-only',
logLevel: 'warn' logLevel: 'warn'
}, },
concurrency: 1,
singleRun: true, singleRun: true,
browserNoActivityTimeout: 90000 browserNoActivityTimeout: 90000
}); });
} };

View File

@@ -39,16 +39,16 @@
"istanbul-instrumenter-loader": "^3.0.1", "istanbul-instrumenter-loader": "^3.0.1",
"jasmine-core": "^3.1.0", "jasmine-core": "^3.1.0",
"jsdoc": "^3.3.2", "jsdoc": "^3.3.2",
"karma": "^2.0.3", "karma": "5.1.1",
"karma-chrome-launcher": "^2.2.0", "karma-chrome-launcher": "3.1.0",
"karma-firefox-launcher": "^1.3.0", "karma-firefox-launcher": "1.3.0",
"karma-cli": "^1.0.1", "karma-cli": "2.0.0",
"karma-coverage": "^1.1.2", "karma-coverage": "2.0.3",
"karma-coverage-istanbul-reporter": "^2.1.1", "karma-coverage-istanbul-reporter": "3.0.3",
"karma-html-reporter": "^0.2.7", "karma-html-reporter": "0.2.7",
"karma-jasmine": "^1.1.2", "karma-jasmine": "3.3.1",
"karma-sourcemap-loader": "^0.3.7", "karma-sourcemap-loader": "0.3.7",
"karma-webpack": "^3.0.0", "karma-webpack": "4.0.2",
"location-bar": "^3.0.1", "location-bar": "^3.0.1",
"lodash": "^4.17.12", "lodash": "^4.17.12",
"markdown-toc": "^0.11.7", "markdown-toc": "^0.11.7",

View File

@@ -47,7 +47,7 @@ define([
) { ) {
return { return {
name:"platform/commonUI/about", name: "platform/commonUI/about",
definition: { definition: {
"name": "About Open MCT", "name": "About Open MCT",
"extensions": { "extensions": {

View File

@@ -20,7 +20,6 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/** /**
* Implements Open MCT's About dialog. * Implements Open MCT's About dialog.
* @namespace platform/commonUI/about * @namespace platform/commonUI/about

View File

@@ -31,8 +31,14 @@ define(
beforeEach(function () { beforeEach(function () {
testVersions = [ 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"]); mockWindow = jasmine.createSpyObj("$window", ["open"]);
controller = new AboutController(testVersions, mockWindow); controller = new AboutController(testVersions, mockWindow);
@@ -51,7 +57,6 @@ define(
expect(mockWindow.open).toHaveBeenCalledWith("#/licenses"); expect(mockWindow.open).toHaveBeenCalledWith("#/licenses");
}); });
}); });
} }

View File

@@ -49,7 +49,7 @@ define([
) { ) {
return { return {
name:"platform/commonUI/browse", name: "platform/commonUI/browse",
definition: { definition: {
"extensions": { "extensions": {
"routes": [ "routes": [

View File

@@ -46,6 +46,7 @@ define(
NavigateAction.prototype.perform = function () { NavigateAction.prototype.perform = function () {
if (this.navigationService.shouldNavigate()) { if (this.navigationService.shouldNavigate()) {
this.navigationService.setNavigation(this.domainObject, true); this.navigationService.setNavigation(this.domainObject, true);
return Promise.resolve({}); return Promise.resolve({});
} }

View File

@@ -69,8 +69,10 @@ define(
NavigationService.prototype.setNavigation = function (domainObject, force) { NavigationService.prototype.setNavigation = function (domainObject, force) {
if (force) { if (force) {
this.doNavigation(domainObject); this.doNavigation(domainObject);
return true; return true;
} }
if (this.navigated === domainObject) { if (this.navigated === domainObject) {
return true; return true;
} }
@@ -81,6 +83,7 @@ define(
} }
this.doNavigation(domainObject); this.doNavigation(domainObject);
return true; return true;
}; };
@@ -120,6 +123,7 @@ define(
*/ */
NavigationService.prototype.shouldNavigate = function () { NavigationService.prototype.shouldNavigate = function () {
var doNotNavigate = this.shouldWarnBeforeNavigate(); var doNotNavigate = this.shouldWarnBeforeNavigate();
return !doNotNavigate || this.$window.confirm(doNotNavigate); return !doNotNavigate || this.$window.confirm(doNotNavigate);
}; };
@@ -135,6 +139,7 @@ define(
*/ */
NavigationService.prototype.checkBeforeNavigation = function (checkFn) { NavigationService.prototype.checkBeforeNavigation = function (checkFn) {
this.checks.push(checkFn); this.checks.push(checkFn);
return function removeCheck() { return function removeCheck() {
this.checks = this.checks.filter(function (fn) { this.checks = this.checks.filter(function (fn) {
return checkFn !== fn; return checkFn !== fn;
@@ -172,6 +177,7 @@ define(
if (reasons.length) { if (reasons.length) {
return reasons.join('\n'); return reasons.join('\n');
} }
return false; return false;
}; };
@@ -186,6 +192,7 @@ define(
if (shouldWarnBeforeNavigate) { if (shouldWarnBeforeNavigate) {
return shouldWarnBeforeNavigate; return shouldWarnBeforeNavigate;
} }
if (this.oldUnload) { if (this.oldUnload) {
return this.oldUnload.apply(undefined, [].slice.apply(arguments)); return this.oldUnload.apply(undefined, [].slice.apply(arguments));
} }

View File

@@ -40,6 +40,7 @@ define([], function () {
function getParent(domainObject) { function getParent(domainObject) {
var context = domainObject.getCapability('context'); var context = domainObject.getCapability('context');
return context.getParent(); return context.getParent();
} }

View File

@@ -53,6 +53,7 @@ define([
it("sets navigation if it is allowed", function () { it("sets navigation if it is allowed", function () {
mockNavigationService.shouldNavigate.and.returnValue(true); mockNavigationService.shouldNavigate.and.returnValue(true);
return action.perform() return action.perform()
.then(function () { .then(function () {
expect(mockNavigationService.setNavigation) expect(mockNavigationService.setNavigation)
@@ -63,6 +64,7 @@ define([
it("does not set navigation if it is not allowed", function () { it("does not set navigation if it is not allowed", function () {
mockNavigationService.shouldNavigate.and.returnValue(false); mockNavigationService.shouldNavigate.and.returnValue(false);
var onSuccess = jasmine.createSpy('onSuccess'); var onSuccess = jasmine.createSpy('onSuccess');
return action.perform() return action.perform()
.then(onSuccess, function () { .then(onSuccess, function () {
expect(onSuccess).not.toHaveBeenCalled(); expect(onSuccess).not.toHaveBeenCalled();

View File

@@ -79,7 +79,6 @@ define(
navigationService.addListener(callback); navigationService.addListener(callback);
navigationService.removeListener(callback); navigationService.removeListener(callback);
navigationService.setNavigation(testObject); navigationService.setNavigation(testObject);
expect(callback).not.toHaveBeenCalled(); expect(callback).not.toHaveBeenCalled();
}); });

View File

@@ -70,6 +70,7 @@ define([
jasmine.createSpy('throttled-' + mockThrottledFns.length); jasmine.createSpy('throttled-' + mockThrottledFns.length);
mockThrottledFn.and.callFake(fn); mockThrottledFn.and.callFake(fn);
mockThrottledFns.push(mockThrottledFn); mockThrottledFns.push(mockThrottledFn);
return mockThrottledFn; return mockThrottledFn;
}); });
mockTopic.and.returnValue(mockMutationTopic); mockTopic.and.returnValue(mockMutationTopic);
@@ -81,7 +82,7 @@ define([
}[c]; }[c];
}); });
mockDomainObject.hasCapability.and.callFake(function (c) { mockDomainObject.hasCapability.and.callFake(function (c) {
return !!mockDomainObject.getCapability(c); return Boolean(mockDomainObject.getCapability(c));
}); });
mockParentObject.getCapability.and.callFake(function (c) { mockParentObject.getCapability.and.callFake(function (c) {
return { return {
@@ -102,7 +103,6 @@ define([
); );
}); });
it("listens for mutation with a throttled function", function () { it("listens for mutation with a throttled function", function () {
expect(mockMutationTopic.listen) expect(mockMutationTopic.listen)
.toHaveBeenCalledWith(jasmine.any(Function)); .toHaveBeenCalledWith(jasmine.any(Function));
@@ -129,8 +129,8 @@ define([
}); });
[false, true].forEach(function (isEditRoot) { [false, true].forEach(function (isEditRoot) {
var caseName = isEditRoot ? var caseName = isEditRoot
"that are being edited" : "that are not being edited"; ? "that are being edited" : "that are not being edited";
function itNavigatesAsExpected() { function itNavigatesAsExpected() {
if (isOrphan && !isEditRoot) { if (isOrphan && !isEditRoot) {

View File

@@ -45,7 +45,7 @@ define([
) { ) {
return { return {
name:"platform/commonUI/dialog", name: "platform/commonUI/dialog",
definition: { definition: {
"extensions": { "extensions": {
"services": [ "services": [

View File

@@ -31,13 +31,13 @@
</mct-form> </mct-form>
</div> </div>
<div class="c-overlay__button-bar"> <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-class="{ disabled: !createForm.$valid }"
ng-click="ngModel.confirm()"> ng-click="ngModel.confirm()">
OK OK
</a> </button>
<a class='c-button ' <button class='c-button '
ng-click="ngModel.cancel()"> ng-click="ngModel.cancel()">
Cancel Cancel
</a> </button>
</div> </div>

View File

@@ -31,13 +31,13 @@
</mct-include> </mct-include>
</div> </div>
<div class="c-overlay__button-bar"> <div class="c-overlay__button-bar">
<a ng-repeat="option in ngModel.dialog.options" <button ng-repeat="option in ngModel.dialog.options"
href='' href=''
class="s-button lg" class="s-button lg"
title="{{option.description}}" title="{{option.description}}"
ng-click="ngModel.confirm(option.key)" ng-click="ngModel.confirm(option.key)"
ng-class="{ major: $first, subtle: !$first }"> ng-class="{ major: $first, subtle: !$first }">
{{option.name}} {{option.name}}
</a> </button>
</div> </div>
</mct-container> </mct-container>

View File

@@ -24,7 +24,7 @@
<div class="c-overlay__outer"> <div class="c-overlay__outer">
<button ng-click="ngModel.cancel()" <button ng-click="ngModel.cancel()"
ng-if="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 class="c-overlay__contents" ng-transclude></div>
</div> </div>
</div> </div>

View File

@@ -28,7 +28,6 @@ define(
// the a specific template that can be included via mct-include // 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>'; var TEMPLATE = '<mct-include ng-model="overlay" key="key" ng-class="typeClass"></mct-include>';
/** /**
* The OverlayService is responsible for pre-pending templates to * The OverlayService is responsible for pre-pending templates to
* the body of the document, which is useful for displaying templates * the body of the document, which is useful for displaying templates
@@ -53,6 +52,7 @@ define(
this.findBody = function () { this.findBody = function () {
return $document.find('body'); return $document.find('body');
}; };
this.newScope = function () { this.newScope = function () {
return $rootScope.$new(); return $rootScope.$new();
}; };

View File

@@ -129,8 +129,8 @@ define(
); );
}); });
it("invokes the overlay service with the correct parameters when" + it("invokes the overlay service with the correct parameters when"
" a blocking dialog is requested", function () { + " a blocking dialog is requested", function () {
var dialogModel = {}; var dialogModel = {};
expect(dialogService.showBlockingMessage(dialogModel)).not.toBe(false); expect(dialogService.showBlockingMessage(dialogModel)).not.toBe(false);
expect(mockOverlayService.createOverlay).toHaveBeenCalledWith( expect(mockOverlayService.createOverlay).toHaveBeenCalledWith(

View File

@@ -48,7 +48,7 @@ define(
mockScope = jasmine.createSpyObj("scope", ["$destroy"]); mockScope = jasmine.createSpyObj("scope", ["$destroy"]);
mockTimeout = function (callback) { mockTimeout = function (callback) {
callback(); callback();
} };
mockDocument.find.and.returnValue(mockBody); mockDocument.find.and.returnValue(mockBody);
mockCompile.and.returnValue(mockTemplate); mockCompile.and.returnValue(mockTemplate);

View File

@@ -56,6 +56,7 @@ define(
//navigate back to parent because nothing to show. //navigate back to parent because nothing to show.
return domainObject.getCapability("location").getOriginal().then(function (original) { return domainObject.getCapability("location").getOriginal().then(function (original) {
parent = original.getCapability("context").getParent(); parent = original.getCapability("context").getParent();
return parent.getCapability("action").perform("navigate"); return parent.getCapability("action").perform("navigate");
}); });
} }
@@ -78,9 +79,10 @@ define(
*/ */
CancelAction.appliesTo = function (context) { CancelAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject; var domainObject = (context || {}).domainObject;
return domainObject !== undefined &&
domainObject.hasCapability('editor') && return domainObject !== undefined
domainObject.getCapability('editor').isEditContextRoot(); && domainObject.hasCapability('editor')
&& domainObject.getCapability('editor').isEditContextRoot();
}; };
return CancelAction; return CancelAction;

View File

@@ -91,9 +91,9 @@ define(
// Only allow editing of types that support it and are not already // Only allow editing of types that support it and are not already
// being edited // being edited
return type && type.hasFeature('creation') && return type && type.hasFeature('creation')
domainObject.hasCapability('editor') && && domainObject.hasCapability('editor')
!domainObject.getCapability('editor').isEditContextRoot(); && !domainObject.getCapability('editor').isEditContextRoot();
}; };
return EditAction; return EditAction;

View File

@@ -24,7 +24,6 @@ define(
[], [],
function () { function () {
/** /**
* Add one domain object to another's composition. * Add one domain object to another's composition.
* @constructor * @constructor
@@ -42,8 +41,9 @@ define(
// Link these objects // Link these objects
function doLink() { function doLink() {
var composition = self.domainObject && var composition = self.domainObject
self.domainObject.getCapability('composition'); && self.domainObject.getCapability('composition');
return composition && composition.add(self.selectedObject); return composition && composition.add(self.selectedObject);
} }

View File

@@ -99,4 +99,3 @@ define(
); );

View File

@@ -51,6 +51,7 @@ define(
// Property definition is same as form row definition // Property definition is same as form row definition
var row = JSON.parse(JSON.stringify(property.getDefinition())); var row = JSON.parse(JSON.stringify(property.getDefinition()));
row.key = index; row.key = index;
return row; return row;
}).filter(function (row) { }).filter(function (row) {
// Only show properties which are editable // Only show properties which are editable

View File

@@ -86,10 +86,11 @@ define(
*/ */
SaveAction.appliesTo = function (context) { SaveAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject; var domainObject = (context || {}).domainObject;
return domainObject !== undefined &&
domainObject.hasCapability('editor') && return domainObject !== undefined
domainObject.getCapability('editor').isEditContextRoot() && && domainObject.hasCapability('editor')
domainObject.getModel().persisted !== undefined; && domainObject.getCapability('editor').isEditContextRoot()
&& domainObject.getModel().persisted !== undefined;
}; };
return SaveAction; return SaveAction;

View File

@@ -20,7 +20,6 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
define([ define([
'../creation/CreateWizard', '../creation/CreateWizard',
'./SaveInProgressDialog' './SaveInProgressDialog'
@@ -50,6 +49,7 @@ function (
this.injectObjectService = function () { this.injectObjectService = function () {
this.objectService = $injector.get("objectService"); this.objectService = $injector.get("objectService");
}; };
this.dialogService = dialogService; this.dialogService = dialogService;
this.copyService = copyService; this.copyService = copyService;
this.notificationService = notificationService; this.notificationService = notificationService;
@@ -75,15 +75,10 @@ function (
if (!this.objectService) { if (!this.objectService) {
this.injectObjectService(); this.injectObjectService();
} }
return this.objectService; return this.objectService;
}; };
function resolveWith(object) {
return function () {
return object;
};
}
/** /**
* Save changes and conclude editing. * Save changes and conclude editing.
* *
@@ -101,7 +96,6 @@ function (
SaveAsAction.prototype.save = function () { SaveAsAction.prototype.save = function () {
var self = this, var self = this,
domainObject = this.domainObject, domainObject = this.domainObject,
copyService = this.copyService,
dialog = new SaveInProgressDialog(this.dialogService), dialog = new SaveInProgressDialog(this.dialogService),
toUndirty = []; toUndirty = [];
@@ -118,11 +112,13 @@ function (
function showBlockingDialog(object) { function showBlockingDialog(object) {
dialog.show(); dialog.show();
return object; return object;
} }
function hideBlockingDialog(object) { function hideBlockingDialog(object) {
dialog.hide(); dialog.hide();
return object; return object;
} }
@@ -136,18 +132,22 @@ function (
return fetchObject(object.getModel().location); return fetchObject(object.getModel().location);
} }
function allowClone(objectToClone) { function saveObject(parent) {
var allowed = return this.openmct.editor.save().then(() => {
(objectToClone.getId() === domainObject.getId()) || // Force mutation for search indexing
objectToClone.getCapability('location').isOriginal(); return parent;
if (allowed) { });
toUndirty.push(objectToClone);
}
return allowed;
} }
function cloneIntoParent(parent) { function addSavedObjectToParent(parent) {
return copyService.perform(domainObject, parent, allowClone); return parent.getCapability("composition")
.add(domainObject)
.then(function (addedObject) {
return parent.getCapability("persistence").persist()
.then(function () {
return addedObject;
});
});
} }
function undirty(object) { function undirty(object) {
@@ -156,30 +156,22 @@ function (
function undirtyOriginals(object) { function undirtyOriginals(object) {
return Promise.all(toUndirty.map(undirty)) return Promise.all(toUndirty.map(undirty))
.then(resolveWith(object)); .then(() => {
return object;
});
} }
function saveAfterClone(clonedObject) { function indexForSearch(addedObject) {
return this.openmct.editor.save().then(() => { addedObject.useCapability('mutation', (model) => {
// Force mutation for search indexing
return clonedObject;
})
}
function finishEditing(clonedObject) {
return fetchObject(clonedObject.getId())
}
function indexForSearch(savedObject) {
savedObject.useCapability('mutation', (model) => {
return model; return model;
}); });
return savedObject; return addedObject;
} }
function onSuccess(object) { function onSuccess(object) {
self.notificationService.info("Save Succeeded"); self.notificationService.info("Save Succeeded");
return object; return object;
} }
@@ -188,6 +180,7 @@ function (
if (reason !== "user canceled") { if (reason !== "user canceled") {
self.notificationService.error("Save Failed"); self.notificationService.error("Save Failed");
} }
throw reason; throw reason;
} }
@@ -195,17 +188,18 @@ function (
.then(doWizardSave) .then(doWizardSave)
.then(showBlockingDialog) .then(showBlockingDialog)
.then(getParent) .then(getParent)
.then(cloneIntoParent) .then(saveObject)
.then(addSavedObjectToParent)
.then(undirtyOriginals) .then(undirtyOriginals)
.then(saveAfterClone) .then((addedObject) => {
.then(finishEditing) return fetchObject(addedObject.getId());
})
.then(indexForSearch) .then(indexForSearch)
.then(hideBlockingDialog) .then(hideBlockingDialog)
.then(onSuccess) .then(onSuccess)
.catch(onFailure); .catch(onFailure);
}; };
/** /**
* Check if this action is applicable in a given context. * Check if this action is applicable in a given context.
* This will ensure that a domain object is present in the context, * This will ensure that a domain object is present in the context,
@@ -214,10 +208,11 @@ function (
*/ */
SaveAsAction.appliesTo = function (context) { SaveAsAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject; var domainObject = (context || {}).domainObject;
return domainObject !== undefined &&
domainObject.hasCapability('editor') && return domainObject !== undefined
domainObject.getCapability('editor').isEditContextRoot() && && domainObject.hasCapability('editor')
domainObject.getModel().persisted === undefined; && domainObject.getCapability('editor').isEditContextRoot()
&& domainObject.getModel().persisted === undefined;
}; };
return SaveAsAction; return SaveAsAction;

View File

@@ -83,6 +83,7 @@ define(
*/ */
EditorCapability.prototype.save = function () { EditorCapability.prototype.save = function () {
console.warn('DEPRECATED: cannot save via edit capability, use openmct.editor instead.'); console.warn('DEPRECATED: cannot save via edit capability, use openmct.editor instead.');
return Promise.resolve(); return Promise.resolve();
}; };
@@ -95,6 +96,7 @@ define(
*/ */
EditorCapability.prototype.finish = function () { EditorCapability.prototype.finish = function () {
console.warn('DEPRECATED: cannot finish via edit capability, use openmct.editor instead.'); console.warn('DEPRECATED: cannot finish via edit capability, use openmct.editor instead.');
return Promise.resolve(); return Promise.resolve();
}; };

View File

@@ -56,9 +56,10 @@ define(
capabilities.persistence = function (domainObject) { capabilities.persistence = function (domainObject) {
var original = var original =
(typeof persistenceCapability === 'function') ? (typeof persistenceCapability === 'function')
persistenceCapability(domainObject) : ? persistenceCapability(domainObject)
persistenceCapability; : persistenceCapability;
return new TransactionalPersistenceCapability( return new TransactionalPersistenceCapability(
self.$q, self.$q,
self.transactionService, self.transactionService,
@@ -66,6 +67,7 @@ define(
domainObject domainObject
); );
}; };
return capabilities; return capabilities;
}; };

View File

@@ -64,6 +64,7 @@ define(
wrappedPersistence.persist.bind(wrappedPersistence), wrappedPersistence.persist.bind(wrappedPersistence),
wrappedPersistence.refresh.bind(wrappedPersistence) wrappedPersistence.refresh.bind(wrappedPersistence)
); );
//Need to return a promise from this function //Need to return a promise from this function
return this.$q.when(true); return this.$q.when(true);
} else { } else {
@@ -74,6 +75,7 @@ define(
TransactionalPersistenceCapability.prototype.refresh = function () { TransactionalPersistenceCapability.prototype.refresh = function () {
this.transactionManager this.transactionManager
.clearTransactionsFor(this.domainObject.getId()); .clearTransactionsFor(this.domainObject.getId());
return this.persistenceCapability.refresh(); return this.persistenceCapability.refresh();
}; };

View File

@@ -48,9 +48,9 @@ define(
// Maintain all "conclude-editing" and "save" actions in the // Maintain all "conclude-editing" and "save" actions in the
// present context. // present context.
function updateActions() { function updateActions() {
$scope.saveActions = $scope.action ? $scope.saveActions = $scope.action
$scope.action.getActions(SAVE_ACTION_CONTEXT) : ? $scope.action.getActions(SAVE_ACTION_CONTEXT)
[]; : [];
$scope.saveActionsAsMenuOptions = $scope.saveActions.map(actionToMenuOption); $scope.saveActionsAsMenuOptions = $scope.saveActions.map(actionToMenuOption);
@@ -58,9 +58,9 @@ define(
clickedAction.perform(); clickedAction.perform();
}; };
$scope.otherEditActions = $scope.action ? $scope.otherEditActions = $scope.action
$scope.action.getActions(OTHERS_ACTION_CONTEXT) : ? $scope.action.getActions(OTHERS_ACTION_CONTEXT)
[]; : [];
// Required because Angular does not allow 'bind' // Required because Angular does not allow 'bind'
// in expressions. // in expressions.

View File

@@ -30,11 +30,11 @@ define(
function cancelEditing(domainObject) { function cancelEditing(domainObject) {
var navigatedObject = domainObject, var navigatedObject = domainObject,
editorCapability = navigatedObject && editorCapability = navigatedObject
navigatedObject.getCapability("editor"); && navigatedObject.getCapability("editor");
return editorCapability && return editorCapability
editorCapability.finish(); && editorCapability.finish();
} }
/** /**

View File

@@ -35,8 +35,8 @@ define(
// Update root object based on represented object // Update root object based on represented object
function updateRoot(domainObject) { function updateRoot(domainObject) {
var root = self.rootDomainObject, var root = self.rootDomainObject,
context = domainObject && context = domainObject
domainObject.getCapability('context'), && domainObject.getCapability('context'),
newRoot = context && context.getTrueRoot(), newRoot = context && context.getTrueRoot(),
oldId = root && root.getId(), oldId = root && root.getId(),
newId = newRoot && newRoot.getId(); newId = newRoot && newRoot.getId();
@@ -51,6 +51,7 @@ define(
// Update root when represented object changes // Update root when represented object changes
$scope.$watch('domainObject', updateRoot); $scope.$watch('domainObject', updateRoot);
} }
/** /**
* Get the root-level domain object, as reported by the * Get the root-level domain object, as reported by the
* represented domain object. * represented domain object.

View File

@@ -104,7 +104,6 @@ define(
// We will disable this. // We will disable this.
}; };
/** /**
* Metadata associated with a Create action. * Metadata associated with a Create action.
* @typedef {ActionMetadata} CreateActionMetadata * @typedef {ActionMetadata} CreateActionMetadata

View File

@@ -38,9 +38,9 @@ define(
function CreateMenuController($scope) { function CreateMenuController($scope) {
// Update the set of Create actions // Update the set of Create actions
function refreshActions() { function refreshActions() {
$scope.createActions = $scope.action ? $scope.createActions = $scope.action
$scope.action.getActions('create') : ? $scope.action.getActions('create')
[]; : [];
} }
// Listen for new instances of the represented object's // Listen for new instances of the represented object's

View File

@@ -114,6 +114,7 @@ define(
this.domainObject.useCapability("mutation", function () { this.domainObject.useCapability("mutation", function () {
return formModel; return formModel;
}); });
return this.domainObject; return this.domainObject;
}; };

View File

@@ -73,12 +73,13 @@ define(
// as a child contained by that parent. // as a child contained by that parent.
function addToComposition() { function addToComposition() {
var compositionCapability = parent.getCapability('composition'), var compositionCapability = parent.getCapability('composition'),
addResult = compositionCapability && addResult = compositionCapability
compositionCapability.add(newObject); && compositionCapability.add(newObject);
return self.$q.when(addResult).then(function (result) { return self.$q.when(addResult).then(function (result) {
if (!result) { if (!result) {
self.$log.error("Could not modify " + parent.getId()); self.$log.error("Could not modify " + parent.getId());
return undefined; return undefined;
} }
@@ -92,6 +93,7 @@ define(
// what space to create the new object's model in. // what space to create the new object's model in.
if (!persistence || !newObjectPersistence) { if (!persistence || !newObjectPersistence) {
self.$log.warn(NON_PERSISTENT_WARNING); self.$log.warn(NON_PERSISTENT_WARNING);
return self.$q.reject(new Error(NON_PERSISTENT_WARNING)); return self.$q.reject(new Error(NON_PERSISTENT_WARNING));
} }
@@ -99,8 +101,6 @@ define(
return newObjectPersistence.persist().then(addToComposition); return newObjectPersistence.persist().then(addToComposition);
}; };
return CreationService; return CreationService;
} }
); );

View File

@@ -38,8 +38,8 @@ define(
// * treeModel: The model for the embedded tree representation, // * treeModel: The model for the embedded tree representation,
// used for bi-directional object selection. // used for bi-directional object selection.
function setLocatingObject(domainObject, priorObject) { function setLocatingObject(domainObject, priorObject) {
var context = domainObject && var context = domainObject
domainObject.getCapability("context"), && domainObject.getCapability("context"),
contextRoot = context && context.getRoot(); contextRoot = context && context.getRoot();
if (contextRoot && contextRoot !== $scope.rootObject) { if (contextRoot && contextRoot !== $scope.rootObject) {
@@ -65,11 +65,12 @@ define(
$scope.ngModel[$scope.field] = domainObject; $scope.ngModel[$scope.field] = domainObject;
// Restrict which locations can be selected // Restrict which locations can be selected
if (domainObject && if (domainObject
$scope.structure && && $scope.structure
$scope.structure.validate) { && $scope.structure.validate) {
if (!$scope.structure.validate(domainObject)) { if (!$scope.structure.validate(domainObject)) {
setLocatingObject(priorObject, undefined); setLocatingObject(priorObject, undefined);
return; return;
} }
} }
@@ -78,7 +79,7 @@ define(
if ($scope.ngModelController) { if ($scope.ngModelController) {
$scope.ngModelController.$setValidity( $scope.ngModelController.$setValidity(
'composition', 'composition',
!!$scope.treeModel.selectedObject Boolean($scope.treeModel.selectedObject)
); );
} }
} }

View File

@@ -45,6 +45,7 @@ define(
// because it may be saved elsewhere // because it may be saved elsewhere
if ((key === 'edit' && category === 'view-control') || key === 'properties') { if ((key === 'edit' && category === 'view-control') || key === 'properties') {
let newStyleObject = objectUtils.toNewFormat(domainObject, domainObject.getId()); let newStyleObject = objectUtils.toNewFormat(domainObject, domainObject.getId());
return this.openmct.objects.isPersistable(newStyleObject); return this.openmct.objects.isPersistable(newStyleObject);
} }

View File

@@ -74,6 +74,7 @@ define(
model.configuration = model.configuration || {}; model.configuration = model.configuration || {};
model.configuration[this.key] = configuration; model.configuration[this.key] = configuration;
} }
domainObject.useCapability('mutation', function () { domainObject.useCapability('mutation', function () {
return model; return model;
}); });

View File

@@ -41,6 +41,7 @@ define(['./Transaction'], function (Transaction) {
Transaction.prototype.commit.bind(this), Transaction.prototype.commit.bind(this),
Transaction.prototype.cancel.bind(this) Transaction.prototype.cancel.bind(this)
); );
return Promise.resolve(true); return Promise.resolve(true);
}; };

View File

@@ -41,8 +41,12 @@ define([], function () {
* pair of callbacks from the transaction * pair of callbacks from the transaction
*/ */
Transaction.prototype.add = function (commit, cancel) { Transaction.prototype.add = function (commit, cancel) {
var callback = { commit: commit, cancel: cancel }; var callback = {
commit: commit,
cancel: cancel
};
this.callbacks.push(callback); this.callbacks.push(callback);
return function () { return function () {
this.callbacks = this.callbacks.filter(function (c) { this.callbacks = this.callbacks.filter(function (c) {
return c !== callback; return c !== callback;
@@ -91,6 +95,5 @@ define([], function () {
}; };
}); });
return Transaction; return Transaction;
}); });

View File

@@ -50,7 +50,7 @@ define([], function () {
* @returns {boolean} true if callbacks have been added * @returns {boolean} true if callbacks have been added
*/ */
TransactionManager.prototype.isScheduled = function (id) { TransactionManager.prototype.isScheduled = function (id) {
return !!this.clearTransactionFns[id]; return Boolean(this.clearTransactionFns[id]);
}; };
/** /**
@@ -77,6 +77,7 @@ define([], function () {
return promiseFn().then(nextFn); return promiseFn().then(nextFn);
}; };
} }
/** /**
* Clear any existing persistence calls for object with given ID. This ensures only the most recent persistence * 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. * call is executed. This should prevent stale objects being persisted and overwriting fresh ones.

View File

@@ -48,9 +48,9 @@ define(
* #cancel} are called * #cancel} are called
*/ */
TransactionService.prototype.startTransaction = function () { TransactionService.prototype.startTransaction = function () {
var transaction = this.isActive() ? var transaction = this.isActive()
new NestedTransaction(this.transactions[0]) : ? new NestedTransaction(this.transactions[0])
new Transaction(this.$log); : new Transaction(this.$log);
this.transactions.push(transaction); this.transactions.push(transaction);
}; };
@@ -99,13 +99,16 @@ define(
if (!transaction) { if (!transaction) {
return Promise.reject(); return Promise.reject();
} }
if (!this.isActive()) { if (!this.isActive()) {
return transaction.commit() return transaction.commit()
.then(function (r) { .then(function (r) {
this.cacheService.flush(); this.cacheService.flush();
return r; return r;
}.bind(this)); }.bind(this));
} }
return transaction.commit(); return transaction.commit();
}; };
@@ -119,6 +122,7 @@ define(
*/ */
TransactionService.prototype.cancel = function () { TransactionService.prototype.cancel = function () {
var transaction = this.transactions.pop(); var transaction = this.transactions.pop();
return transaction ? transaction.cancel() : Promise.reject(); return transaction ? transaction.cancel() : Promise.reject();
}; };

View File

@@ -102,7 +102,7 @@ define(
}); });
mockDomainObject.hasCapability.and.callFake(function (name) { mockDomainObject.hasCapability.and.callFake(function (name) {
return !!capabilities[name]; return Boolean(capabilities[name]);
}); });
capabilities.editor.finish.and.returnValue(mockPromise(true)); capabilities.editor.finish.and.returnValue(mockPromise(true));
@@ -123,8 +123,8 @@ define(
expect(CancelAction.appliesTo(actionContext)).toBeFalsy(); expect(CancelAction.appliesTo(actionContext)).toBeFalsy();
}); });
it("invokes the editor capability's cancel functionality when" + it("invokes the editor capability's cancel functionality when"
" performed", function () { + " performed", function () {
mockDomainObject.getModel.and.returnValue({persisted: 1}); mockDomainObject.getModel.and.returnValue({persisted: 1});
//Return true from navigate action //Return true from navigate action
capabilities.action.perform.and.returnValue(mockPromise(true)); capabilities.action.perform.and.returnValue(mockPromise(true));

View File

@@ -93,7 +93,6 @@ define(
action = new EditAndComposeAction(actionContext); action = new EditAndComposeAction(actionContext);
}); });
it("adds to the parent's composition when performed", function () { it("adds to the parent's composition when performed", function () {
action.perform(); action.perform();
expect(mockComposition.add) expect(mockComposition.add)
@@ -106,8 +105,8 @@ define(
expect(mockEditAction.perform).toHaveBeenCalled(); expect(mockEditAction.perform).toHaveBeenCalled();
}); });
it("Does not enable edit mode for objects that do not have an" + it("Does not enable edit mode for objects that do not have an"
" edit action", function () { + " edit action", function () {
mockActionCapability.getActions.and.returnValue([]); mockActionCapability.getActions.and.returnValue([]);
action.perform(); action.perform();
expect(mockEditAction.perform).not.toHaveBeenCalled(); expect(mockEditAction.perform).not.toHaveBeenCalled();

View File

@@ -64,7 +64,10 @@ define(
return true; return true;
} }
}; };
context = { someKey: "some value", domainObject: object }; context = {
someKey: "some value",
domainObject: object
};
dialogService = { dialogService = {
getUserInput: function () { getUserInput: function () {
return mockPromise(input); return mockPromise(input);

View File

@@ -138,6 +138,7 @@ define(
it("notifies if saving succeeded", function () { it("notifies if saving succeeded", function () {
var mockCallback = jasmine.createSpy("callback"); var mockCallback = jasmine.createSpy("callback");
mockEditorCapability.save.and.returnValue(Promise.resolve()); mockEditorCapability.save.and.returnValue(Promise.resolve());
return action.perform().then(mockCallback).then(function () { return action.perform().then(mockCallback).then(function () {
expect(mockNotificationService.info).toHaveBeenCalled(); expect(mockNotificationService.info).toHaveBeenCalled();
expect(mockNotificationService.error).not.toHaveBeenCalled(); expect(mockNotificationService.error).not.toHaveBeenCalled();
@@ -147,6 +148,7 @@ define(
it("notifies if saving failed", function () { it("notifies if saving failed", function () {
var mockCallback = jasmine.createSpy("callback"); var mockCallback = jasmine.createSpy("callback");
mockEditorCapability.save.and.returnValue(Promise.reject("some failure reason")); mockEditorCapability.save.and.returnValue(Promise.reject("some failure reason"));
return action.perform().then(mockCallback).then(function () { return action.perform().then(mockCallback).then(function () {
expect(mockNotificationService.error).toHaveBeenCalled(); expect(mockNotificationService.error).toHaveBeenCalled();
expect(mockNotificationService.info).not.toHaveBeenCalled(); expect(mockNotificationService.info).not.toHaveBeenCalled();

View File

@@ -97,7 +97,6 @@ define(
action = new SaveAndStopEditingAction(dialogService, notificationService, actionContext); action = new SaveAndStopEditingAction(dialogService, notificationService, actionContext);
}); });
it("only applies to domain object with an editor capability", function () { it("only applies to domain object with an editor capability", function () {
expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(true); expect(SaveAndStopEditingAction.appliesTo(actionContext)).toBe(true);
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");

View File

@@ -42,15 +42,15 @@ define(
function noop() {} function noop() {}
function mockPromise(value) { function mockPromise(value) {
return (value || {}).then ? value : return (value || {}).then ? value
{ : {
then: function (callback) { then: function (callback) {
return mockPromise(callback(value)); return mockPromise(callback(value));
}, },
catch: function (callback) { catch: function (callback) {
return mockPromise(callback(value)); return mockPromise(callback(value));
} }
} ; };
} }
beforeEach(function () { beforeEach(function () {
@@ -67,7 +67,10 @@ define(
mockDomainObject.getCapability.and.callFake(function (capability) { mockDomainObject.getCapability.and.callFake(function (capability) {
return capabilities[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); mockDomainObject.getId.and.returnValue(0);
mockClonedObject = jasmine.createSpyObj( mockClonedObject = jasmine.createSpyObj(
@@ -168,8 +171,8 @@ define(
expect(SaveAsAction.appliesTo(actionContext)).toBe(false); expect(SaveAsAction.appliesTo(actionContext)).toBe(false);
}); });
it("only applies to domain object that has not already been" + it("only applies to domain object that has not already been"
" persisted", function () { + " persisted", function () {
expect(SaveAsAction.appliesTo(actionContext)).toBe(true); expect(SaveAsAction.appliesTo(actionContext)).toBe(true);
expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor"); expect(mockDomainObject.hasCapability).toHaveBeenCalledWith("editor");

View File

@@ -118,8 +118,8 @@ define(
expect(capability.isEditContextRoot()).toBe(true); expect(capability.isEditContextRoot()).toBe(true);
}); });
it("inEditingContext returns true if parent object is being" + it("inEditingContext returns true if parent object is being"
" edited", function () { + " edited", function () {
mockStatusCapability.get.and.returnValue(false); mockStatusCapability.get.and.returnValue(false);
mockParentStatus.get.and.returnValue(false); mockParentStatus.get.and.returnValue(false);
expect(capability.inEditContext()).toBe(false); expect(capability.inEditContext()).toBe(false);
@@ -179,8 +179,8 @@ define(
capability.edit(); capability.edit();
capability.finish(); capability.finish();
}); });
it("returns true if the object has been modified since it" + it("returns true if the object has been modified since it"
" was last persisted", function () { + " was last persisted", function () {
mockTransactionService.size.and.returnValue(0); mockTransactionService.size.and.returnValue(0);
expect(capability.dirty()).toBe(false); expect(capability.dirty()).toBe(false);
mockTransactionService.size.and.returnValue(1); mockTransactionService.size.and.returnValue(1);

View File

@@ -76,15 +76,15 @@ define(
); );
}); });
it("if no transaction is active, passes through to persistence" + it("if no transaction is active, passes through to persistence"
" provider", function () { + " provider", function () {
mockTransactionManager.isActive.and.returnValue(false); mockTransactionManager.isActive.and.returnValue(false);
capability.persist(); capability.persist();
expect(mockPersistence.persist).toHaveBeenCalled(); expect(mockPersistence.persist).toHaveBeenCalled();
}); });
it("if transaction is active, persist and cancel calls are" + it("if transaction is active, persist and cancel calls are"
" queued", function () { + " queued", function () {
mockTransactionManager.isActive.and.returnValue(true); mockTransactionManager.isActive.and.returnValue(true);
capability.persist(); capability.persist();
expect(mockTransactionManager.addToTransaction).toHaveBeenCalled(); expect(mockTransactionManager.addToTransaction).toHaveBeenCalled();

View File

@@ -40,6 +40,7 @@ define(
mockedSaveActions.forEach(function (action) { mockedSaveActions.forEach(function (action) {
action.getMetadata.and.returnValue(mockSaveActionMetadata); action.getMetadata.and.returnValue(mockSaveActionMetadata);
}); });
return mockedSaveActions; return mockedSaveActions;
} else if (actionContext.category === "conclude-editing") { } else if (actionContext.category === "conclude-editing") {
return ["a", "b", "c"]; return ["a", "b", "c"];

View File

@@ -54,7 +54,7 @@ define(
); );
mockCapabilities = { mockCapabilities = {
"editor" : mockEditorCapability, "editor": mockEditorCapability,
"status": mockStatusCapability "status": mockStatusCapability
}; };
@@ -77,7 +77,10 @@ define(
testViews = [ testViews = [
{ key: 'abc' }, { key: 'abc' },
{ key: 'def', someKey: 'some value' }, {
key: 'def',
someKey: 'some value'
},
{ key: 'xyz' } { key: 'xyz' }
]; ];

View File

@@ -48,10 +48,10 @@ define(
mockContext.getTrueRoot.and.callFake(function () { mockContext.getTrueRoot.and.callFake(function () {
var mockRoot = jasmine.createSpyObj('root', ['getId']); var mockRoot = jasmine.createSpyObj('root', ['getId']);
mockRoot.getId.and.returnValue('root-id'); mockRoot.getId.and.returnValue('root-id');
return mockRoot; return mockRoot;
}); });
controller = new EditPanesController(mockScope); controller = new EditPanesController(mockScope);
}); });
@@ -97,6 +97,7 @@ define(
mockContext.getTrueRoot.and.callFake(function () { mockContext.getTrueRoot.and.callFake(function () {
var mockRoot = jasmine.createSpyObj('root', ['getId']); var mockRoot = jasmine.createSpyObj('root', ['getId']);
mockRoot.getId.and.returnValue('other-root-id'); mockRoot.getId.and.returnValue('other-root-id');
return mockRoot; return mockRoot;
}); });

View File

@@ -51,6 +51,7 @@ define(
); );
mockType.hasFeature.and.returnValue(true); mockType.hasFeature.and.returnValue(true);
mockType.getName.and.returnValue(name); mockType.getName.and.returnValue(name);
return mockType; return mockType;
} }
@@ -75,7 +76,7 @@ define(
}; };
mockPolicyService.allow.and.callFake(function (category, type) { mockPolicyService.allow.and.callFake(function (category, type) {
return category === "creation" && mockCreationPolicy(type) ? true : false; return Boolean(category === "creation" && mockCreationPolicy(type));
}); });
mockTypeService.listTypes.and.returnValue(mockTypes); mockTypeService.listTypes.and.returnValue(mockTypes);

View File

@@ -77,7 +77,7 @@ define(
] ]
); );
mockDomainObject.hasCapability.and.callFake(function (name) { mockDomainObject.hasCapability.and.callFake(function (name) {
return !!capabilities[name]; return Boolean(capabilities[name]);
}); });
mockDomainObject.getCapability.and.callFake(function (name) { mockDomainObject.getCapability.and.callFake(function (name) {
return capabilities[name]; return capabilities[name];
@@ -150,8 +150,8 @@ define(
expect(mockEditAction.perform).toHaveBeenCalled(); expect(mockEditAction.perform).toHaveBeenCalled();
}); });
it("uses the save-as action if object does not have an edit action" + it("uses the save-as action if object does not have an edit action"
" available", function () { + " available", function () {
capabilities.action.getActions.and.returnValue([]); capabilities.action.getActions.and.returnValue([]);
capabilities.action.perform.and.returnValue(mockPromise(undefined)); capabilities.action.perform.and.returnValue(mockPromise(undefined));
capabilities.editor.save.and.returnValue(promise); capabilities.editor.save.and.returnValue(promise);

View File

@@ -45,6 +45,7 @@ define(
control: "textfield" control: "textfield"
}); });
mockProperty.getValue.and.returnValue(name); mockProperty.getValue.and.returnValue(name);
return mockProperty; return mockProperty;
} }
@@ -120,7 +121,10 @@ define(
// Should have gotten a setValue call // Should have gotten a setValue call
mockProperties.forEach(function (mockProperty, i) { mockProperties.forEach(function (mockProperty, i) {
expect(mockProperty.setValue).toHaveBeenCalledWith( expect(mockProperty.setValue).toHaveBeenCalledWith(
{ someKey: "some value", type: 'test' }, {
someKey: "some value",
type: 'test'
},
"field " + i "field " + i
); );
}); });
@@ -188,7 +192,6 @@ define(
})).toEqual(false); })).toEqual(false);
}); });
}); });
} }
); );

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