Compare commits

...

173 Commits

Author SHA1 Message Date
d635ea4cc9 Merge branch 'master' into root-object-name 2020-09-04 10:15:20 -07:00
6f2d8e6ce3 change time conductor bounds on zoom end (#3345) 2020-09-03 09:23:26 -07:00
b802870f30 modifying root name 2020-09-03 09:23:09 -07:00
91d1681698 [Navigation Tree] Prevent showing "no items" while still loading (#3341)
* no  showing "no items" if still loading

* added additional no items variable to handle dictionary composition loading race conditions

* code cleanup

* more descript variable name
2020-08-31 11:23:50 -07:00
efd97de743 [Conditionals] Ensure correct conditions are updated after reordering (#3336)
* Use id of condition instead of index to ensure
2020-08-28 11:54:52 -07:00
c4cd725c9a [Navigation] Properly handle overflow in conditional style selection tree (#3338) 2020-08-28 11:46:03 -07:00
23e5efbb19 Merge pull request #3243 from nasa/iso-date-format
Merging new ISODateFormatter
2020-08-28 11:13:09 -07:00
4e995c10da Merge branch 'master' into iso-date-format 2020-08-28 11:05:38 -07:00
b5cf157c40 cleaning up tests 2020-08-28 10:54:45 -07:00
ac082e9f58 removing openmct from tests as it is not required 2020-08-28 10:46:05 -07:00
9f7799b44f Couchdb object provider (#3245)
* Added legacy persistence service adapter
* Use new couch provider
* Added queuing of requests
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-08-27 15:21:06 -07:00
cdf9c50b8a Merge branch 'master' into iso-date-format 2020-08-26 11:12:29 -07:00
ffb3b302c7 [MCT Tree] Testathon Fixes (#3324)
* WIP: testing backwards compatibility checks

* added new localstorage key for expanded tree node, delete old one if detected

* removing obsolete backwords compatibility code

* fixed going up the tree items not showing, going down the tree "ghost" image showing

* removing console log

* removed duplicate functionality
2020-08-25 14:15:28 -07:00
278f48f65c backwards compatible fix and switching between multi to single root children fix (#3319) 2020-08-24 15:00:11 -07:00
4801dc4f32 New tree refactor (#3098)
* revised new tree refactor, moved most of the logic to mct-tree instead of tree-item

* scrollTo set for sync, bug fixes, window resize handling

* removing console logs

* checking domainobject composition for length to verify children instead of composition object itself

* added scrollTo on load if in viewed objects directory

* loading, sync bug, search issues, opitmization

* initial PR review updates

* modified so search now uses the same container and virtual scroll

* eslint fix

* Adding new glyphs

- Multiple new glyphs cherrypicked from branch `add-new-glyphs-062320`;

* Styling for new-tree-refactor WIP

- WIP!
- New glyphs, markup changes in BrowseBar.vue;
- Refinements to tree items, WIP;
- TODO: move hard-coded CSS values into _constants, make
theme-compatible;

* Styling for new-tree-refactor WIP

- WIP!
- Added new `c-click-link` CSS class;
- Move tree sync button into tree pane area;
- Added named "controls" slot to pane.vue;
- _up and _down arrows now use visibility instead of opacity to prevent
accidental clicks;

* Styling for new-tree-refactor WIP

- WIP!
- Significant mods and simplification in pane.vue and assoc CSS for
expand/collapse functionality;
- Wait spinner when in tree: cleanups, simplification;

* More new glyphs, updated art

- New glyphs: icon-unlocked and icon-target;
- Updated art for icon-lock glyph;

* remove arrows for search results, hightlight "my items" correctly, added empty folder notic

* Styling for new-tree-refactor WIP

- WIP!
- Refinements to "empty" object element;
- Changed sync-tree icon glyph;

* Styling for new-tree-refactor WIP

- Nav up arrows now left-align properly;

* Styling for new-tree-refactor

- Significant consolidation and cleanups in mct-tree.scss;
- Normalize base and hover styles across new tree, legacy tree,
list-items (used in Notebook) and Folder List View;
- Class naming normalization, change `c-list-item__name-value` to
`c-list-item__name`;
- Add styling to override and remove `<a> outline: dotted` coming from
normalize-min;
- Removed too-broad `<a>` coloring in tables;

* Styling for new-tree-refactor

- Fix styles for Snow theme;
- Sync Maelstrom and Espresso themes;
- Remove too-broad `<a>` hover styling from global.scss;
- Disallow pointer-events on `is-navigated` object's label (click on
c-nav__down element still allowed);

* Styling for new-tree-refactor

- Normalizing status area expand/collapse iconography to match new
approach in panes;

* Adding new glyphs

- Added `icon-items-collapse` and `icon-items-expand`;

* Styling for new-tree-refactor

- Using new glyphs for items expand/collapse in Status area;

* dynamic item height for desktop and mobile views

* lint fixes

* updated addChild and removeChild functions as they were not working at all

* some PR comment updates!;

* Remove unneeded hard-coded CSS color property

* fixed issues when multiple root children exist, added plugin to change the name of the default root object

* removing "my other items" testing references

* linting fixes

* updating karma timeouts for testing purposes

* eslint fixes

* WIP: fixing linting issues

* updating for testing

* set root object provider to update root registry if called more than once

* tweaking tests so that it passes both locally and on the serve tests

* removing old css code preventing context clicks on active menu items

* fixing testing errors

* backwards compatible storage fix

Co-authored-by: charlesh88 <charlesh88@gmail.com>
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-08-24 13:47:56 -07:00
9e8f845fbe Fix plot axis separator line color and hash colors (#3314)
* Fixes for NIRVSS UI spectral plot view

- Fixes Y axis 2 vertical line color in spectral plot;

* Fixes for NIRVSS UI spectral plot view

- Fixes Y axis 2 vertical line color in spectral plot;
- Tweaks to themed plot hash line colors;
2020-08-21 15:22:26 -07:00
b4d1cdaae8 Fixes for NIRVSS UI spectral plot view (#3310)
- Fixed Plotly axis label title font sizing;
- Fixed Plotly axis vertical line color;
- Removed styling that caused `c-button` within
`h-local-controls--overlay-content` to be background on background
color;
2020-08-20 12:27:25 -07:00
f9d3af2724 Version 1.3.0 snapshot (#3307)
* Updating version to 1.2.4 for end of sprint.

* Update master to 1.3.0-SNAPSHOT sprint version
2020-08-18 12:19:49 -07:00
37debefadc Stop evaluation of conditions when one evaluates to true (#3276)
* Stop evaluation of conditions when one evaluates to true

* Fix broken test

* Fixes broken tests

* Addresses review comments - Rename getResult to updateResult

* Rename condition getResult to updateResult

* Renames condition getResult to updateResult
2020-08-14 10:09:35 -07:00
891fe0a36b Merge pull request #3154 from nasa/remove-action-tests
Remove action tests
2020-08-13 13:31:08 -07:00
4b6de59b03 Merge branch 'master' into remove-action-tests 2020-08-13 09:52:35 -07:00
6a5b902365 copyright stuff 2020-08-11 13:51:08 -07:00
270f07ebd5 Compare the enum value to the input, not the index of the enumeration (#3277) 2020-08-11 13:19:38 -07:00
52500f6097 lint fixes 2020-08-11 13:11:08 -07:00
2fa8a8d61d Merge branch 'master' into iso-date-format
Merg'n master
2020-08-11 13:07:10 -07:00
69a6cd20af linting 2020-08-11 13:01:54 -07:00
28eb268af1 Merge branch 'remove-action-tests' of https://github.com/nasa/openmct into remove-action-tests
More merg'n
2020-08-11 12:57:26 -07:00
045bb443cb Merge branch 'master' into remove-action-tests
Merg'n master
2020-08-11 12:57:02 -07:00
c6ca912f2b ESLint one-var, no-var rules (#3239)
* fixed issues for eslint one-var and no-var rules

Co-authored-by: Joshi <simplyrender@gmail.com>
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-08-10 12:13:23 -07:00
78c7484d54 Merge branch 'master' into remove-action-tests 2020-08-10 11:57:06 -07:00
4d560086dd ESLint upgrade, implement additional rules (#3230)
* upgrade to ESLintv7, added overrides for rules violated
* removed overrides for spec files
* fixed no-prototype-builtins issues
* added rules for default-case-last, default-param-last, grouped-accessor-pairs, no-constructor-return, and added override for one violation

Co-authored-by: Andrew Henry <akhenry@gmail.com>
Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
2020-08-10 11:23:35 -07:00
ef965ebdfd ESLint rules: array-callback-return, no-invalid-this, func-style (#3151)
* satisfied array-callback-return rule
* satisfying no-invalid-this rule
* fixed invalid-this issues
* changed isNotEqual to arrow function
* added rule func-style
* added return false to satisfy array-callback-return rule

Co-authored-by: Joel McKinnon <jmckinnon@apple.com>
Co-authored-by: Joshi <simplyrender@gmail.com>
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-08-10 10:59:18 -07:00
0b4a843617 ESLint rules: rules requiring minor changes (#3139)
* implemented trivial code changes necessary batch of rules

Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-08-10 10:35:40 -07:00
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
b3fd6c9b85 Merge branch 'master' into iso-date-format 2020-08-03 14:34:38 -07:00
deb0511b43 Merge branch 'master' into remove-action-tests 2020-08-03 13:43:40 -07:00
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
abc458cef4 [Time conductor] Better persistence handling for history (#3246) 2020-08-03 11:56:29 -07:00
2198a4780b Merge branch 'master' of https://github.com/nasa/openmct into remove-action-tests 2020-08-03 09:47:42 -07:00
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
9ebb013f22 Merge branch 'master' into remove-action-tests 2020-07-31 14:30:14 -07:00
5a4cba0226 Merge branch 'master' into telemetry-table-config-updates 2020-07-31 14:23:12 -07:00
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
7c1550ced7 Merge branch 'master' into remove-action-tests 2020-07-31 12:46:40 -07:00
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
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
fd3be63805 classic eslint fix 2020-07-28 13:58:31 -07:00
ad8ed419de removing old references in legacy code (accident) and adding tests for new formatter 2020-07-28 13:45:45 -07:00
8b4f07c2e0 added ISOTimeFormat plugin and format 2020-07-28 11:23:56 -07:00
e667b22b3c remove modified and persisted keys from duplicates (#3241) 2020-07-28 11:05:55 -07:00
9198effafe adding ISO Time Formatter to be used with openmct-yamcs 2020-07-27 10:32:22 -07:00
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
de6eceb98b parsing datum itself rather than specific key of datum, let telemetry api do the work 2020-07-24 11:37:41 -07:00
13ff0c368d Merge branch 'master' into telemetry-table-config-updates 2020-07-24 10:46:02 -07:00
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
b7d2402434 Update TelemetryTable config to allow disable multiselect. 2020-07-23 14:11:44 -07:00
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
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
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
a5c4508578 add minified vue to production (#3183)
Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
2020-07-22 14:47:46 -07:00
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
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
41138a1731 Merge pull request #3205 from nasa/data-dropout-fixes
### Reviewer Checklist

1. Changes appear to address issue? Y
2. Appropriate unit tests included? Y
3. Code style and in-line documentation are appropriate? Y
4. Commit messages meet standards? Y
5. Has associated issue been labelled `unverified`? (only applicable if this PR closes the issue) Y
2020-07-21 10:08:31 -07:00
a54a2f8f84 Merge branch 'master' into data-dropout-fixes 2020-07-21 10:01:01 -07:00
5bbe710552 Merge pull request #3215 from nasa/circle-ci-chromeheadless-test-failure
Removing use of ChromeHeadless and using FirefoxHeadless for Circle CI builds
2020-07-21 09:53:40 -07:00
f2d34d7c33 For the short term, removing use of ChromeHeadless and using FirefoxHeadless instead. (added npm dependency)
Also increasing browserNoActivityTimeout to 90000

Resolves #3214
2020-07-20 15:12:53 -07:00
8fa1770885 Merge branch 'master' into data-dropout-fixes 2020-07-20 15:01:11 -07:00
7221dc1ac6 make clear data indicator a configurable option (#3206) 2020-07-17 16:48:14 -07:00
25bb9939d6 Merge pull request #3193 from nasa/fix-safari-3192
Fix Safari display issues for #3192
2020-07-17 15:59:38 -07:00
e7e12504f2 Merge branch 'master' into fix-safari-3192 2020-07-17 15:19:32 -07:00
63bf856d89 Enable persistence operations from Object Providers (#3200)
* Implement 'save' method in Object API

* Refactor legacy persistence code to work with new save object API

* Added 'isPersistable' check to object API

* Fixed incompatibility between object API changes and composition policies

* Make save method private

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-07-17 09:58:03 -07:00
e3dcd51f8d Disallow editor Edit mode when object is locked (#3208)
* Don't allow editor edit if object is locked

* Adds log statement

* Use capture phase for onDragOver

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-07-17 09:23:51 -07:00
cb63f4eca1 Fix is-missing layout problem #3194 (#3195)
- Fixes related to `is-missing` including fixes for Display Layout
alphanumeric views and Tabs view tabs;
2020-07-16 12:43:37 -07:00
3f60c3c0f1 Merge branch 'master' into data-dropout-fixes 2020-07-16 11:55:02 -07:00
16bb22e834 Added regression test 2020-07-16 11:50:03 -07:00
b1467548da Fix Safari display issues #3192
- Tweaks to fix `c-tab` elements, fix clip-path for webkit;
- Fix Notebook Snapshots header;
2020-07-14 23:40:42 -07:00
baa7c0bc58 Fix Safari display issues #3192
- Tweak to Status area indicator hover bubbles;
2020-07-14 21:51:22 -07:00
73b81e38e7 Fix Safari display issues #3192
- Fix collapsed Status area indicators width problem;
2020-07-14 19:22:18 -07:00
8b088b7a2c Fix Safari display issues #3192
- Fix Status area indicators width problem;
- Also fixes collapsing-status-area-indicator-bubbles transition problem
 as well!;
2020-07-14 18:53:30 -07:00
894da25461 Fix Safari display issues #3192
- Fix Inspector `__content` to properly use flex column layout;
- Change `u-angular-object-view-wrapper` to `display: contents`;
- Fix `gl-plot` to properly use `flex: 1 1 auto` instead of width and
height;
2020-07-14 18:42:52 -07:00
79c4dc9272 typo fix! and using object assign where appropriate 2020-07-13 14:42:01 -07:00
87d63806b9 [Plots] Better Pan/Marquee handling (#3165)
* check for alt key pressed on mouse events

* allows for release of alt key during drag

* eliminates non-browser event states like alt-tab switching apps in windows

* do not listen to plot mouse events on browser context (ctrl) click

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-07-13 12:39:37 -07:00
f0e7f8cfc0 Fix incorrect property inspection (#3180)
- Fixed Folder grid and list views;
- Fixed plot collapsed and expanded legends;

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-07-13 11:36:21 -07:00
db597e1e93 [Tabs View] Fix tab not being added (#3160) 2020-07-13 10:24:22 -07:00
98db273f5d Remove unsubscribe callback 2020-07-10 15:10:33 -07:00
8a6f944655 Missing items (#3125)
* Missing objects styling WIP

- Grabbing prior work from `missing-items` branch;

* Missing objects styling WIP

- Grabbing prior work on hover and missing theme constants from
`missing-items` branch;
- Refined theme constants values;
- Renamed relevant mixins and classes from "isUnknown" to "isMissing";
- Applied new hover and missing/unknown styling to Folder-view grid
items;

* Missing objects styling WIP

- Significant refinements and additions to `is-missing`;
- Normalize object type icons as a markup `*__type-icon` to support
styling and positioning of `is-missing__indicator` as a markup element;
- Application to tree items, l-browse-bar in main view, c-object-label,
grid view;
- Change hover approach in grid-items and tree to use filters;

* Missing objects styling WIP

- Styles added to object-name component in Inspector, markup simplified;
- Styles added to Tabs view;

* Missing objects styling WIP

- Simplified and consolidated `is-missing` approach into
`.c-object-label` class;
- Modded `.c-object-label` class to use flex 1 1 auto, instead of 0 1
auto - be on the outlook for regression problems!;
- TODO: wire up `is-missing` for real and Folder List view;

* Missing objects styling WIP

- Added `is-missing` styling to Folder list view;
- Cleanups, simplification and normalization with tree items in
list-item and list-view.scss;
- Using `c-object-label` now in Folder list view;
- Removed too-broad `<a>` color definition in table.scss;

* Missing objects styling WIP

- `is-missing` added to layout frames, with support for hidden
frames and telemetry views.
- Further styles enhancement;
- Continued added wiring points into markup;

* Missing objects styling WIP

- `is-missing` added to mct-plot;
- Significant improvements for cursor lock indicators in plots;

* Missing objects styling WIP

- Plot legend fixes, added overflow scrolling for collapsed and expanded
 legends;
- Removed conmmented code;

* Wire up 'is-missing'

- Added property checks on domainObject for status 'missing';

* Fix linting issues

* remove carat from eslint package

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-07-10 15:08:14 -07:00
bacad24811 Delete telemetry cache only when count reaches 0 2020-07-10 13:27:30 -07:00
8cc58946cf Remove Karma Report that was accidentally checked in (#3097)
* remove karma report

* add report.*.json to gitignore

Co-authored-by: Andrew Henry <akhenry@gmail.com>
Co-authored-by: Nikhil <nikhil.k.mandlik@nasa.gov>
2020-07-10 12:47:52 -07:00
3338bc1000 upgrade painterro to +1.00.35 (#3172) 2020-07-09 13:41:52 -07:00
80c20b3d05 [Plots] Allow user to change marker style (#3135)
* lineWidth is not supported in modern browsers

* allow marker shape selection in plot inspector

add shapes for canvas2d - point, cross, star

* change line style to line method in anticipation of adding true line style attribute

* add canvas2d circle marker shape

* allow point shapes for webGL plots

add circle shape

* refactor for clarity

* refactor shape to shape code

* add missing semi-colon

* helper function for marker options display in inspector

refactor for clarity

* access correct file

* add diamond marker shape

* add triangle shape to canvas

* add webgl draw triangle marker shape

* refactor fragment shader for clarity
2020-07-09 13:14:32 -07:00
0d9558b891 Merge pull request #3162 from nasa/display-layout-fix-3161
Fixes issue created when removing Lodash function
2020-07-07 16:54:54 -07:00
c29c3c386f fix issue created by lodash upgrade 2020-07-07 15:39:21 -07:00
e1d0c22071 removing fdescribe 2020-07-06 15:27:38 -07:00
7dee6344b0 updating spec statements to be more broad 2020-07-06 14:14:57 -07:00
731ab89561 added some tests for remove action as well as another mock object "folder" 2020-07-06 14:05:32 -07:00
9ceb3c5b1e Merge pull request #3130 from nasa/display-layout-fix-3128
[Display Layouts] Prevent duplicate from being added when composition 'add' is fired
2020-07-06 11:36:25 -07:00
6bd0246db6 Merge branch 'master' into remove-action-tests
Merging master
2020-07-02 12:53:43 -07:00
bee3a9eedf Merge branch 'master' into display-layout-fix-3128 2020-07-02 10:48:53 -07:00
e515d19acd Merge pull request #3144 from nasa/switching-type-error
Fix for non working switch from alpha to tables and plots
2020-07-02 10:38:01 -07:00
dd13efe065 Merge branch 'master' into switching-type-error 2020-07-02 10:26:13 -07:00
99aa5c7b7b few more tests, not ready yet though 2020-07-02 10:14:14 -07:00
b5dfbe268c Merge pull request #3146 from nasa/new-folder-action-fix-07012020
Added unnamed folder and made it required
2020-07-01 16:48:10 -07:00
a9b9107cc3 change icon and action name 2020-07-01 16:30:03 -07:00
cfda4e4214 added unnamed folder and required 2020-07-01 16:20:33 -07:00
0a657de4b2 Fix for non working switch from alpha to tables 2020-07-01 16:09:05 -07:00
8153edb9cb Update any/all criterion when telemetry is removed (#3138)
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-07-01 12:22:47 -07:00
22ca339fb9 [LADTable] Lad bounds listener FIX (#3114)
* added bounds listener, moved history request to function, checking for race conditions

Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-07-01 09:50:18 -07:00
7f8764560b Add new glyphs 062320 (#3140)
* Adding new glyphs for multiple branches

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-06-30 16:19:45 -07:00
4411bb0a2d UI fixes for NIRVSS #170 (#3141)
* UI fixes for NIRVSS client #170
2020-06-30 16:12:28 -07:00
4ecd264d93 [Time Conductor] add history and select range features (#2932)
* basic brush prototype visible

* require alt pressed for grab handle. display only

* pan and zoom now co-exist

* revert selection to times

* make LocalTimeSystem UTCBased (Earth based)

* add LocalTimeSystem

* make isTimeFixed check reusable

* linting

* zoom axis sets start and end times

* pass isFixed as props so we can watch for change from parent

* disable cursor for local time and enable for fixed time

* linting

* resize brush on window resize

* just use d3-brush instead of entire d3 package

* WIP prototyping conductor history

* set global bounds before emitting change event

* WIP conductor history

* WIP save history to and pull history from local storage

* WIP persistence works

* reset axis height after prototyping

* conductor history functionality complete

* clean up refactoring

* add presets

code cleanup

* axis visual tuning

* remove unused function calls

* change tick to timespan to avoid confusion

* fix bounds to use for timespans on pan axis

* linting

* linting

* more linting

* linting

* change realtime end bound to 30 secondes

* add max duration validation

* Tweaks to Time Conductor History menu

- Enhanced styles for `.c-menu`;
- Added hint messaging and separator;
- Reversed displayed history array so that latest entry is always first;

* refactor to use browser mouse events instead of d3brush

* Styling Time Conductor axis area

- Styles for `is-zooming` state and brush;
- Styles for `is-alt-key-down` for panning;
- Styles for hover modified;

* resolve merge conflicts

* Styling Time Conductor axis and inputs

- Moved panning and zooming styles up into `conductor.scss`;
- Stubbed in :class names in Conductor.vue;
- New theme constants;

* fix merge conflict

* move zoom/pan styling up to conductor

* WIP almost there

* fix zoom

* move altPressed up to parent

* handle no drag on pan

* rename inMode vars for clarity

* Styling for Time Conductor zoom and pan

- Minor fix to hover cursor for alt-pressed panning;

* add configurable bounds limit to time conductor

* add presets and records

* fixes for history

* remove lodash

* add default configurables for examples

* do not install local time system

* cleanup

* fix indentation

remove logging

* remove comments

* section-hint without section-separator styling

* provide reasonable defaults for conductor configuration

* specify input to check validation on

* improve validation

* first check both inputs for valid formats

* clear each valid input on new entry

* tear down listeners

* add user instructions

* allow preset bounds to be declared as callback function

* set this.left on resize

code refactoring

Co-authored-by: charlesh88 <charlesh88@gmail.com>
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-30 12:10:35 -07:00
16677c99c9 Add staleness evaluation to conditions. (#3110)
* Add staleness evaluation to conditions.
Add supporting tests
Resolves #3109

* Fix broken test

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-29 14:13:44 -07:00
6ab468086a Lock views and prevent editing (#3094)
* working lock and unlock

* prevent flexible layout drop hints from showing

* fix lint issue

* wip

* disable mousedown when not editing in DisplayLayout

* continued wip

* Cherrypick new glyphs from add-new-glyphs-062320

* More new glyphs, updated art

- New glyphs: icon-unlocked and icon-target;
- Updated art for icon-lock glyph;

* Edit toggle refinements WIP

- Markup, CSS in BrowseBar.vue;

* More new glyphs, updated art

- New glyphs: icon-unlocked and icon-target;
- Updated art for icon-lock glyph;

* Edit toggle refinements

- Replaced toggle switch with button;

* prevent styling changes when locked

* fix lint issues

* fix tests

* make reviewer suggested changes

Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-06-29 13:14:42 -07:00
9d2991ee10 [Snapshots] Add download as PNG and JPG buttons (#3123)
* working export

* fix lint errors
2020-06-26 17:34:36 -07:00
dadb6120c2 fix lint error 2020-06-26 14:00:39 -07:00
d9a94db59d prevent composition from adding a dupe into layout 2020-06-26 13:51:03 -07:00
6dd8d448df Merge pull request #3116 from nasa/new-folder-action
New folder action
2020-06-25 13:27:28 -07:00
ef2db1edaf Merge branch 'master' into new-folder-action 2020-06-25 13:13:06 -07:00
3748927e87 Display layout fixes 062320 (#3111)
* fix for persisting new domainObject

* convert stacked plot to alpha
2020-06-25 11:03:31 -07:00
7e4aac028b Merge branch 'master' into new-folder-action 2020-06-25 10:08:26 -07:00
8e54b8a819 LAD Table (Set) Composition Policy (#2962)
* added LAD Table composition policy, with a check for lad table sets, child can only be lad table
Co-authored-by: Andrew Henry <akhenry@gmail.com>
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-24 13:26:22 -07:00
9e5eddec9b [Plots] y-axis width fix (#3112)
* remove lodash

native implementation of lodash max

* remove unused lodash imports

* add 'missing' semi-colon

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-24 11:44:40 -07:00
c46e4c5dad Merge branch 'master' into new-folder-action 2020-06-24 09:51:39 -07:00
f0dc928230 Imagery Bug Fixes (Future Date Issues) (#3107)
[Example Imagery] Console error on pause when start and end date is in future #3103

* added some checks for no image

* some code style updates and removing a nested if statement

Co-authored-by: Nikhil <nikhil.k.mandlik@nasa.gov>
2020-06-24 09:47:04 -07:00
6f674930d9 remove fdescribe 2020-06-23 18:34:19 -07:00
8675fc3fa6 add a few more tests 2020-06-23 18:33:51 -07:00
25434342f3 remove unused imports 2020-06-23 16:20:44 -07:00
8044dfe726 fix tests 2020-06-23 16:20:28 -07:00
cd6c7fdc5e fix broken tests 2020-06-23 15:54:10 -07:00
7ff85dc396 remove report 2020-06-23 15:30:37 -07:00
fb4877924a remove fdescribe 2020-06-23 15:23:00 -07:00
4b13cbdb33 add test 2020-06-23 15:22:43 -07:00
51c9328dfd working new folder action 2020-06-23 14:39:19 -07:00
31ac67b393 Do not respond to bounds tick changes (#3106)
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-23 13:14:17 -07:00
0399766ccd Merge pull request #3074 from nasa/testing-guidelines
Added guidelines to testing documentation
2020-06-23 10:53:39 -07:00
18ab034147 Merge branch 'master' into testing-guidelines 2020-06-23 10:40:58 -07:00
8a4bc2a463 bumped angular to >=1.8.0 (#3100) 2020-06-22 14:56:06 -07:00
771fb9c044 [Display Layout] Allow multiple selection, duplication, and changing types (#3083)
* enable multiple selection

* enable object duplication

* enable copy styles

* enable converting plots and tables to alpha numerics

* enable merging multiple alpha numerics

* change icon for viewSwitcher

* allow users to merge overlay plots into a stacked plot

* New glyph for alphanumeric

Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-06-19 11:44:17 -07:00
055cf2b118 Lad testing (#3045)
* Added tests for LAD Tables and LAD Table Sets

Co-authored-by: Andrew Henry <akhenry@gmail.com>
Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
2020-06-17 17:25:34 -07:00
e9cf337aac Merge branch 'master' into testing-guidelines 2020-06-17 15:38:56 -07:00
04a18248c7 Added reference to Angular memory leak best practices 2020-06-17 15:38:17 -07:00
d462db60de Add note on convenience function for test cleanup 2020-06-17 15:31:35 -07:00
67ebcf4749 Update testing plan document with description of testathon process (#3022)
* Update testing plan document with description of testathon process
* Add instructions on unverified issues + link to instructions on pull requests.

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
2020-06-17 15:05:02 -07:00
38dbf2ccab Addresses review comments for conditionals code (#2978)
Conditionals code refactoring

Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-06-17 14:56:36 -07:00
e9968e3649 Replace Angular code that synchronizes URL parameters with Time API (#3089)
* Added new test to telemetry tables to check that telemetry data is correctly rendered in rows

* Added test tools for mocking builtins

* Changed order that promises are resolved to address race condition

* Remove duplicate installation of UTC Time System

* Added additional test telemetry

* Start Open MCT headless

* Added headless mode start option. Fixes #3064

* Added new non-angular URL handler

* Removed legacy Angular TimeSettingsURLHandler

* Added function to testTools to reset application state

* Use resetApplicationState function from telemetry table spec

* Added new TimeSettingsURLHandler to plugins

* Added missing semicolons

* #2826 Refactored code into separate class

* Handling of hash-relative URLs

* Refactoring URL sync code

* Refactored to external class

* Moved utils to new 'utils' directory. Refactored location util functions from class to exported functions

* Added test specs for openmctLocation

* Added new function to destroy instances of Open MCT between test runs

* Ensure test specs are cleaning up after themselves

* Added test spec for new URLTimeSettingsSynchronizer

* Removed use of shell script as it doesn't work in windows

* Pushed test coverage to 100%

* Added missing copyright statement

* Removed debugging output

* Fixed linting error

* Upgrade node version

* Clear cache

* Re-enabled tests

Co-authored-by: Melanie Lean <melanielean@Melanies-MacBook-Pro.local>
Co-authored-by: Shefali Joshi <simplyrender@gmail.com>
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-17 13:58:25 -07:00
d9fafd2956 Tweaked code standards for ternaries and return statements (#3082)
* Tweaked code standards for ternaries and return statements

* Tweaked language slightly

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-17 10:52:30 -07:00
b5aba7ce8f Merge pull request #3096 from nasa/revert-3095-patch-1
Revert "Update API.md"
2020-06-12 10:12:56 -07:00
0db5648e10 Revert "Update API.md" 2020-06-12 10:07:49 -07:00
83325da738 Merge pull request #3095 from willmendil/patch-1
Update API.md
2020-06-12 08:50:23 -07:00
4d1b2f3456 Update API.md
typo
2020-06-12 17:42:39 +02:00
6137700c82 Merge pull request #3092 from nasa/contributor-guide-grammar
Fixes a grammatical issue in the wording of the contributor's guide
2020-06-10 11:06:59 -07:00
91a1b3f31d Fixes a grammatical issue in the wording of the contributor's guide 2020-06-10 10:29:47 -07:00
357b25a76b LAD views should respond to conductor bounds changes (#2946)
Added bounds listener, moved history request to function, checking for race conditions
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-06-09 16:51:32 -07:00
bab53ad9bd Fix static styles bug - adding null checks. (#3084)
* Fix static styles bug - adding null checks. Fixes #3076

* Adds tests for updating conditional and static styles for layout drawing items

Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-05 15:30:35 -07:00
d0d4579f13 Give users the option to hide table headers (#3085)
* working hide header config

* Simplified Inspector UI layout

* fix lint errors

Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-06-05 15:09:59 -07:00
02b537580c Merge pull request #3057 from nasa/code-standards-update
Updated code standard
2020-06-02 13:31:21 -07:00
7073b0717f Merge branch 'master' into code-standards-update 2020-06-02 13:05:32 -07:00
d6bb1b2a12 Added note about requiring a single return statement. 2020-06-02 13:05:15 -07:00
c256696790 Image view should react to time conductor changes - 2712 (#2934)
Image view reacts to time conductor changes
Fixes #2712
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-06-02 12:27:55 -07:00
d5480e7524 Multiple item conditional styles (#3017)
Conditional Styles for multiple items #3076

* Preview condition styles on selecting that condition or one of it's styles
Do not evaluate conditional styles in edit mode

* Conditions styling tweaked

- Condition match `is-current` styling for browse and edit modes;
- Disallowed pointer events on Conditions to prevent selection in
Inspector when not editing;

* Highlight current condition in conditionSet view

* Addresses review comments.

* Condition matching highlighting tweaked

- Enable match highlighting during Editing;
- Tweaks to `is-current` styling;

* Don't reset the callback on destroy

* Combine multiple and single selection styling of objects

* Fix issue with applying styles in edit mode

* Fix item styles bug

* Remove comment

* Adds back visibility toggle

* Set isEditing on initialization.

* Addresses review comments - removes use of lodash.

Co-authored-by: charlesh88 <charlesh88@gmail.com>
Co-authored-by: Deep Tailor <deep.j.tailor@nasa.gov>
2020-06-01 12:40:40 -07:00
ab463e93fe Refactor Notifications to use Vue, and add clear all option (#3068)
[Notifications] Need a clear all notifications option #3006

* create new notifications indicator in vue, and sunset old one

* add notifications list overlay

* working notifications

* add support for progress notifications

* update percentage on mounted

* Markup cleanups in new Vue Notifications files

- Removed unneeded markup and class wrappers;
- Removed unneeded inline styling;

* remove example notifications

* fix lint errors

* make reviewer requested changes, remove old not needed files, add test

* update testTools to testUtils

Co-authored-by: charlesh88 <charlesh88@gmail.com>
2020-06-01 11:45:33 -07:00
8962b0c88b Merge branch 'master' into testing-guidelines 2020-05-28 15:48:12 -07:00
8363c65312 [Notebook] display bounds change notification only if bounds changed (#3062) Resolves (#3051)
* display bounds change notification only if bounds changed

* avoid empty notification messages.
2020-05-28 12:29:32 -07:00
04598b6cf1 Bug fixes for plots (#3019) (#3069)
* prevent plots from breaking when more than one NaN is received.

* fix y axis label issue

* dont emit a viewport change event when marquee doesnt happen
2020-05-28 09:58:22 -07:00
3876151a4b Added guidelines to testing documentation
Migrating our testing guidelines into the open source repository in the interests of transparency, and to assist contributors to the project.
2020-05-27 13:57:46 -07:00
43628ad9d6 Lodash upgrade and cleanup (#2990)
* Upgrades lodash
* Replaces some usage of lodash with native functions.
* Adds linting to catch cases where native functions could be used instead of lodash functions
* Renamed testTools to testUtils

Co-authored-by: Joshi <simplyrender@gmail.com>
Co-authored-by: David Tsay <david.e.tsay@nasa.gov>
Co-authored-by: David Tsay <3614296+davetsay@users.noreply.github.com>
Co-authored-by: Andrew Henry <akhenry@gmail.com>
2020-05-27 10:59:02 -07:00
67bea86bc8 Added headless mode start option (#3065)
* Added headless mode start option. Fixes #3064
2020-05-26 11:39:55 -07:00
2fa29124bf Merge branch 'master' into code-standards-update 2020-05-18 11:45:27 -07:00
33faeafa98 New proposed ESLint rules that require no code changes 2020-05-16 16:19:36 -07:00
a40ff07353 Updated guidance on anonymous functions 2020-05-16 16:11:42 -07:00
41dc9c794d Fixed capitalization on CONST 2020-05-16 16:08:43 -07:00
f1faf3965d Changed reference to constructors to classes 2020-05-16 16:07:49 -07:00
da2ecbbcad Fixed formatting issues, removed outdated example code. 2020-05-16 16:06:59 -07:00
32c892fe98 Updated code standards 2020-05-16 15:56:30 -07:00
900 changed files with 17091 additions and 6852 deletions

View File

@ -2,7 +2,7 @@ version: 2
jobs: jobs:
build: build:
docker: docker:
- image: circleci/node:8-browsers - image: circleci/node:13-browsers
environment: environment:
CHROME_BIN: "/usr/bin/google-chrome" CHROME_BIN: "/usr/bin/google-chrome"
steps: steps:

View File

@ -1,3 +1,4 @@
const LEGACY_FILES = ["platform/**", "example/**"];
module.exports = { module.exports = {
"env": { "env": {
"browser": true, "browser": true,
@ -10,7 +11,8 @@ module.exports = {
}, },
"extends": [ "extends": [
"eslint:recommended", "eslint:recommended",
"plugin:vue/recommended" "plugin:vue/recommended",
"plugin:you-dont-need-lodash-underscore/compatible"
], ],
"parser": "vue-eslint-parser", "parser": "vue-eslint-parser",
"parserOptions": { "parserOptions": {
@ -22,6 +24,9 @@ module.exports = {
} }
}, },
"rules": { "rules": {
"you-dont-need-lodash-underscore/omit": "off",
"you-dont-need-lodash-underscore/throttle": "off",
"you-dont-need-lodash-underscore/flatten": "off",
"no-bitwise": "error", "no-bitwise": "error",
"curly": "error", "curly": "error",
"eqeqeq": "error", "eqeqeq": "error",
@ -66,6 +71,141 @@ module.exports = {
], ],
"dot-notation": "error", "dot-notation": "error",
"indent": ["error", 4], "indent": ["error", 4],
// https://eslint.org/docs/rules/no-case-declarations
"no-case-declarations": "error",
// https://eslint.org/docs/rules/max-classes-per-file
"max-classes-per-file": ["error", 1],
// https://eslint.org/docs/rules/no-eq-null
"no-eq-null": "error",
// https://eslint.org/docs/rules/no-eval
"no-eval": "error",
// https://eslint.org/docs/rules/no-floating-decimal
"no-floating-decimal": "error",
// https://eslint.org/docs/rules/no-implicit-globals
"no-implicit-globals": "error",
// https://eslint.org/docs/rules/no-implied-eval
"no-implied-eval": "error",
// https://eslint.org/docs/rules/no-lone-blocks
"no-lone-blocks": "error",
// https://eslint.org/docs/rules/no-loop-func
"no-loop-func": "error",
// https://eslint.org/docs/rules/no-new-func
"no-new-func": "error",
// https://eslint.org/docs/rules/no-new-wrappers
"no-new-wrappers": "error",
// https://eslint.org/docs/rules/no-octal-escape
"no-octal-escape": "error",
// https://eslint.org/docs/rules/no-proto
"no-proto": "error",
// https://eslint.org/docs/rules/no-return-await
"no-return-await": "error",
// https://eslint.org/docs/rules/no-script-url
"no-script-url": "error",
// https://eslint.org/docs/rules/no-self-compare
"no-self-compare": "error",
// https://eslint.org/docs/rules/no-sequences
"no-sequences": "error",
// https://eslint.org/docs/rules/no-unmodified-loop-condition
"no-unmodified-loop-condition": "error",
// https://eslint.org/docs/rules/no-useless-call
"no-useless-call": "error",
// https://eslint.org/docs/rules/wrap-iife
"wrap-iife": "error",
// https://eslint.org/docs/rules/no-nested-ternary
"no-nested-ternary": "error",
// https://eslint.org/docs/rules/switch-colon-spacing
"switch-colon-spacing": "error",
// https://eslint.org/docs/rules/no-useless-computed-key
"no-useless-computed-key": "error",
// https://eslint.org/docs/rules/rest-spread-spacing
"rest-spread-spacing": ["error"],
// https://eslint.org/docs/rules/no-var
"no-var": "error",
// https://eslint.org/docs/rules/one-var
"one-var": ["error", "never"],
// https://eslint.org/docs/rules/default-case-last
"default-case-last": "error",
// https://eslint.org/docs/rules/default-param-last
"default-param-last": "error",
// https://eslint.org/docs/rules/grouped-accessor-pairs
"grouped-accessor-pairs": "error",
// https://eslint.org/docs/rules/no-constructor-return
"no-constructor-return": "error",
// https://eslint.org/docs/rules/array-callback-return
"array-callback-return": "error",
// https://eslint.org/docs/rules/no-invalid-this
"no-invalid-this": "error", // Believe this one actually surfaces some bugs
// https://eslint.org/docs/rules/func-style
"func-style": ["error", "declaration"],
// https://eslint.org/docs/rules/no-unused-expressions
"no-unused-expressions": "error",
// https://eslint.org/docs/rules/no-useless-concat
"no-useless-concat": "error",
// https://eslint.org/docs/rules/radix
"radix": "error",
// https://eslint.org/docs/rules/require-await
"require-await": "error",
// https://eslint.org/docs/rules/no-alert
"no-alert": "error",
// https://eslint.org/docs/rules/no-useless-constructor
"no-useless-constructor": "error",
// https://eslint.org/docs/rules/no-duplicate-imports
"no-duplicate-imports": "error",
// https://eslint.org/docs/rules/no-implicit-coercion
"no-implicit-coercion": "error",
//https://eslint.org/docs/rules/no-unneeded-ternary
"no-unneeded-ternary": "error",
// https://eslint.org/docs/rules/semi
"semi": ["error", "always"],
// https://eslint.org/docs/rules/no-multi-spaces
"no-multi-spaces": "error",
// https://eslint.org/docs/rules/key-spacing
"key-spacing": ["error", {
"afterColon": true
}],
// https://eslint.org/docs/rules/keyword-spacing
"keyword-spacing": ["error", {
"before": true,
"after": true
}],
// https://eslint.org/docs/rules/comma-spacing
// Also requires one line code fix
"comma-spacing": ["error", {
"after": true
}],
//https://eslint.org/docs/rules/no-whitespace-before-property
"no-whitespace-before-property": "error",
// https://eslint.org/docs/rules/object-curly-newline
"object-curly-newline": ["error", {"consistent": true, "multiline": true}],
// https://eslint.org/docs/rules/object-property-newline
"object-property-newline": "error",
// https://eslint.org/docs/rules/brace-style
"brace-style": "error",
// https://eslint.org/docs/rules/no-multiple-empty-lines
"no-multiple-empty-lines": ["error", {"max": 1}],
// https://eslint.org/docs/rules/operator-linebreak
"operator-linebreak": ["error", "before", {"overrides": {"=": "after"}}],
// https://eslint.org/docs/rules/padding-line-between-statements
"padding-line-between-statements":["error", {
"blankLine": "always",
"prev": "multiline-block-like",
"next": "*"
}, {
"blankLine": "always",
"prev": "*",
"next": "return"
}],
// https://eslint.org/docs/rules/space-infix-ops
"space-infix-ops": "error",
// https://eslint.org/docs/rules/space-unary-ops
"space-unary-ops": ["error", {"words": true, "nonwords": false}],
// https://eslint.org/docs/rules/arrow-spacing
"arrow-spacing": "error",
// https://eslint.org/docs/rules/semi-spacing
"semi-spacing": ["error", {"before": false, "after": true}],
"vue/html-indent": [ "vue/html-indent": [
"error", "error",
4, 4,
@ -96,21 +236,24 @@ module.exports = {
} }
}], }],
"vue/multiline-html-element-content-newline": "off", "vue/multiline-html-element-content-newline": "off",
"vue/singleline-html-element-content-newline": "off" "vue/singleline-html-element-content-newline": "off",
}, },
"overrides": [ "overrides": [
{ {
"files": ["*Spec.js"], "files": LEGACY_FILES,
"rules": { "rules": {
"no-unused-vars": [ "no-unused-vars": [
"warn", "warn",
{ {
"vars": "all", "vars": "all",
"args": "none", "args": "none",
"varsIgnorePattern": "controller", "varsIgnorePattern": "controller"
} }
] ],
"no-nested-ternary": "off",
"no-var": "off",
"one-var": "off"
} }
} }
] ]

3
.gitignore vendored
View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government * Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *
@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/EventTelemetryProvider" "./src/EventTelemetryProvider"
@ -29,7 +28,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

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government * Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *
@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define */
/** /**
* Module defining EventTelemetry. * Module defining EventTelemetry.
@ -44,13 +43,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define,Promise*/
/** /**
* Module defining EventTelemetryProvider. Created by chacskaylo on 06/18/2015. * Module defining EventTelemetryProvider. Created by chacskaylo on 06/18/2015.
@ -57,6 +56,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([], function () { define([], function () {
'use strict'; 'use strict';
@ -76,13 +75,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
'./ExportTelemetryAsCSVAction' './ExportTelemetryAsCSVAction'
@ -27,7 +26,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/ExampleFormController" "./src/ExampleFormController"
@ -29,7 +28,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

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government * Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *
@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define,window*/
define( define(
[], [],
@ -80,7 +79,7 @@ define(
control: "button", control: "button",
csslass: "icon-save", csslass: "icon-save",
click: function () { click: function () {
window.alert("Save"); console.log("Save");
} }
}, },
{ {
@ -88,7 +87,7 @@ define(
csslass: "icon-x", csslass: "icon-x",
description: "Button B", description: "Button B",
click: function () { click: function () {
window.alert("Cancel"); console.log("Cancel");
} }
}, },
{ {
@ -97,7 +96,7 @@ define(
description: "Button C", description: "Button C",
disabled: true, disabled: true,
click: function () { click: function () {
window.alert("Delete"); console.log("Delete");
} }
} }
] ]
@ -152,10 +151,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 +175,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

@ -28,9 +28,20 @@ define([
domain: 2 domain: 2
} }
}, },
// Need to enable "LocalTimeSystem" plugin to make use of this
// {
// key: "local",
// name: "Time",
// format: "local-format",
// source: "utc",
// hints: {
// domain: 3
// }
// },
{ {
key: "sin", key: "sin",
name: "Sine", name: "Sine",
unit: "Hz",
formatString: '%0.2f', formatString: '%0.2f',
hints: { hints: {
range: 1 range: 1
@ -39,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
@ -61,6 +73,15 @@ define([
domain: 1 domain: 1
} }
}, },
{
key: "local",
name: "Time",
format: "utc",
source: "utc",
hints: {
domain: 2
}
},
{ {
key: "state", key: "state",
source: "value", source: "value",
@ -89,18 +110,18 @@ define([
} }
] ]
} }
} };
function GeneratorMetadataProvider() { function GeneratorMetadataProvider() {
} }
GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) { GeneratorMetadataProvider.prototype.supportsMetadata = function (domainObject) {
return METADATA_BY_TYPE.hasOwnProperty(domainObject.type); return Object.prototype.hasOwnProperty.call(METADATA_BY_TYPE, domainObject.type);
}; };
GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) { GeneratorMetadataProvider.prototype.getMetadata = function (domainObject) {
return _.extend( return Object.assign(
{}, {},
domainObject.telemetry, domainObject.telemetry,
METADATA_BY_TYPE[domainObject.type] METADATA_BY_TYPE[domainObject.type]

View File

@ -62,18 +62,22 @@ define([
var workerRequest = {}; var workerRequest = {};
props.forEach(function (prop) { props.forEach(function (prop) {
if (domainObject.telemetry && domainObject.telemetry.hasOwnProperty(prop)) { if (domainObject.telemetry && Object.prototype.hasOwnProperty.call(domainObject.telemetry, prop)) {
workerRequest[prop] = domainObject.telemetry[prop]; workerRequest[prop] = domainObject.telemetry[prop];
} }
if (request && request.hasOwnProperty(prop)) {
if (request && Object.prototype.hasOwnProperty.call(request, prop)) {
workerRequest[prop] = request[prop]; workerRequest[prop] = request[prop];
} }
if (!workerRequest.hasOwnProperty(prop)) {
if (!Object.prototype.hasOwnProperty.call(workerRequest, 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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
@ -78,12 +77,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

@ -72,13 +72,16 @@ define([
}); });
var messageId; var messageId;
let self = this;
function callback(message) { function callback(message) {
if (message.error) { if (message.error) {
deferred.reject(message.error); deferred.reject(message.error);
} else { } else {
deferred.resolve(message.data); deferred.resolve(message.data);
} }
delete this.callbacks[messageId];
delete self.callbacks[messageId];
} }
messageId = this.dispatch('request', request, callback.bind(this)); messageId = this.dispatch('request', request, callback.bind(this));
@ -101,8 +104,5 @@ define([
}.bind(this); }.bind(this);
}; };
return WorkerInterface; return WorkerInterface;
}); });

View File

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government * Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *
@ -20,8 +20,6 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global self*/
(function () { (function () {
var FIFTEEN_MINUTES = 15 * 60 * 1000; var FIFTEEN_MINUTES = 15 * 60 * 1000;
@ -64,13 +62,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 +86,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 +110,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 +123,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./GeneratorProvider", "./GeneratorProvider",
@ -56,7 +55,7 @@ define([
initialize: function (object) { initialize: function (object) {
object.telemetry = { object.telemetry = {
duration: 5 duration: 5
} };
} }
}); });

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/ExampleIdentityService" "./src/ExampleIdentityService"
@ -29,7 +28,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/identity", name: "example/identity",
definition: { definition: {
"extensions": { "extensions": {
"components": [ "components": [

View File

@ -19,32 +19,35 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( 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 +80,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

@ -52,6 +52,7 @@ define([
return { return {
name: name, name: name,
utc: Math.floor(timestamp / 5000) * 5000, utc: Math.floor(timestamp / 5000) * 5000,
local: Math.floor(timestamp / 5000) * 5000,
url: IMAGE_SAMPLES[Math.floor(timestamp / 5000) % IMAGE_SAMPLES.length] url: IMAGE_SAMPLES[Math.floor(timestamp / 5000) % IMAGE_SAMPLES.length]
}; };
} }
@ -78,34 +79,34 @@ define([
}, },
request: function (domainObject, options) { request: function (domainObject, options) {
var start = options.start; var start = options.start;
var end = options.end; var end = Math.min(options.end, Date.now());
var data = []; var data = [];
while (start <= end && data.length < 5000) { while (start <= end && data.length < 5000) {
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 = {
@ -118,6 +119,14 @@ define([
name: 'Time', name: 'Time',
key: 'utc', key: 'utc',
format: 'utc', format: 'utc',
hints: {
domain: 2
}
},
{
name: 'Local Time',
key: 'local',
format: 'local-format',
hints: { hints: {
domain: 1 domain: 1
} }
@ -131,7 +140,7 @@ define([
} }
} }
] ]
} };
} }
}); });

View File

@ -19,13 +19,12 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([], function () { 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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/RemsTelemetryServerAdapter", "./src/RemsTelemetryServerAdapter",
@ -31,14 +30,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 +89,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
[], [],
@ -38,7 +37,7 @@ define(
"identifier": "msl", "identifier": "msl",
"instruments": [ "instruments": [
{ {
"name":"rems", "name": "rems",
"identifier": "rems", "identifier": "rems",
"measurements": [ "measurements": [
{ {

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
function () { function () {
@ -81,6 +80,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 +90,7 @@ define(
} }
}; };
} }
return RemsTelemetryModelProvider; return RemsTelemetryModelProvider;
} }
); );

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define */
define ( define (
['./RemsTelemetrySeries'], ['./RemsTelemetrySeries'],
function (RemsTelemetrySeries) { function (RemsTelemetrySeries) {
@ -74,6 +73,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define */
define( define(
function () { function () {
"use strict"; "use strict";
@ -57,6 +56,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
/*jslint es5: true */ /*jslint es5: true */
define( define(
@ -95,28 +94,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/DialogLaunchController", "./src/DialogLaunchController",
@ -39,7 +38,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/notifications", name: "example/notifications",
definition: { definition: {
"extensions": { "extensions": {
"templates": [ "templates": [

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
[], [],
@ -91,7 +90,6 @@ define(
} }
}; };
/* /*
Demonstrates launching an error dialog Demonstrates launching an error dialog
*/ */
@ -132,9 +130,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 +151,7 @@ define(
}; };
} }
return DialogLaunchController; return DialogLaunchController;
} }
); );

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define,window*/
define( define(
[], [],
@ -42,9 +41,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
[], [],
@ -48,7 +47,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 +61,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 +74,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 +93,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 +120,7 @@ define(
}; };
} }
return NotificationLaunchController; return NotificationLaunchController;
} }
); );

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define,window*/
define( define(
[], [],
@ -42,9 +41,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/BrowserPersistenceProvider" "./src/BrowserPersistenceProvider"
@ -29,7 +28,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/persistence", name: "example/persistence",
definition: { definition: {
"extensions": { "extensions": {
"components": [ "components": [

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
/** /**
* Stubbed implementation of a persistence provider, * Stubbed implementation of a persistence provider,
@ -30,8 +29,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 +48,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 +66,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/ExamplePolicy" "./src/ExamplePolicy"
@ -29,7 +28,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
[], [],
@ -37,6 +36,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/WatchIndicator", "./src/WatchIndicator",
@ -31,7 +30,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/profiling", name: "example/profiling",
definition: { definition: {
"extensions": { "extensions": {
"indicators": [ "indicators": [

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
[], [],

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
[], [],

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define([ define([
"./src/ScratchPersistenceProvider" "./src/ScratchPersistenceProvider"
@ -29,7 +28,7 @@ define([
"use strict"; "use strict";
return { return {
name:"example/scratchpad", name: "example/scratchpad",
definition: { definition: {
"extensions": { "extensions": {
"roots": [ "roots": [

View File

@ -20,8 +20,6 @@
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define,window*/
define( define(
[], [],
function () { function () {
@ -54,13 +52,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 +67,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
[], [],
@ -30,14 +29,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 +77,6 @@ define(
}; };
} }
return ExampleStyleGuideModelProvider return ExampleStyleGuideModelProvider;
} }
); );

View File

@ -34,8 +34,8 @@
<body> <body>
</body> </body>
<script> <script>
const FIVE_MINUTES = 5 * 60 * 1000; const THIRTY_SECONDS = 30 * 1000;
const THIRTY_MINUTES = 30 * 60 * 1000; const THIRTY_MINUTES = THIRTY_SECONDS * 60;
[ [
'example/eventGenerator' 'example/eventGenerator'
@ -63,7 +63,39 @@
bounds: { bounds: {
start: Date.now() - THIRTY_MINUTES, start: Date.now() - THIRTY_MINUTES,
end: Date.now() end: Date.now()
} },
// commonly used bounds can be stored in history
// bounds (start and end) can accept either a milliseconds number
// or a callback function returning a milliseconds number
// a function is useful for invoking Date.now() at exact moment of preset selection
presets: [
{
label: 'Last Day',
bounds: {
start: () => Date.now() - 1000 * 60 * 60 * 24,
end: () => Date.now()
}
},
{
label: 'Last 2 hours',
bounds: {
start: () => Date.now() - 1000 * 60 * 60 * 2,
end: () => Date.now()
}
},
{
label: 'Last hour',
bounds: {
start: () => Date.now() - 1000 * 60 * 60,
end: () => Date.now()
}
}
],
// maximum recent bounds to retain in conductor history
records: 10,
// maximum duration between start and end bounds
// for utc-based time systems this is in milliseconds
limit: 1000 * 60 * 60 * 24
}, },
{ {
name: "Realtime", name: "Realtime",
@ -71,7 +103,7 @@
clock: 'local', clock: 'local',
clockOffsets: { clockOffsets: {
start: - THIRTY_MINUTES, start: - THIRTY_MINUTES,
end: FIVE_MINUTES end: THIRTY_SECONDS
} }
} }
] ]
@ -81,7 +113,10 @@
openmct.install(openmct.plugins.LADTable()); openmct.install(openmct.plugins.LADTable());
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay'])); openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
openmct.install(openmct.plugins.ObjectMigration()); openmct.install(openmct.plugins.ObjectMigration());
openmct.install(openmct.plugins.ClearData(['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked'])); openmct.install(openmct.plugins.ClearData(
['table', 'telemetry.plot.overlay', 'telemetry.plot.stacked'],
{indicator: true}
));
openmct.start(); openmct.start();
</script> </script>
</html> </html>

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' : 'ChromeHeadless']; const browsers = [process.env.NODE_ENV === 'debug' ? 'ChromeDebugging' : 'FirefoxHeadless'];
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',
@ -82,19 +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'
}, },
singleRun: true concurrency: 1,
singleRun: true,
browserNoActivityTimeout: 400000
}); });
} };

View File

@ -32,6 +32,6 @@ if (document.currentScript) {
const MCT = require('./src/MCT'); const MCT = require('./src/MCT');
var openmct = new MCT(); const openmct = new MCT();
module.exports = openmct; module.exports = openmct;

View File

@ -1,12 +1,12 @@
{ {
"name": "openmct", "name": "openmct",
"version": "1.0.0-snapshot", "version": "1.3.0-SNAPSHOT",
"description": "The Open MCT core platform", "description": "The Open MCT core platform",
"dependencies": {}, "dependencies": {},
"devDependencies": { "devDependencies": {
"angular": "1.7.9", "angular": ">=1.8.0",
"angular-route": "1.4.14", "angular-route": "1.4.14",
"babel-eslint": "8.2.6", "babel-eslint": "10.0.3",
"comma-separated-values": "^3.6.4", "comma-separated-values": "^3.6.4",
"concurrently": "^3.6.1", "concurrently": "^3.6.1",
"copy-webpack-plugin": "^4.5.2", "copy-webpack-plugin": "^4.5.2",
@ -22,8 +22,9 @@
"d3-selection": "1.3.x", "d3-selection": "1.3.x",
"d3-time": "1.0.x", "d3-time": "1.0.x",
"d3-time-format": "2.1.x", "d3-time-format": "2.1.x",
"eslint": "5.2.0", "eslint": "7.0.0",
"eslint-plugin-vue": "^6.0.0", "eslint-plugin-vue": "^6.0.0",
"eslint-plugin-you-dont-need-lodash-underscore": "^6.10.0",
"eventemitter3": "^1.2.0", "eventemitter3": "^1.2.0",
"exports-loader": "^0.7.0", "exports-loader": "^0.7.0",
"express": "^4.13.1", "express": "^4.13.1",
@ -38,27 +39,28 @@
"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-cli": "^1.0.1", "karma-firefox-launcher": "1.3.0",
"karma-coverage": "^1.1.2", "karma-cli": "2.0.0",
"karma-coverage-istanbul-reporter": "^2.1.1", "karma-coverage": "2.0.3",
"karma-html-reporter": "^0.2.7", "karma-coverage-istanbul-reporter": "3.0.3",
"karma-jasmine": "^1.1.2", "karma-html-reporter": "0.2.7",
"karma-sourcemap-loader": "^0.3.7", "karma-jasmine": "3.3.1",
"karma-webpack": "^3.0.0", "karma-sourcemap-loader": "0.3.7",
"karma-webpack": "4.0.2",
"location-bar": "^3.0.1", "location-bar": "^3.0.1",
"lodash": "^3.10.1", "lodash": "^4.17.12",
"markdown-toc": "^0.11.7", "markdown-toc": "^0.11.7",
"marked": "^0.3.5", "marked": "^0.3.5",
"mini-css-extract-plugin": "^0.4.1", "mini-css-extract-plugin": "^0.4.1",
"minimist": "^1.1.1", "minimist": "^1.2.5",
"moment": "2.25.3", "moment": "2.25.3",
"moment-duration-format": "^2.2.2", "moment-duration-format": "^2.2.2",
"moment-timezone": "0.5.28", "moment-timezone": "0.5.28",
"node-bourbon": "^4.2.3", "node-bourbon": "^4.2.3",
"node-sass": "^4.9.2", "node-sass": "^4.14.1",
"painterro": "^0.2.65", "painterro": "^1.0.35",
"printj": "^1.2.1", "printj": "^1.2.1",
"raw-loader": "^0.5.1", "raw-loader": "^0.5.1",
"request": "^2.69.0", "request": "^2.69.0",
@ -83,10 +85,10 @@
"build:prod": "cross-env NODE_ENV=production webpack", "build:prod": "cross-env NODE_ENV=production webpack",
"build:dev": "webpack", "build:dev": "webpack",
"build:watch": "webpack --watch", "build:watch": "webpack --watch",
"test": "karma start --single-run", "test": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --single-run",
"test:debug": "cross-env NODE_ENV=debug karma start --no-single-run", "test:debug": "cross-env NODE_ENV=debug karma start --no-single-run",
"test:coverage": "./scripts/test-coverage.sh", "test:coverage": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" COVERAGE=true karma start --single-run",
"test:watch": "karma start --no-single-run", "test:watch": "cross-env NODE_OPTIONS=\"--max_old_space_size=4096\" karma start --no-single-run",
"verify": "concurrently 'npm:test' 'npm:lint'", "verify": "concurrently 'npm:test' 'npm:lint'",
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api", "jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
"otherdoc": "node docs/gendocs.js --in docs/src --out dist/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'", "otherdoc": "node docs/gendocs.js --in docs/src --out dist/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'",

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

@ -25,14 +25,20 @@ define(
function (AboutController) { function (AboutController) {
describe("The About controller", function () { describe("The About controller", function () {
var testVersions, let testVersions;
mockWindow, let mockWindow;
controller; let controller;
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);
@ -50,8 +56,6 @@ define(
controller.openLicenses(); controller.openLicenses();
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

@ -6,6 +6,12 @@
ng-show="ngModel.dialog.messages.length > 1 || ng-show="ngModel.dialog.messages.length > 1 ||
ngModel.dialog.messages.length == 0">s</span> ngModel.dialog.messages.length == 0">s</span>
</div> </div>
<button
ng-if="ngModel.dialog.topBarButton"
class="c-button c-button--major"
ng-click="ngModel.topBarButton.onClick">
{{ ngModel.topBarButton.label }}
</button>
</div> </div>
<div class="w-messages c-overlay__messages"> <div class="w-messages c-overlay__messages">
<mct-include <mct-include
@ -16,7 +22,7 @@
<button ng-repeat="dialogAction in ngModel.dialog.actions" <button ng-repeat="dialogAction in ngModel.dialog.actions"
class="c-button c-button--major" class="c-button c-button--major"
ng-click="dialogAction.action()"> ng-click="dialogAction.action()">
{{dialogAction.label}} {{ dialogAction.label }}
</button> </button>
</div> </div>
</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

@ -81,10 +81,15 @@ define(
* context. * context.
*/ */
PropertiesAction.appliesTo = function (context) { PropertiesAction.appliesTo = function (context) {
var domainObject = (context || {}).domainObject, var domainObject = (context || {}).domainObject,
type = domainObject && domainObject.getCapability('type'), type = domainObject && domainObject.getCapability('type'),
creatable = type && type.hasFeature('creation'); creatable = type && type.hasFeature('creation');
if (domainObject && domainObject.model && domainObject.model.locked) {
return false;
}
// Only allow creatable types to be edited // Only allow creatable types to be edited
return domainObject && creatable; return domainObject && creatable;
}; };
@ -94,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 self.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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
['./TransactionalPersistenceCapability'], ['./TransactionalPersistenceCapability'],
@ -56,9 +55,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 +66,7 @@ define(
domainObject domainObject
); );
}; };
return capabilities; return capabilities;
}; };

View File

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
[], [],
@ -64,6 +63,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 +74,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

@ -56,10 +56,11 @@ define(
*/ */
CreateWizard.prototype.getFormStructure = function (includeLocation) { CreateWizard.prototype.getFormStructure = function (includeLocation) {
var sections = [], var sections = [],
domainObject = this.domainObject; domainObject = this.domainObject,
self = this;
function validateLocation(parent) { function validateLocation(parent) {
return parent && this.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter')); return parent && self.openmct.composition.checkPolicy(parent.useCapability('adapter'), domainObject.useCapability('adapter'));
} }
sections.push({ sections.push({
@ -114,6 +115,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

@ -21,7 +21,7 @@
*****************************************************************************/ *****************************************************************************/
define( define(
['../../../../../src/api/objects/object-utils'], ['objectUtils'],
function (objectUtils) { function (objectUtils) {
/** /**
@ -36,8 +36,6 @@ define(
} }
EditPersistableObjectsPolicy.prototype.allow = function (action, context) { EditPersistableObjectsPolicy.prototype.allow = function (action, context) {
var identifier;
var provider;
var domainObject = context.domainObject; var domainObject = context.domainObject;
var key = action.getMetadata().key; var key = action.getMetadata().key;
var category = (context || {}).category; var category = (context || {}).category;
@ -46,9 +44,9 @@ define(
// is also invoked during the create process which should be allowed, // is also invoked during the create process which should be allowed,
// 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') {
identifier = objectUtils.parseKeyString(domainObject.getId()); let newStyleObject = objectUtils.toNewFormat(domainObject, domainObject.getId());
provider = this.openmct.objects.getProvider(identifier);
return provider.save !== undefined; return this.openmct.objects.isPersistable(newStyleObject);
} }
return true; return true;

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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global define*/
define( define(
['./Transaction', './NestedTransaction'], ['./Transaction', './NestedTransaction'],
function (Transaction, NestedTransaction) { function (Transaction, NestedTransaction) {
@ -48,9 +47,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 +98,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 +121,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

@ -1,5 +1,5 @@
/***************************************************************************** /*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government * Open MCT, Copyright (c) 2014-2020, United States Government
* as represented by the Administrator of the National Aeronautics and Space * as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved. * Administration. All rights reserved.
* *
@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global describe,it,expect,beforeEach,jasmine*/
define( define(
["../../src/actions/SaveAction"], ["../../src/actions/SaveAction"],
@ -138,6 +137,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 +147,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

@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available * this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information. * at runtime from the About dialog for additional information.
*****************************************************************************/ *****************************************************************************/
/*global describe,it,expect,beforeEach,jasmine*/
define( define(
["../../src/actions/SaveAndStopEditingAction"], ["../../src/actions/SaveAndStopEditingAction"],
@ -97,7 +96,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");

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