Compare commits

..

196 Commits

Author SHA1 Message Date
charlesh88
075cf6a4da [Frontend] Refactor .object-holder > .holder-object
- Mods to markup and CSS;
- Cherry pick this commit into master once Notebook is merged in;
2018-06-01 14:42:41 -07:00
charlesh88
4f86b4e0de Merge branch 'fluid-layouts' into notebook-integration-deep 2018-06-01 11:02:00 -07:00
charlesh88
554fb7574e Merge branch 'master' into notebook-integration-deep
# Resolve conflicts:
#	index.html
#	platform/commonUI/general/res/sass/mobile/_layout.scss
2018-05-25 17:13:28 -07:00
charlesh88
2fe1977c32 [Frontend] Notebook mobile mods
- Hide entry area when mobile;
- Disallow entry edit or delete in mobile;
2018-05-25 14:31:20 -07:00
Deep Tailor
721b966b0c fix failing test 2018-05-25 13:15:31 -07:00
Deep Tailor
1fc64e54b5 merge with master and fix coflicts 2018-05-25 13:11:27 -07:00
charlesh88
ec682d5734 [Frontend] Added new 12px grippy glyph
- Font files and CSS updates for Elements pool sorting styling;
2018-05-22 17:16:02 -07:00
charlesh88
6b8da63697 [Frontend] Added new 12px list view glyph
- Font files and CSS updates;
2018-05-22 16:30:39 -07:00
charlesh88
6040bafba8 [Frontend] Tweaks to Elements pool reordering styles
- "reorder-actor" added/removed from parent tree item;
- Refined styling for drag in process in list;
2018-05-22 16:12:35 -07:00
Deep Tailor
cb9ae92e69 stacked plots reload on composition change 2018-05-22 13:53:12 -07:00
Deep Tailor
d14c2cf62e add reorder-actor class to draggable item in elements pool when selected and remove class when dropped 2018-05-22 11:39:39 -07:00
charlesh88
03663488b9 [Frontend] Styles for reordering in Elements pool
- Changed class "dragging" to "reordering";
- Visual styling WIP;
- TODO: style "reorder-actor" when implemented;
2018-05-22 11:20:39 -07:00
charlesh88
34ccf45351 [Frontend] Allow editor to set mins dimensions for fluid layout
- Cleanups in CSS;
- Mod to LayoutController.js to use minWidth and minHeight;
2018-05-22 10:48:14 -07:00
Charles Hacskaylo
dff7e3d8a2 Merge branch 'fluid-layouts' of https://github.com/nasa/openmct into fluid-layouts 2018-05-21 16:07:29 -07:00
Charles Hacskaylo
5435e9d88b [Frontend] Added fl-mobile-best-fit 2018-05-21 16:05:38 -07:00
Deep Tailor
8c22ce23bf add maxHeight and maxWidth to layout frames 2018-05-21 13:39:51 -07:00
Deep Tailor
4b827e2c13 add ability to rearrange composition using drag gestures 2018-05-21 12:11:04 -07:00
Deep Tailor
25588c87d1 fix conflict 2018-05-21 10:17:26 -07:00
Deep Tailor
73a8f71740 merge latest to local 2018-05-21 10:15:54 -07:00
Deep Tailor
04f333f99b working drag and switch, need to mutate 2018-05-18 08:55:30 -07:00
charlesh88
5f592099fb [Frontend] More CSS tweaks
- WIP!
- Added .fl-phone-best-fit
2018-05-17 15:19:13 -07:00
charlesh88
9a9db2ddd9 [Frontend] Added .drag-vertical
- For use in Elements pool;
- Applied in elements.html;
2018-05-17 14:56:38 -07:00
charlesh88
5ae0e97e03 [Frontend] More CSS tweaks
- WIP!
2018-05-17 14:56:38 -07:00
charlesh88
62ccbd87ba [Frontend] Grid holder and class prefixing
- WIP!
- Edit grid-holder set to position: absolute
- Added "fl-" prefix to fluid layout class names;
2018-05-17 14:56:38 -07:00
charlesh88
4ce2b471d7 [Frontend] Add Advanced CSS property to Display Layouts
- WIP!
- Add property to bundle;
- Add CSS for column, row and fit-all classes;
2018-05-17 14:56:38 -07:00
Deep Tailor
202ca2e553 fixes issue #1999 - Use Object name as default export filename (#2001)
* fixes issue #1999
add dynamic name(object name) to exportAsCSV filename

* make requested changes
2018-05-17 14:56:38 -07:00
Nick Weingartner
e1397258e5 [Copyright] Update copyright year across platform code references
Fixes #2034.
2018-05-17 14:56:38 -07:00
Dhrubomoy Das Gupta
935386ef6e [TimeConductor] Fixes Issue #925 (#2020)
* [TimeConductor] Fixes Issue #925`
- Pressing enter in date field will update bounds properly in Safari
2018-05-17 14:56:37 -07:00
Nick Weingartner
e1c1a25d66 [Timer] Fix regression in timer visual indication and add tests 2018-05-17 14:56:37 -07:00
Even Stensberg
b8248aabfb fix: check if stats is present before reseting zoom (#2029) 2018-05-17 14:56:37 -07:00
charlesh88
7d32ea468f [Frontend] Added .drag-vertical
- For use in Elements pool;
- Applied in elements.html;
2018-05-17 14:50:19 -07:00
charlesh88
73ad8aa74f [Frontend] More CSS tweaks
- WIP!
2018-05-17 14:31:06 -07:00
charlesh88
6448269d5c [Frontend] Grid holder and class prefixing
- WIP!
- Edit grid-holder set to position: absolute
- Added "fl-" prefix to fluid layout class names;
2018-05-17 11:20:10 -07:00
charlesh88
00b8104023 [Frontend] Add Advanced CSS property to Display Layouts
- WIP!
- Add property to bundle;
- Add CSS for column, row and fit-all classes;
2018-05-16 16:43:01 -07:00
Deep Tailor
809d137b28 fix auto focus on new entry when in oldest first order, both in layout and regular view 2018-05-16 11:57:01 -07:00
Deep Tailor
3d440f3374 Add default sort options on creation menu of Notebook 2018-05-16 11:21:00 -07:00
Charles Hacskaylo
18c1056800 [Frontend] Mods to imagery CSS
Fixes #2008
- Reduced size of image thumbnails;
- Changed min-heights of image and thumbnail
holders for .mobile.phone
2018-05-11 08:37:15 -07:00
Deep Tailor
853d21bb32 remove couchdb and reinstall localStorage 2018-05-10 14:43:23 -07:00
Deep Tailor
f265c3e495 Add touch functionality to mct-drag
it allows users to use the splitter in mobile
and include appropriate tests
2018-05-10 14:32:07 -07:00
Deep Tailor
ef9e24c313 fixes edge case for issue #1981
Add a reject callback in the edgecase that user presses the x icon or esc key to cancel annotation, which was leading to the drag drop issue
2018-05-09 12:36:15 -07:00
charlesh88
336d58d45a [Frontend] Various
Fixes #2008
- Always show Timeline zoom controls;
- Prevent inline editing of object names in the main view when in
mobile;
2018-05-09 12:17:30 -07:00
Deep Tailor
f8f95c5263 remove create snapshot action from embeds, and add preview action to embeds 2018-05-08 15:54:10 -07:00
Deep Tailor
c22659432d fixes multiple issues related to 2008
context menu firing too often - fixed by setting a isDragging flag
Add and Remove respective classes on mobile orientation change by using mathMedia
Close tree pane when navigating in mobile portrait only
2018-05-07 12:07:18 -07:00
charlesh88
5126e6b842 [Frontend] Significant mobile fixes for panes and viewport
Fixes #2008
Fixes #1770
Fixes #1928
- Left and right panes now positioning properly in mobile;
- Fixed body overflow problem for #2008 "viewport" issue;
2018-05-04 18:10:06 -07:00
charlesh88
e02e47f2a0 [Frontend] Hide TC ticks when on mobile
Fixes #2008
- Added class `mobile-hide` to <conductor-axis>
2018-05-04 18:10:06 -07:00
charlesh88
8a51e8ca48 [Frontend] Remove data visualization element in TC
Fixes #2008
- Note: this element holds the TOI indicator!
2018-05-04 18:10:06 -07:00
charlesh88
a60996abd4 [Frontend] Fix to Time Conductor for Safari
Fixes #2008
- CSS mod for gradient blockers in TC
2018-05-04 18:10:06 -07:00
charlesh88
2b58500508 [Frontend] Viewport metatag updated
Fixes #2008
- Added shrink-to-fit=no;
2018-05-04 18:10:06 -07:00
Deep Tailor
67a68ff8db remove description required when saving snapshot to notebook 2018-05-03 11:23:48 -07:00
Deep Tailor
77d08798e8 fix painterro button styling issue
move jquery logic inside timeout block, because buttons are asynchronously created
2018-04-23 15:37:08 -07:00
Deep Tailor
facf732692 Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-04-23 15:27:44 -07:00
Deep Tailor
5a181a34dc fixes issue where annotating snapshot that is already saved in notebook does not work 2018-04-23 15:27:27 -07:00
Deep Tailor
e96ed9942b Merge branch 'master' into notebook-integration-deep 2018-04-23 14:31:01 -07:00
Deep Tailor
1e807829a3 Merge pull request #1997 from nasa/painterro-verification
Painterro verification
2018-04-23 13:45:29 -07:00
Deep Tailor
e70d4d0338 fix checkstyle 2018-04-23 13:37:38 -07:00
Pete Richards
891d863590 Bump Node Version 2018-04-23 13:21:49 -07:00
Deep Tailor
22b30383a5 fixes #1951
persist modified empty entry on blur
2018-04-23 12:48:01 -07:00
Deep Tailor
5fe9be7882 add save flag and call done in both cases (clicking on cancel or ok) 2018-04-23 11:04:42 -07:00
Henry
e3f0c79b2e Use updated painterro library. Fixes #1981 2018-04-20 16:40:53 -07:00
Henry
0972b64a40 Reduce frequency of template recompilation in mct-include 2018-04-18 08:37:18 -07:00
Deep Tailor
5f80ce9504 add functionality of being able to add buttons to the browse bar element of overlay when instantiating the overlay service 2018-04-02 15:37:29 -07:00
Deep Tailor
ef48249a27 fix checkstyle and lint 2018-04-02 13:06:45 -07:00
Deep Tailor
5ab9bd5960 fix broken mcttriggermodal tests 2018-04-02 13:04:03 -07:00
Deep Tailor
36ecf66abb abstract overlay into a service/api - to reduce code duplication
catch error produced by painterro because of async div creation by dialog service
2018-04-02 12:50:32 -07:00
Charles Hacskaylo
beebd002ac [Frontend] Notebook/Preview related sanding and polishing
Fixes #1947
- Classes for Notebook Entry button spacing;
2018-03-28 14:39:36 -07:00
Deep Tailor
a6a73126e1 code cleanup 2018-03-28 14:32:43 -07:00
Charles Hacskaylo
957a9e8eab [Frontend] Notebook/Preview related sanding and polishing
Fixes #1947
- Added new global "hide-in-t-main-view" class;
- Apply new class to Preview action to suppress
display of that button in main view of navigated object;
2018-03-27 18:41:35 -07:00
Charles Hacskaylo
c3b98890d9 [Frontend] Notebook/Preview related sanding and polishing
Fixes #1947
- Changed description for notebook-new-entry
2018-03-27 18:40:02 -07:00
Charles Hacskaylo
b8ae9fb08a [Frontend] Painterro styling and config
Fixes #1896
Fixes #1947
- Changes mainly related to toolbar styling and labels
2018-03-27 16:40:33 -07:00
Deep Tailor
91f442401d changes to browseController and NavigationService to block navigation and show preview of object when trying to navigate to object in tree in edit mode 2018-03-27 15:55:26 -07:00
Deep Tailor
261583293b dont allow preview action on objects getting edited currently 2018-03-27 13:51:26 -07:00
Deep Tailor
10a11b2597 change glyph for preview, use similar tempalte to frame.html 2018-03-27 10:45:41 -07:00
Deep Tailor
25373e0c89 fix checkstyle 2018-03-26 16:10:35 -07:00
Deep Tailor
8daada635b add preview action, working, need styling for notebook action on preview 2018-03-26 16:09:43 -07:00
Deep Tailor
e6b6bd2772 remove snapshot from frame view, add it only to overlay, change mctSnapShot to accomodate taking snaps of overlay/object view 2018-03-22 15:48:25 -07:00
Deep Tailor
796814359c remove snapshot button from frames in layout 2018-03-22 14:12:19 -07:00
Charles Hacskaylo
21294812e4 [Frontend] Adding background color to snapshot
Fixes #1896
Fixes #1947
2018-03-22 13:36:24 -07:00
Charles Hacskaylo
fca221dbb3 Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-03-22 13:33:46 -07:00
Deep Tailor
f1da9df37b remove snapshot class after async image render 2018-03-22 13:32:35 -07:00
Charles Hacskaylo
82c11a4fb8 Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-03-22 13:25:35 -07:00
Charles Hacskaylo
5edcd78ca3 [Frontend] Adding background color to snapshot
Fixes #1896
Fixes #1947
2018-03-22 13:25:28 -07:00
Deep Tailor
d8205e0a8f select correct div for snapshot 2018-03-22 13:23:08 -07:00
Charles Hacskaylo
97488cc996 Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-03-22 13:09:28 -07:00
Charles Hacskaylo
90fe0545d3 [Frontend] Local controls CSS added for hide/show of trash can icons
Fixes #1896
Fixes #1947
- Also updated frame.scss to use same transition timing
2018-03-22 13:08:56 -07:00
Deep Tailor
1bb6e140c1 dragging objects to notebook now only creates a link, clicking on snapshot from object view takes a snapshot of the current view, without re-rendering 2018-03-22 13:06:24 -07:00
Pete Richards
7cbeb22e1c proper shimming 2018-03-22 11:22:02 -07:00
Charles Hacskaylo
50f85dfa8e Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-03-22 10:56:24 -07:00
Charles Hacskaylo
bdf5b9ec1a [Frontend] Local controls CSS added for hide/show of trash can icons
Fixes #1896
Fixes #1947
- Also updated frame.scss to use same transition timing
2018-03-22 10:33:20 -07:00
Pete Richards
a0c1729df2 specify require paths for new library 2018-03-22 10:21:47 -07:00
Charles Hacskaylo
220a93e530 Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-03-21 22:37:48 -07:00
Deep Tailor
f9464ba065 fixes issue of overlay not closing when context menu item in clicked when viewing snapshot 2018-03-21 22:37:20 -07:00
Charles Hacskaylo
541e3d7be1 [Frontend] Painterro styling
Fixes #1896
Fixes #1947
- WIP
- Painterro styling overrides and config
2018-03-21 22:33:23 -07:00
Charles Hacskaylo
1670b8dc9e [Frontend] Painterro styling
Fixes #1896
Fixes #1947
- WIP
- Painterro styling overrides and config
- Removed commented code
2018-03-21 19:02:27 -07:00
Deep Tailor
f45198b91c fixes issue of overlay not closing when context menu item in clicked when viewing snapshot 2018-03-21 12:48:09 -07:00
Charles Hacskaylo
2a4a5e1a73 [Frontend] Snapshot styling
Fixes #1896
Fixes #1947
- Final tweaks after rebase from
notebook-integration-deep-styling
2018-03-21 11:29:39 -07:00
Charles Hacskaylo
3496a83474 Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-03-21 11:26:08 -07:00
Pete Richards
d8b07ac8ff Lock filesaver version (#1956)
Lock filesaver version as there have been a large number of broken
builds from what should be non-breaking version increases.

Fixes currently broken build.
2018-03-21 11:25:37 -07:00
Henry
f3a8c64af3 Updated version number for Enterprise release 2018-03-21 11:25:37 -07:00
Henry
0ee35f3f54 Removed snapshot from version number to close sprint eagle 2018-03-21 11:25:37 -07:00
Charles Hacskaylo
257e2dd67e [Frontend] WIP Snapshot styling
Fixes #1896
Fixes #1947
- Significant markup changes to ViewSnaphot.js;
- Change in imagery.scss to move non-layout styling
to appropriate class;
2018-03-21 11:01:30 -07:00
Charles Hacskaylo
8bfebc11e6 [Frontend] WIP Snapshot styling
Fixes #1896
Fixes #1947
- Significant markup changes to template in ViewSnaphot.js
- WIP!!! Keeping own topic branch for now
2018-03-20 18:01:47 -07:00
Deep Tailor
832572052d Merge branch 'master' of https://github.com/nasa/openmct into notebook-integration-deep 2018-03-19 14:53:33 -07:00
Deep Tailor
bdcc058dc1 change snapshot library to dom-to-image 2018-03-19 13:57:00 -07:00
Deep Tailor
5d55f43d22 user findElementById in entrydnd 2018-03-19 12:24:38 -07:00
Deep Tailor
05fdfcf8e0 abstract findElementById for reusability and improve performance from O^2 to O 2018-03-19 10:34:39 -07:00
Deep Tailor
b93c1757e4 fix focus one new entry issue, cleanup of code related to finding elements, and write more reusable code 2018-03-16 11:59:42 -07:00
Deep Tailor
6c9efcdfb9 fix (not being able to focus on content editable div to add text, while in layout)
- when in layout, the first child of the outermost div is the only one that registers a click, this was causing an issue of not being able to edit notebook entries. My fix includes finding the first child of the div that registers the click and forcing a focus event.
2018-03-15 13:40:24 -07:00
Deep Tailor
d689b7aac5 fix layout display overload, remove viewpolicy and notebookLayout.html. Fix delete error - issues found when deploying for testathon 2018-03-14 14:01:35 -07:00
Deep Tailor
7a5a3b0cf0 disable view policy - to allow layouts to function - needs more investigation 2018-03-13 11:10:44 -07:00
Henry
49759a39b8 Inlined templates for notebook 2018-03-12 18:27:09 -07:00
Deep Tailor
cc50186700 include painterro in karma config 2018-03-09 16:34:45 -08:00
Deep Tailor
1bd4fe0de2 fix export image after merging with master 2018-03-09 16:21:40 -08:00
Deep Tailor
f44bf30b02 merge master 2018-03-09 16:09:12 -08:00
Deep Tailor
166cc0421d add comments, clean out some code, and fix broken tests 2018-03-08 13:13:49 -08:00
Deep Tailor
4b13d0374b fix issue of preserving line breaks when text is received from a persisted source 2018-03-08 10:57:41 -08:00
Deep Tailor
02b1ec1343 remove frame layout duplicate and use frame.html 2018-02-26 14:43:24 -08:00
Charles Hacskaylo
ad1b2681d2 [Frontend] WIP Snapshot styling
Fixes #1896
- Better class names;
- Moved buttons in frame layout;
2018-02-22 18:17:45 -08:00
Charles Hacskaylo
9751236da5 Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-02-22 16:04:18 -08:00
Deep Tailor
db14b806d1 prevent multiple new notebook entry divs from being created on open overlay, instead create on initialization 2018-02-22 15:47:27 -08:00
Charles Hacskaylo
18bae253bd Merge branch 'notebook-integration-deep' of https://github.com/nasa/openmct into notebook-integration-deep 2018-02-22 15:45:34 -08:00
Charles Hacskaylo
43c9804326 [Frontend] WIP Mobile styling
Fixes #1896
- Fixed general approach to portrait orientation in
mobile/_layout.scss to use media query;
- Fixed portrait layout in _notebook_base.scss
to use media query;
2018-02-22 15:45:13 -08:00
Deep Tailor
63bc8178a9 remove duplicate code from MCTModalNotebook and roll changes into MCTTriggerModal 2018-02-22 15:38:38 -08:00
Charles Hacskaylo
3fbb1833bf [Frontend] Fix custom Selects
Fixes #1896
- Custom Selects now much more
solid, handle width compression better;
2018-02-22 14:36:29 -08:00
Charles Hacskaylo
50420a5eff [Frontend] Fixes to search control
Fixes #1896
- Search control now more robust, added
.search-filter-by-type class selector;
2018-02-22 14:35:48 -08:00
Deep Tailor
ab748026ab fix expand in layout, which was causing snapshot at expand 2018-02-22 13:28:21 -08:00
Charles Hacskaylo
f34bb48398 [Frontend] WIP Mobile styling
Fixes #1896
- phone portrait entry layout optimization
2018-02-21 19:02:38 -08:00
Charles Hacskaylo
c47defd6bc [Frontend] Mobile styling
Fixes #1896
- Mod .has-local-controls to not apply when in touch context
2018-02-21 18:31:33 -08:00
Charles Hacskaylo
3d926f2ff7 [Frontend] CSS sanding and cleanups
Fixes #1896
- Removing unused classes;
- Finessed margin and padding;
2018-02-21 18:30:35 -08:00
Deep Tailor
f653ff4890 added modifiedOn time for entries that are changed, and fixed issue regarding inner text being filled when new entry button clicked 2018-02-14 12:29:11 -08:00
Charles Hacskaylo
b8e8ca8332 [Frontend] CSS normalizing, apply general styles in markup
Fixes #1896
- Notebook class names more individualized;
- Apply .labeled and .has-local-controls general classes;
- Apply .s-input-inline to contenteditable div;
- Look and feel cleanups for drag area and entry elements;
2018-02-13 19:05:12 -08:00
Charles Hacskaylo
4eebec5c13 [Merge] Generalized labeled icon-* elements
Fixes #1896
2018-02-13 19:02:29 -08:00
Charles Hacskaylo
09ef7d8d38 [Merge] Generalized hover hide/show of local controls
Fixes #1896
2018-02-13 19:01:45 -08:00
Charles Hacskaylo
d430f3e621 [Front-end] Refined styling of entry embeds
Fixes #1896
2018-02-09 16:57:47 -08:00
Deep Tailor
585f05d576 fix drag and drop, delete entries 2018-02-08 11:56:32 -08:00
Deep Tailor
54fe6d0e59 Merge branch 'notebook-integration-1896-styling' of https://github.com/nasa/openmct into notebook-integration-deep 2018-02-07 11:48:28 -08:00
Charles Hacskaylo
ab95f947e8 [Merge] WIP Mods related to MCTModalNotebook.js
Fixes #1896
Fixes #1906
2018-02-06 19:05:23 -08:00
Charles Hacskaylo
179e69867b [Merge] WIP SCSS and markup polishing
Fixes #1896
- Significant style and markup changes;
- Styles, layout, etc. relating to embed elements;
- Fixes in both notebook.html and embedControl.html;
- Class name normalization;
2018-02-06 18:15:54 -08:00
Charles Hacskaylo
b2fb958a77 [Merge] Cleanups in JS
Fixes #1896
- Removed and commented out logging statements
2018-02-06 18:12:53 -08:00
Charles Hacskaylo
3ee6a04db0 [Front-end] Notebook thematic styling; test console
Fixes #1896
- Added thematic styles and config;
- Really, really, really WIP!!
- DnD doesn't work properly, and drag to
existing entry no longer works.
2018-02-05 15:54:06 -08:00
Deep Tailor
cca8b558bd Merge branch 'master' of https://github.com/nasa/openmct into notebook-integration-deep 2018-02-05 11:54:10 -08:00
Charles Hacskaylo
59fd3415d6 [Merge] JS debugging
Fixes #1896
- Really, really WIP
- DnD doesn't work properly, and drag to
existing entry no longer works.
2018-02-02 17:08:58 -08:00
Charles Hacskaylo
8aeef6ae37 [Merge] JS debugging
Fixes #1896
- Very much WIP!
2018-02-02 14:30:23 -08:00
Charles Hacskaylo
0543aa9521 [Merge] WIP markup and styling
Fixes #1896
- Very much WIP, attempting to convert
textarea to contenteditable;
2018-01-31 19:42:42 -08:00
Charles Hacskaylo
78ae568302 [Merge] WIP markup and styling
Fixes #1896
- Very much WIP, currently having issues with
hovering and jiggling
2018-01-30 18:46:42 -08:00
Victor Woeltjen
fad3afbd3c [Notebook] Fix require config for painterro 2018-01-30 15:46:47 -08:00
Victor Woeltjen
6f975c2d9d [Notebook] Include painterro for tests 2018-01-30 15:42:45 -08:00
Victor Woeltjen
9fd397b34e [Notebook] Run gulp fixstyle 2018-01-30 15:36:35 -08:00
Victor Woeltjen
cbddfac96f [Notebook] Fix lint issues 2018-01-30 15:31:42 -08:00
Victor Woeltjen
b5153b0f27 [Notebook] Fix lint issues 2018-01-30 15:28:23 -08:00
Victor Woeltjen
b766a22034 [Notebook] Fix lint issues 2018-01-30 15:26:35 -08:00
Victor Woeltjen
4bde1c1ab8 [Notebook] Fix lint issues 2018-01-30 15:18:47 -08:00
Victor Woeltjen
1d314a91e0 [Notebook] Fix lint issues 2018-01-30 15:17:51 -08:00
Victor Woeltjen
e370fbd6c5 [Notebook] Fix lint issues 2018-01-30 15:14:26 -08:00
Victor Woeltjen
25cce4dd0d [Notebook] Fix lint issues 2018-01-30 15:13:01 -08:00
Victor Woeltjen
78dd80d081 [Notebook] Fix lint issues 2018-01-30 15:10:16 -08:00
Victor Woeltjen
944fb5e53a [Notebook] Fix lint issues 2018-01-30 15:08:58 -08:00
Victor Woeltjen
ac7ea7ba44 [Notebook] Use dot notation instead of brackets
...for checkstyle
2018-01-30 15:05:31 -08:00
Victor Woeltjen
5d34628dd8 [Notebook] Run gulp fixstyle 2018-01-30 15:04:47 -08:00
Victor Woeltjen
c3a2ac3dd5 [Notebook] Remove extra comma 2018-01-30 15:04:25 -08:00
Victor Woeltjen
62ebcd7277 [Notebook] Use dot notation instead of brackets
...for checkstyle
2018-01-30 15:01:27 -08:00
Victor Woeltjen
79a5e479cb [Notebook] Run gulp fixstyle 2018-01-30 15:00:06 -08:00
Victor Woeltjen
d9b66e23aa [Notebook] Remove demo entries 2018-01-30 14:59:03 -08:00
Victor Woeltjen
f1c3a56147 [Notebook] Expose via openmct.plugins 2018-01-30 14:58:34 -08:00
Victor Woeltjen
02e5defbdc [Notebook] Restore original index.html 2018-01-30 14:54:08 -08:00
Victor Woeltjen
9897883335 [Notebook] Remove obsolete README 2018-01-30 14:53:47 -08:00
Victor Woeltjen
c15bb45411 [Notebook] Relocate to platform/features/notebook 2018-01-30 14:49:44 -08:00
Victor Woeltjen
a085b2a7b8 Merge remote-tracking branch 'origin/master' into notebook-integration-1896
Fixes #1896
2018-01-30 14:41:31 -08:00
lunarkid
3366f21155 Merge pull request #37 from cristianmusic7/master
Naming conventions fixes
2017-12-28 12:16:27 +07:00
Cristian Franco
45d5b0752b filenames fix 2017-12-28 00:08:10 -05:00
Cristian Franco
07d7f8fd5f names and package fixes 2017-12-28 00:03:49 -05:00
lunarkid
2b7b4a552c Merge pull request #36 from cristianmusic7/master
Code issues fixed
2017-12-27 15:11:03 +07:00
Cristian Franco
3f9bad1805 Code issues fixes:
NotificationLaunchIndicator deleted.
Inappropriate modifications to domain object models fixed.
Implemented $destroy listener on entryDnd directive.
Naming conventions fixed.
Unnecessary changes made to platform handled.
Painterro dependency handled
gulp verify fix.
2017-12-27 00:26:27 -05:00
lunarkid
fec1d38f7e Merge pull request #28 from cristianmusic7/master
Test case functional and cosmetic issues fixed.
2017-12-18 10:31:31 +07:00
Cristian Franco
499655def2 updated file saver library 2017-12-17 22:09:34 -05:00
Cristian Franco
d5985b844c Merge branch 'master' of https://github.com/cristianmusic7/openmct 2017-12-15 23:56:37 -05:00
Cristian Franco
59bb5d3d55 Test cases functional and cosmetic issues fixed. 2017-12-15 23:53:14 -05:00
Cristian Franco
5b298525e3 Test case functional and cosmetic issues fixed. 2017-12-15 23:41:10 -05:00
lunarkid
1540fbcf54 Merge pull request #27 from cristianmusic7/master
CouchDB setup documentation added.
2017-11-13 14:15:26 +07:00
cristianmusic7
b15f193f5d CouchDB setup documentation added 2017-11-11 01:48:00 -05:00
cristianmusic7
bdf856526b CouchDB documentation added
Screenshots added.
2017-11-11 01:43:43 -05:00
Cristian Franco
9aafb5cbf9 CouchDB documentation added 2017-11-11 01:27:19 -05:00
lunarkid
2ccf3f0fb1 Merge pull request #26 from cristianmusic7/master
NASA review fixes:
2017-11-09 14:38:22 +07:00
Cristian Franco
46d7c117cb NASA review fixes:
css files adjusted
notebook children tree removed
embed's title links to live object
2017-11-09 01:47:01 -05:00
lunarkid
60168ea87b Merge pull request #24 from cristianmusic7/master
Painterro .map file issue fix
2017-10-26 23:52:46 +07:00
Cristian Franco
5ba3afb1a8 painterro .map file issue fixed. 2017-10-26 11:48:44 -05:00
lunarkid
3974991cfd Merge pull request #23 from cristianmusic7/master
Annotation toolbar UI style fixes, added annotation functionality on new entry dialog
2017-10-21 13:28:18 +07:00
Cristian Franco
39c5b1bbfd Annotation toolbar UI style fixes, added annotation functionality on new entry dialog 2017-10-21 01:22:48 -05:00
lunarkid
c82563c80f Merge pull request #22 from cristianmusic7/master
NASA reported issues fixed.
2017-10-20 08:11:30 +07:00
Cristian Franco
01fda1adfc NASA reported issues fixed:
objects saved in notebook, delete entry dialog, style files, and new entry from drag objects fixed.
2017-10-19 18:20:43 -05:00
lunarkid
bf5ed84f94 Merge pull request #19 from cristianmusic7/master
drag and drop style, new entry focus and delete display fixes
2017-10-15 16:45:43 +07:00
Cristian Franco
7c34f03a95 drag and drop style fix, new entry focus, delete display fix 2017-10-15 03:08:27 -05:00
lunarkid
3cf1ad8e40 Merge pull request #18 from cristianmusic7/master
Code updates, review fixes
2017-10-14 15:58:44 +07:00
Cristian Franco
3fab80c276 Code updates:
-Topcoder final fixes
-NASA review fixes
2017-10-14 02:52:07 -05:00
lunarkid
194dc43e24 Merge pull request #2 from cristianmusic7/master
Initial submission
2017-10-11 17:15:30 +07:00
Cristian Franco
16e0eeff67 NASA - OPEN MCT NOTEBOOK UI PROTOTYPE CHALLENGE
https://www.topcoder.com/challenge-details/30059614/
Initial submission
2017-10-11 02:51:39 -05:00
lunarkid
37be478a08 Merge pull request #1 from nasa/master
Add Notebook icon (#1742)
2017-10-10 11:34:53 +07:00
1088 changed files with 55123 additions and 37681 deletions

View File

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

View File

@@ -1,79 +0,0 @@
module.exports = {
"env": {
"browser": true,
"es6": true,
"jasmine": true,
"amd": true
},
"extends": "eslint:recommended",
"parser": "babel-eslint",
"parserOptions": {
"allowImportExportEverywhere": true,
"ecmaVersion": 2015,
"ecmaFeatures": {
"impliedStrict": true
}
},
"rules": {
"no-bitwise": "error",
"curly": "error",
"eqeqeq": "error",
"guard-for-in": "error",
"no-extend-native": "error",
"no-inner-declarations": "off",
"no-use-before-define": ["error", "nofunc"],
"no-caller": "error",
"no-sequences": "error",
"no-irregular-whitespace": "error",
"no-new": "error",
"no-shadow": "error",
"no-undef": "error",
"no-unused-vars": [
"error",
{
"vars": "all",
"args": "none"
}
],
"no-console": "off",
"no-trailing-spaces": "error",
"space-before-function-paren": [
"error",
{
"anonymous": "always",
"asyncArrow": "always",
"named": "never",
}
],
"array-bracket-spacing": "error",
"space-in-parens": "error",
"space-before-blocks": "error",
"comma-dangle": "error",
"eol-last": "error",
"new-cap": [
"error",
{
"capIsNew": false,
"properties": false
}
],
"dot-notation": "error",
"indent": ["error", 4]
},
"overrides": [
{
"files": ["*Spec.js"],
"rules": {
"no-unused-vars": [
"warn",
{
"vars": "all",
"args": "none",
"varsIgnorePattern": "controller",
}
]
}
}
]
};

5
.jscsrc Normal file
View File

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

26
.jshintrc Normal file
View File

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

88
API.md
View File

@@ -37,7 +37,7 @@
- [Time Systems and Bounds](#time-systems-and-bounds)
- [Defining and Registering Time Systems](#defining-and-registering-time-systems)
- [Getting and Setting the Active Time System](#getting-and-setting-the-active-time-system)
- [Time Bounds](#time-bounds)
- [Time Bounds](#time-bounds)
- [Clocks](#clocks)
- [Defining and registering clocks](#defining-and-registering-clocks)
- [Getting and setting active clock](#getting-and-setting-active-clock)
@@ -48,10 +48,6 @@
- [The Time Conductor](#the-time-conductor)
- [Time Conductor Configuration](#time-conductor-configuration)
- [Example conductor configuration](#example-conductor-configuration)
- [Indicators](#indicators)
- [The URL Status Indicator](#the-url-status-indicator)
- [Creating a Simple Indicator](#creating-a-simple-indicator)
- [Custom Indicators](#custom-indicators)
- [Included Plugins](#included-plugins)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
@@ -692,7 +688,7 @@ openmct.time.timeSystem(utcTimeSystem, bounds);
Setting the active time system will trigger a [`'timeSystem'`](#time-events)
event. If you supplied bounds, a [`'bounds'`](#time-events) event will be triggered afterwards with your newly supplied bounds.
#### Time Bounds
### Time Bounds
The TimeAPI provides a getter/setter for querying and setting time bounds. Time
bounds are simply an object with a `start` and an end `end` attribute.
@@ -981,72 +977,6 @@ openmct.install(openmct.plugins.Conductor({
}));
```
## Indicators
Indicators are small widgets that reside at the bottom of the screen and are visible from
every screen in Open MCT. They can be used to convey system state using an icon and text.
Typically an indicator will display an icon (customizable with a CSS class) that will
reveal additional information when the mouse cursor is hovered over it.
### The URL Status Indicator
A common use case for indicators is to convey the state of some external system such as a
persistence backend or HTTP server. So long as this system is accessible via HTTP request,
Open MCT provides a general purpose indicator to show whether the server is available and
returing a 2xx status code. The URL Status Indicator is made available as a default plugin. See
[Included Plugins](#included-plugins) below for details on how to install and configure the
URL Status Indicator.
### Creating a Simple Indicator
A simple indicator with an icon and some text can be created and added with minimal code. An indicator
of this type exposes functions for customizing the text, icon, and style of the indicator.
eg.
``` javascript
var myIndicator = openmct.indicators.simpleIndicator();
myIndicator.text("Hello World!");
openmct.indicators.add(myIndicator);
```
This will create a new indicator and add it to the bottom of the screen in Open MCT.
By default, the indicator will appear as an information icon. Hovering over the icon will
reveal the text set via the call to `.text()`. The Indicator object returned by the API
call exposes a number of functions for customizing the content and appearance of the indicator:
* `.text([text])`: Gets or sets the text shown when the user hovers over the indicator.
Accepts an __optional__ `string` argument that, if provided, will be used to set the text.
Hovering over the indicator will expand it to its full size, revealing this text alongside
the icon. Returns the currently set text as a `string`.
* `.description([description])`: Gets or sets the indicator's description. Accepts an
__optional__ `string` argument that, if provided, will be used to set the text. The description
allows for more detail to be provided in a tooltip when the user hovers over the indicator.
Returns the currently set text as a `string`.
* `.iconClass([className])`: Gets or sets the CSS class used to define the icon. Accepts an __optional__
`string` parameter to be used to set the class applied to the indicator. Any of
[the built-in glyphs](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home/glyphs?view=styleguide.glyphs)
may be used here, or a custom CSS class can be provided. Returns the currently defined CSS
class as a `string`.
* `.statusClass([className])`: Gets or sets the CSS class used to determine status. Accepts an __optional __
`string` parameter to be used to set a status class applied to the indicator. May be used to apply
different colors to indicate status.
### Custom Indicators
A completely custom indicator can be added by simple providing a DOM element to place alongside other indicators.
``` javascript
var domNode = document.createElement('div');
domNode.innerText = new Date().toString();
setInterval(function () {
domNode.innerText = new Date().toString();
}, 1000);
openmct.indicators.add({
element: domNode
});
```
## Included Plugins
Open MCT is packaged along with a few general-purpose plugins:
@@ -1070,18 +1000,18 @@ openmct.install(openmct.plugins.CouchDB('http://localhost:9200'))
* `openmct.plugins.Espresso` and `openmct.plugins.Snow` are two different
themes (dark and light) available for Open MCT. Note that at least one
of these themes must be installed for Open MCT to appear correctly.
* `openmct.plugins.URLIndicator` adds an indicator which shows the
* `openmct.plugins.URLIndicatorPlugin` adds an indicator which shows the
availability of a URL with the following options:
- `url` : URL to indicate the status of
- `iconClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items)
- `cssClass`: Icon to show in the status bar, defaults to `icon-database`, [list of all icons](https://nasa.github.io/openmct/style-guide/#/browse/styleguide:home?view=items)
- `interval`: Interval between checking the connection, defaults to `10000`
- `label` Name showing up as text in the status bar, defaults to url
```javascript
openmct.install(openmct.plugins.URLIndicator({
url: 'http://localhost:8080',
iconClass: 'check',
interval: 10000,
label: 'Localhost'
openmct.install(openmct.plugins.URLIndicatorPlugin({
url: 'http://google.com',
cssClass: 'check',
interval: 10000,
label: 'Google'
})
);
```

View File

@@ -84,6 +84,7 @@ Documentation will be generated in `target/docs`.
## Deploying Open MCT
Open MCT is built using [`npm`](http://npmjs.com/)
and [`gulp`](http://gulpjs.com/).
To build Open MCT for deployment:
@@ -93,13 +94,32 @@ This will compile and minify JavaScript sources, as well as copy over assets.
The contents of the `dist` folder will contain a runnable Open MCT
instance (e.g. by starting an HTTP server in that directory), including:
* `openmct.js` - Open MCT source code.
* `openmct.css` - Basic styles to load to prevent a FOUC.
* `index.html`, an example to run Open MCT in the basic configuration.
* A `main.js` file containing Open MCT source code.
* Various assets in the `example` and `platform` directories.
* An `index.html` that runs Open MCT in its default configuration.
Additional `gulp` tasks are defined in [the gulpfile](gulpfile.js).
## Bundles
A bundle is a group of software components (including source code, declared
as AMD modules, as well as resources such as images and HTML templates)
that is intended to be added or removed as a single unit. A plug-in for
Open MCT will be expressed as a bundle; platform components are also
expressed as bundles.
A bundle is also just a directory which contains a file `bundle.json`,
which declares its contents.
The file `bundles.json` (note the plural), at the top level of the
repository, is a JSON file containing an array of all bundles (expressed as
directory names) to include in a running instance of Open MCT. Adding or
removing paths from this list will add or remove bundles from the running
application.
## Tests
Tests are written for [Jasmine 3](http://jasmine.github.io/)
Tests are written for [Jasmine 1.3](http://jasmine.github.io/1.3/introduction.html)
and run by [Karma](http://karma-runner.github.io). To run:
`npm test`

128
app.js
View File

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

28
bower.json Normal file
View File

@@ -0,0 +1,28 @@
{
"name": "openmct",
"description": "The Open MCT core platform",
"main": "",
"license": "Apache-2.0",
"moduleType": [],
"homepage": "http://nasa.github.io/openmct/",
"private": true,
"dependencies": {
"angular": "1.4.4",
"angular-route": "1.4.4",
"moment": "^2.11.1",
"moment-duration-format": "^1.3.0",
"requirejs": "~2.1.22",
"text": "requirejs-text#^2.0.14",
"es6-promise": "^3.3.0",
"screenfull": "^3.0.0",
"node-uuid": "^1.4.7",
"comma-separated-values": "^3.6.4",
"file-saver": "1.3.3",
"zepto": "^1.1.6",
"eventemitter3": "^1.2.0",
"lodash": "3.10.1",
"almond": "~0.3.2",
"html2canvas": "^0.4.1",
"moment-timezone": "^0.5.13"
}
}

27
circle.yml Normal file
View File

@@ -0,0 +1,27 @@
machine:
node:
version: 8.11.0
dependencies:
pre:
- npm install -g npm@latest
deployment:
production:
branch: master
commands:
- npm install canvas nomnoml
- ./build-docs.sh
openmctweb-staging-deux:
branch: mobile
heroku:
appname: openmctweb-staging-deux
test:
post:
- gulp lint
- gulp checkstyle
general:
branches:
ignore:
- gh-pages

View File

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

View File

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

View File

@@ -0,0 +1,74 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define*/
define([
"./src/ExampleController",
"./src/ExampleDirective",
"./src/ExampleService",
'legacyRegistry'
], function (
ExampleController,
ExampleDirective,
ExampleService,
legacyRegistry
) {
"use strict";
legacyRegistry.register("example/builtins", {
"name": "Angular Built-ins Example",
"description": "Example showing how to declare extensions with built-in support from Angular.",
"sources": "src",
"extensions": {
"controllers": [
{
"key": "ExampleController",
"implementation": ExampleController,
"depends": [
"$scope",
"exampleService"
]
}
],
"directives": [
{
"key": "exampleDirective",
"implementation": ExampleDirective,
"depends": [
"examples[]"
]
}
],
"routes": [
{
"templateUrl": "templates/example.html"
}
],
"services": [
{
"key": "exampleService",
"implementation": ExampleService
}
]
}
});
});

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -19,22 +19,28 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global define,Promise*/
/**
* Module defining ExampleService. Created by vwoeltje on 11/4/14.
*/
define(
[],
function () {
function MCTIndicators(openmct) {
"use strict";
/**
*
* @constructor
*/
function ExampleService() {
return {
restrict: "E",
link: function link(scope, element) {
openmct.indicators.indicatorElements
.forEach(function (indicatorElement) {
element.append(indicatorElement);
});
getMessage: function () {
return "I heard this from a service";
}
};
}
return MCTIndicators;
return ExampleService;
}
);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -49,7 +49,7 @@ define([
{
"key": "eventGenerator",
"name": "Event Message Generator",
"cssClass": "icon-generator-events",
"cssClass": "icon-folder-new",
"description": "For development use. Creates sample event message data that mimics a live data stream.",
"priority": 10,
"features": "creation",
@@ -60,8 +60,8 @@ define([
"source": "eventGenerator",
"domains": [
{
"key": "utc",
"name": "Timestamp",
"key": "time",
"name": "Time",
"format": "utc"
}
],

View File

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

View File

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

View File

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

View File

@@ -30,7 +30,6 @@ define([
{
key: "sin",
name: "Sine",
formatString: '%0.2f',
hints: {
range: 1
}
@@ -38,7 +37,6 @@ define([
{
key: "cos",
name: "Cosine",
formatString: '%0.2f',
hints: {
range: 2
}

View File

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

View File

@@ -72,7 +72,7 @@ define([
var data = [];
while (start <= end && data.length < 5000) {
data.push(pointForTimestamp(start, duration, domainObject.name));
start += duration;
start += 5000;
}
return Promise.resolve(data);
};

View File

@@ -21,7 +21,7 @@
*****************************************************************************/
define([
'raw-loader!./generatorWorker.js',
'text!./generatorWorker.js',
'uuid'
], function (
workerText,

View File

@@ -38,19 +38,20 @@ define([
openmct.types.addType("example.state-generator", {
name: "State Generator",
description: "For development use. Generates test enumerated telemetry by cycling through a given set of states",
cssClass: "icon-generator-telemetry",
cssClass: "icon-telemetry",
creatable: true,
form: [
{
name: "State Duration (seconds)",
control: "numberfield",
control: "textfield",
cssClass: "l-input-sm l-numeric",
key: "duration",
required: true,
property: [
"telemetry",
"duration"
]
],
pattern: "^\\d*(\\.\\d*)?$"
}
],
initialize: function (object) {
@@ -65,7 +66,7 @@ define([
openmct.types.addType("generator", {
name: "Sine Wave Generator",
description: "For development use. Generates example streaming telemetry data using a simple sine wave algorithm.",
cssClass: "icon-generator-telemetry",
cssClass: "icon-telemetry",
creatable: true,
form: [
{

View File

@@ -38,8 +38,7 @@ define([
"provides": "identityService",
"type": "provider",
"depends": [
"dialogService",
"$q"
"dialogService"
]
}
]

View File

@@ -55,37 +55,21 @@ define(
* @implements {IdentityService}
* @memberof platform/identity
*/
function ExampleIdentityProvider(dialogService, $q) {
this.dialogService = dialogService;
this.$q = $q;
function ExampleIdentityProvider(dialogService) {
// Handle rejected dialog messages by treating the
// current user as undefined.
function echo(v) { return v; }
function giveUndefined() { return undefined; }
this.returnUser = this.returnUser.bind(this);
this.returnUndefined = this.returnUndefined.bind(this);
this.userPromise =
dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY)
.then(echo, giveUndefined);
}
ExampleIdentityProvider.prototype.getUser = function () {
if (this.user) {
return this.$q.when(this.user);
} else {
return this.dialogService.getUserInput(DIALOG_STRUCTURE, DEFAULT_IDENTITY)
.then(this.returnUser, this.returnUndefined);
}
return this.userPromise;
};
/**
* @private
*/
ExampleIdentityProvider.prototype.returnUser = function (user) {
return this.user = user;
}
/**
* @private
*/
ExampleIdentityProvider.prototype.returnUndefined = function () {
return undefined;
}
return ExampleIdentityProvider;
}
);

View File

@@ -26,16 +26,12 @@ define([
"./src/NotificationLaunchController",
"./src/DialogLaunchIndicator",
"./src/NotificationLaunchIndicator",
"./res/dialog-launch.html",
"./res/notification-launch.html",
'legacyRegistry'
], function (
DialogLaunchController,
NotificationLaunchController,
DialogLaunchIndicator,
NotificationLaunchIndicator,
DialogLaunch,
NotificationLaunch,
legacyRegistry
) {
"use strict";
@@ -45,11 +41,11 @@ define([
"templates": [
{
"key": "dialogLaunchTemplate",
"template": DialogLaunch
"templateUrl": "dialog-launch.html"
},
{
"key": "notificationLaunchTemplate",
"template": NotificationLaunch
"templateUrl": "notification-launch.html"
}
],
"controllers": [

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,26 +1,10 @@
define([
"./src/ExampleStyleGuideModelProvider",
"./src/MCTExample",
"./res/templates/intro.html",
"./res/templates/standards.html",
"./res/templates/colors.html",
"./res/templates/status.html",
"./res/templates/glyphs.html",
"./res/templates/controls.html",
"./res/templates/input.html",
"./res/templates/menus.html",
'legacyRegistry'
], function (
ExampleStyleGuideModelProvider,
MCTExample,
introTemplate,
standardsTemplate,
colorsTemplate,
statusTemplate,
glyphsTemplate,
controlsTemplate,
inputTemplate,
menusTemplate,
legacyRegistry
) {
legacyRegistry.register("example/styleguide", {
@@ -39,14 +23,14 @@ define([
{ "key": "styleguide.menus", "name": "Menus", "cssClass": "icon-page", "description": "Context menus, dropdowns" }
],
"views": [
{ "key": "styleguide.intro", "type": "styleguide.intro", "template": introTemplate, "editable": false },
{ "key": "styleguide.standards", "type": "styleguide.standards", "template": standardsTemplate, "editable": false },
{ "key": "styleguide.colors", "type": "styleguide.colors", "template": colorsTemplate, "editable": false },
{ "key": "styleguide.status", "type": "styleguide.status", "template": statusTemplate, "editable": false },
{ "key": "styleguide.glyphs", "type": "styleguide.glyphs", "template": glyphsTemplate, "editable": false },
{ "key": "styleguide.controls", "type": "styleguide.controls", "template": controlsTemplate, "editable": false },
{ "key": "styleguide.input", "type": "styleguide.input", "template": inputTemplate, "editable": false },
{ "key": "styleguide.menus", "type": "styleguide.menus", "template": menusTemplate, "editable": false }
{ "key": "styleguide.intro", "type": "styleguide.intro", "templateUrl": "templates/intro.html", "editable": false },
{ "key": "styleguide.standards", "type": "styleguide.standards", "templateUrl": "templates/standards.html", "editable": false },
{ "key": "styleguide.colors", "type": "styleguide.colors", "templateUrl": "templates/colors.html", "editable": false },
{ "key": "styleguide.status", "type": "styleguide.status", "templateUrl": "templates/status.html", "editable": false },
{ "key": "styleguide.glyphs", "type": "styleguide.glyphs", "templateUrl": "templates/glyphs.html", "editable": false },
{ "key": "styleguide.controls", "type": "styleguide.controls", "templateUrl": "templates/controls.html", "editable": false },
{ "key": "styleguide.input", "type": "styleguide.input", "templateUrl": "templates/input.html", "editable": false },
{ "key": "styleguide.menus", "type": "styleguide.menus", "templateUrl": "templates/menus.html", "editable": false }
],
"roots": [
{
@@ -101,6 +85,16 @@ define([
"$q"
]
}
],
"stylesheets": [
{
"stylesheetUrl": "css/style-guide-espresso.css",
"theme": "espresso"
},
{
"stylesheetUrl": "css/style-guide-snow.css",
"theme": "snow"
}
]
}
});

View File

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

View File

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

View File

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

View File

@@ -149,21 +149,12 @@
<h2>Local Controls</h2>
<div class="cols cols1-1">
<div class="col">
<p>Local controls are typically buttons and selects that provide actions in close proximity to a component.</p>
<p>These controls can optionally be hidden to reduce clutter until the user hovers their cursor over an enclosing element. To use this approach, apply the class <code>.has-local-controls</code> to the element that should be aware of the hover and ensure that element encloses <code>.h-local-controls</code>.</p>
<p>Local controls are typically buttons and selects that provide local control to an individual element. Typically, these controls are hidden in order to not block data display until the user hovers their cursor over an element, when the controls are displayed using a transition fade. Mousing out of the element fades the controls from view.</p>
</div>
<mct-example><div class="plot-display-area" style="padding: 10px; position: relative;">
Some content in here
<div class="h-local-controls h-local-controls-overlay-content l-btn-set">
<mct-example><div class="plot-display-area" style="height: 100px; padding: 10px; position: relative;">Hover over me
<div class="l-local-controls gl-plot-local-controls t-plot-display-controls">
<a class="s-button icon-arrow-left" title="Restore previous pan/zoom"></a>
<a class="s-button icon-reset" title="Reset pan/zoom"></a>
</div>
</div>
<div class="plot-display-area has-local-controls" style="padding: 10px; position: relative;">
Hover here
<div class="h-local-controls h-local-controls-overlay-content local-controls-hidden l-btn-set">
<a class="s-button icon-arrow-left" title="Restore previous pan/zoom"></a>
<a class="s-button icon-reset" title="Reset pan/zoom"></a>
<a class="s-button icon-arrows-out" title="Reset pan/zoom"></a>
</div>
</div></mct-example>
</div>

View File

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

View File

@@ -20,12 +20,12 @@
at runtime from the About dialog for additional information.
-->
<style>
.w-mct-example div[class*="s-status"],
.w-mct-example span[class*="s-status"],
.w-mct-example div[class*="s-limit"],
.w-mct-example div[class*="s-status"],
.w-mct-example div[class*="s-unsynced"],
.w-mct-example span[class*="s-limit"] {
border-radius: 3px;
padding: 2px 5px;
border-radius: 4px;
padding: 3px 7px;
}
.w-mct-example table {
width: 100%;
@@ -36,12 +36,65 @@
<h1>Status Indication</h1>
<div class="l-section">
<h2>Status Classes</h2>
<h2>Overview</h2>
<p>Many elements in Open MCT need to articulate a dynamic status; Open MCT provides the following styles and conventions to handle this:</p>
<ul>
<li><strong>Limits</strong>: when telemetry values exceed minimum or maximum values, they can be violating limits. Limit styles include both color and iconography; color is used to indicate severity while icons are used to indicate direction, upper or lower.</li>
<li><strong>Status</strong>: Open MCT also provides a number or built-in Status styles allowing telemetry or other displayed information to be visually classified by type. Common uses for these classes are to visually denote event records.</li>
<li><strong>Synchronization</strong>: When the system is displaying real-time data, it is very important that displays clearly indicate when they are not doing so, such as when a plot if frozen while panning or zooming. Open MCT provides a style for this.</li>
</ul>
</div>
<div class="l-section">
<h2>Limits</h2>
<div class="cols cols1-1">
<div class="col">
<p>Status classes allow any block or inline-block element to be decorated in order to articulate a
status. Provided classes include color-only and color plus icon; custom icons can easily be
employed by using a color-only status class in combination with an <a class="link" href="#/browse/styleguide:home/glyphs?tc.mode=local&tc.timeSystem=utc&tc.startDelta=1800000&tc.endDelta=0&view=styleguide.glyphs">glyph</a>.</p>
<p>Limit CSS classes can be applied to any block or inline element. Open MCT limit classes set color and optionally an icon, but don't effect other properties. Yellow and red limit classes can be used as is, or allow the application of any custom icon available in Open MCT's glyphs library. &quot;Level&quot; limit classes - upper and lower - always use an icon in addition to a color; Open MCT doesn't support level limits without color.</p>
<ul>
<li>Color only</li>
<ul>
<li><code>s-limit-yellow</code>: A yellow limit.</li>
<li><code>s-limit-red</code>: A red limit.</li>
</ul>
<li>Color and icon</li>
<ul>
<li><code>s-limit-yellow-icon</code>: A yellow limit with icon.</li>
<li><code>s-limit-red-icon</code>: A red limit with icon.</li>
</ul>
<li>Upper and lower limit indicators. Must be used with a color limit class to be visible.</li>
<ul>
<li><code>s-limit-upr</code>: Upper limit.
</li>
<li><code>s-limit-lwr</code>: Lower limit.
</li>
</ul>
</ul>
</div>
<mct-example><div class="s-limit-yellow">Yellow limit</div>
<div class="s-limit-red">Red limit</div>
<div class="s-limit-yellow-icon">Yellow limit with icon</div>
<div class="s-limit-red-icon">Red limit with icon</div>
<div class="s-limit-yellow s-limit-lwr">Lower yellow limit</div>
<div class="s-limit-red s-limit-upr">Upper red limit</div>
<div class="s-limit-red icon-bell">Red Limit with a custom icon</div>
<div>Some text with an <span class="s-limit-yellow-icon">inline element</span> showing a yellow limit.</div>
<!-- Limits applied in a table -->
<table>
<tr class='header'><td>Name</td><td>Value 1</td><td>Value 2</td></tr>
<tr><td>ENG_PWR 4991</td><td>7.023</td><td class="s-limit-yellow s-limit-upr">70.23</td></tr>
<tr><td>ENG_PWR 4992</td><td>49.784</td><td class="s-limit-red s-limit-lwr">-121.22</td></tr>
<tr><td>ENG_PWR 4993</td><td class="s-limit-yellow icon-bell">0.451</td><td>1.007</td></tr>
</table>
</mct-example>
</div>
</div>
<div class="l-section">
<h2>Status</h2>
<div class="cols cols1-1">
<div class="col">
<p>Classes here can be applied to elements as needed.</p>
<ul>
<li>Color only</li>
<ul>
@@ -53,175 +106,37 @@
</ul>
<li>Color and icon</li>
<ul>
<li><code>s-status-icon-warning-hi</code></li>
<li><code>s-status-icon-warning-lo</code></li>
<li><code>s-status-icon-diagnostic</code></li>
<li><code>s-status-icon-info</code></li>
<li><code>s-status-icon-ok</code></li>
<li><code>s-status-warning-hi-icon</code></li>
<li><code>s-status-warning-lo-icon</code></li>
<li><code>s-status-diagnostic-icon</code></li>
<li><code>s-status-info-icon</code></li>
<li><code>s-status-ok-icon</code></li>
</ul>
</ul>
</div>
<mct-example><!-- Color alone examples -->
<div class="s-status-warning-hi">WARNING HI</div>
<mct-example><div class="s-status-warning-hi">WARNING HI</div>
<div class="s-status-warning-lo">WARNING LOW</div>
<div class="s-status-diagnostic">DIAGNOSTIC</div>
<div class="s-status-info">INFO</div>
<div class="s-status-ok">OK</div>
<!-- Color and icon examples -->
<div class="s-status-icon-warning-hi">WARNING HI with icon</div>
<div class="s-status-icon-warning-lo">WARNING LOW with icon</div>
<div class="s-status-icon-diagnostic">DIAGNOSTIC with icon</div>
<div class="s-status-icon-info">INFO with icon</div>
<div class="s-status-icon-ok">OK with icon</div>
<div class="s-status-warning-hi icon-alert-triangle">WARNING HI with custom icon</div>
<div>Some text with an <span class="s-status-icon-diagnostic">inline element</span> showing a Diagnostic status.</div>
<div class="s-status-warning-hi-icon">WARNING HI with icon</div>
<div class="s-status-warning-lo-icon">WARNING LOW with icon</div>
<div class="s-status-diagnostic-icon">DIAGNOSTIC with icon</div>
<div class="s-status-info-icon">INFO with icon</div>
<div class="s-status-ok-icon">OK with icon</div>
<div class="s-status-warning-hi icon-gear">WARNING HI with custom icon</div>
</mct-example>
</div>
</div>
<div class="l-section">
<h2>Limit Classes</h2>
<h2>Synchronization</h2>
<div class="cols cols1-1">
<div class="col">
<p>Limit classes are a specialized form of status, specifically meant to be applied to telemetry
displays to indicate that a limit threshold has been violated. Open MCT provides both severity
and direction classes; severity (yellow and red) can be used alone or in combination
with direction (upper or lower). Direction classes cannot be used on their own.</p>
<p>Like Status classes, Limits can be used as color-only, or color plus icon. Custom icons can
be applied in the same fashion as described above.</p>
<ul>
<li>Severity color alone</li>
<ul>
<li><code>s-limit-yellow</code>: A yellow limit.</li>
<li><code>s-limit-red</code>: A red limit.</li>
</ul>
<li>Severity color and icon</li>
<ul>
<li><code>s-limit-icon-yellow</code>: A yellow limit with icon.</li>
<li><code>s-limit-icon-red</code>: A red limit with icon.</li>
</ul>
<li>Direction indicators. MUST be used with a &quot;color alone&quot; limit class. See
examples for more.</li>
<ul>
<li><code>s-limit-upr</code>: Upper limit.</li>
<li><code>s-limit-lwr</code>: Lower limit.</li>
</ul>
</ul>
<p>When the system is operating in real-time streaming mode, it is important for views that display real-time data to clearly articulate when they are not, such as when a user zooms or pans a plot view, freezing that view. In that case, the CSS class <code>s-unsynced</code> should be applied to that view.</p>
</div>
<mct-example><!-- Color alone examples -->
<div class="s-limit-yellow">Yellow limit</div>
<div class="s-limit-red">Red limit</div>
<!-- Color and icon examples -->
<div class="s-limit-icon-yellow">Yellow limit with icon</div>
<div class="s-limit-icon-red">Red limit with icon</div>
<div class="s-limit-red icon-alert-rect">Red Limit with a custom icon</div>
<div>Some text with an <span class="s-limit-icon-yellow">inline element</span> showing a yellow limit.</div>
<!-- Severity and direction examples -->
<div class="s-limit-yellow s-limit-lwr">Lower yellow limit</div>
<div class="s-limit-red s-limit-upr">Upper red limit</div>
<!-- Limits applied in a table -->
<table>
<tr class='header'><td>Name</td><td>Value 1</td><td>Value 2</td></tr>
<tr><td>ENG_PWR 4991</td><td>7.023</td><td class="s-limit-yellow s-limit-upr">70.23</td></tr>
<tr><td>ENG_PWR 4992</td><td>49.784</td><td class="s-limit-red s-limit-lwr">-121.22</td></tr>
<tr><td>ENG_PWR 4993</td><td class="s-limit-yellow icon-alert-triangle">0.451</td><td>1.007</td></tr>
</table>
<mct-example><div class="s-unsynced">This element is unsynced</div>
</mct-example>
</div>
</div>
<div class="l-section">
<h2>Status Bar Indicators</h2>
<div class="cols cols1-1">
<div class="col">
<p>Indicators are small iconic notification elements that appear in the Status Bar area of
the application at the window's bottom. Indicators should be used to articulate the state of a
system and optionally provide gestures related to that system. They use a combination of icon and
color to identify themselves and articulate a state respectively.</p>
<h3>Recommendations</h3>
<ul>
<li><strong>Keep the icon consistent</strong>. The icon is the principal identifier of the system and is a valuable
recall aid for the user. Don't change the icon as a system's state changes, use color and
text for that purpose.</li>
<li><strong>Don't use the same icon more than once</strong>. Select meaningful and distinct icons so the user
will be able to quickly identify what they're looking for.</li>
</ul>
<h3>States</h3>
<ul>
<li><strong>Disabled</strong>: The system is not available to the user.</li>
<li><strong>Off / Available</strong>: The system is accessible to the user but is not currently
&quot;On&quot; or has not been configured. If the Indicator directly provides gestures
related to the system, such as opening a configuration dialog box, then use
&quot;Available&quot;; if the user must act elsewhere or the system isn't user-controllable,
use &quot;Off&quot;.</li>
<li><strong>On</strong>: The system is enabled or configured; it is having an effect on the larger application.</li>
<li><strong>Alert / Error</strong>: There has been a problem with the system. Generally, &quot;Alert&quot;
should be used to call attention to an issue that isn't critical, while &quot;Error&quot;
should be used to call attention to a problem that the user should really be aware of or do
something about.</li>
</ul>
<h3>Structure</h3>
<p>Indicators consist of a <code>.ls-indicator</code>
wrapper element with <code>.icon-*</code> classes for the type of thing they represent and
<code>.s-status-*</code> classes to articulate the current state. Title attributes should be used
to provide more verbose information about the thing and/or its status.</p>
<p>The wrapper encloses a <code>.label</code> element that is displayed on hover. This element should
include a brief statement of the current status, and can also include clickable elements
as <code>&lt;a&gt;</code> tags. An optional <code>.count</code> element can be included to display
information such as a number of messages.</p>
<p>Icon classes are as defined on the
<a class="link" href="#/browse/styleguide:home/glyphs?tc.mode=local&tc.timeSystem=utc&tc.startDelta=1800000&tc.endDelta=0&view=styleguide.glyphs">
Glyphs page</a>. Status classes applicable to Indicators are as follows:</p>
<ul>
<li><code>s-status-disabled</code></li>
<li><code>s-status-off</code></li>
<li><code>s-status-available</code></li>
<li><code>s-status-on</code></li>
<li><code>s-status-alert</code></li>
<li><code>s-status-error</code></li>
</ul>
</div>
<mct-example><div class="s-ue-bottom-bar status-holder s-status-bar">
<span class="ls-indicator icon-database s-status-disabled" title="The system is currently disabled.">
<span class="label">System not enabled.</span>
</span>
</div>
<div class="s-ue-bottom-bar status-holder s-status-bar">
<span class="ls-indicator icon-database s-status-available" title="Configure data connection.">
<span class="label">Data connection available
<a class="icon-gear">Configure</a>
</span>
</span>
</div>
<div class="s-ue-bottom-bar status-holder s-status-bar">
<span class="ls-indicator icon-database s-status-on" title="Data connected.">
<span class="label">Connected to Skynet
<a class="icon-gear">Change</a>
<a>Disconnect</a>
</span>
</span>
</div>
<div class="s-ue-bottom-bar status-holder s-status-bar">
<span class="ls-indicator icon-database s-status-alert" title="System is self-aware.">
<span class="label">Skynet at Turing Level 5</span>
</span>
<span class="ls-indicator icon-bell s-status-error" title="You have alerts.">
<span class="label">
<a class="icon-alert-triangle">View Alerts</a>
</span>
<span class="count">495</span>
</span>
</div>
</mct-example>
</div>
</div>
</div>
</div>

View File

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

View File

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

View File

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

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

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

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

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

View File

@@ -1,5 +1,5 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2019, United States Government
* Open MCT, Copyright (c) 2014-2017, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
@@ -19,44 +19,49 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div class="l-shell__app-logo" @click="launchAbout" ref="aboutLogo"></div>
</template>
<style lang="scss">
.l-shell__app-logo {
cursor: pointer;
width: 70px;
height: 20px;
background: url('assets/images/logo-app.svg') center no-repeat;
}
</style>
<script>
import AboutDialog from './AboutDialog.vue';
import Vue from 'vue';
/*global define*/
export default {
inject: ['openmct'],
mounted() {
let branding = this.openmct.branding();
if (branding.smallLogoImage){
this.$refs.aboutLogo.style.backgroundImage = `url('${branding.smallLogoImage}')`
}
},
methods: {
launchAbout(){
let vm = new Vue({
provide: {
openmct: this.openmct
define(
[],
function () {
"use strict";
/**
* Displays Fibonacci numbers in the status area.
* @constructor
*/
function FibonacciIndicator(workerService, $rootScope) {
var latest,
counter = 0,
worker = workerService.run('example.fibonacci');
function requestNext() {
worker.postMessage([counter]);
counter += 1;
}
function handleResponse(event) {
latest = event.data;
$rootScope.$apply();
requestNext();
}
worker.onmessage = handleResponse;
requestNext();
return {
getCssClass: function () {
return "icon-object-unknown";
},
components: {AboutDialog},
template: '<about-dialog></about-dialog>'
}).$mount();
this.openmct.overlays.overlay({
element: vm.$el,
size: 'large'
});
getText: function () {
return latest;
},
getDescription: function () {
return "";
}
};
}
return FibonacciIndicator;
}
}
</script>
);

View File

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

182
gulpfile.js Normal file
View File

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

View File

@@ -26,66 +26,65 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<title></title>
<script src="dist/openmct.js"></script>
<link rel="stylesheet" href="dist/styles/openmct.css">
<link rel="icon" type="image/png" href="dist/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="dist/favicons/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="dist/favicons/favicon-16x16.png" sizes="16x16">
<link rel="shortcut icon" href="dist/favicons/favicon.ico">
</head>
<body>
</body>
<script>
const FIVE_MINUTES = 5 * 60 * 1000;
const THIRTY_MINUTES = 30 * 60 * 1000;
<script src="bower_components/requirejs/require.js"> </script>
<script>
var THIRTY_MINUTES = 30 * 60 * 1000;
[
'example/eventGenerator',
'example/styleguide'
].forEach(
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
);
openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.Generator());
openmct.install(openmct.plugins.ExampleImagery());
openmct.install(openmct.plugins.UTCTimeSystem());
openmct.install(openmct.plugins.ImportExport());
openmct.install(openmct.plugins.AutoflowView({
type: "telemetry.panel"
}));
openmct.install(openmct.plugins.DisplayLayout({
showAsView: ['summary-widget', 'example.imagery']
}));
openmct.install(openmct.plugins.Conductor({
menuOptions: [
{
name: "Fixed",
timeSystem: 'utc',
bounds: {
start: Date.now() - THIRTY_MINUTES,
end: Date.now()
require(['openmct'], function (openmct) {
[
'example/eventGenerator',
'example/styleguide'
].forEach(
openmct.legacyRegistry.enable.bind(openmct.legacyRegistry)
);
openmct.install(openmct.plugins.MyItems());
openmct.install(openmct.plugins.LocalStorage());
openmct.install(openmct.plugins.Espresso());
openmct.install(openmct.plugins.Generator());
openmct.install(openmct.plugins.ExampleImagery());
openmct.install(openmct.plugins.UTCTimeSystem());
openmct.install(openmct.plugins.ImportExport());
openmct.install(openmct.plugins.AutoflowView({
type: "telemetry.panel"
}));
openmct.install(openmct.plugins.Conductor({
menuOptions: [
{
name: "Fixed",
timeSystem: 'utc',
bounds: {
start: Date.now() - THIRTY_MINUTES,
end: Date.now()
}
},
{
name: "Realtime",
timeSystem: 'utc',
clock: 'local',
clockOffsets: {
start: -25 * 60 * 1000,
end: 5 * 60 * 1000
}
}
},
{
name: "Realtime",
timeSystem: 'utc',
clock: 'local',
clockOffsets: {
start: - THIRTY_MINUTES,
end: FIVE_MINUTES
}
}
]
}));
openmct.install(openmct.plugins.SummaryWidget());
openmct.install(openmct.plugins.Notebook());
openmct.install(openmct.plugins.FolderView());
openmct.install(openmct.plugins.Tabs());
openmct.install(openmct.plugins.FlexibleLayout());
openmct.install(openmct.plugins.LADTable());
openmct.install(openmct.plugins.Filters(['table', 'telemetry.plot.overlay']));
openmct.install(openmct.plugins.ObjectMigration());
openmct.start();
]
}));
openmct.install(openmct.plugins.SummaryWidget());
openmct.install(openmct.plugins.Notebook());
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
openmct.time.timeSystem('utc');
openmct.start();
});
</script>
<link rel="stylesheet" href="platform/commonUI/general/res/css/startup-base.css">
<link rel="stylesheet" href="platform/commonUI/general/res/css/openmct.css">
<link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-32x32.png" sizes="32x32">
<link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="platform/commonUI/general/res/images/favicons/favicon-16x16.png" sizes="16x16">
<link rel="shortcut icon" href="platform/commonUI/general/res/images/favicons/favicon.ico">
</head>
<body>
<div class="l-splash-holder s-splash-holder">
<div class="l-splash s-splash"></div>
</div>
</body>
</html>

View File

@@ -21,40 +21,69 @@
*****************************************************************************/
/*global module,process*/
const devMode = process.env.NODE_ENV !== 'production';
module.exports = (config) => {
const webpackConfig = require('./webpack.config.js');
delete webpackConfig.output;
if (!devMode) {
webpackConfig.module.rules.push({
test: /\.js$/,
exclude: /node_modules|example/,
use: 'istanbul-instrumenter-loader'
});
}
module.exports = function(config) {
config.set({
// Base path that will be used to resolve all file patterns.
basePath: '',
frameworks: ['jasmine'],
// Frameworks to use
// Available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'requirejs'],
// List of files / patterns to load in the browser.
// By default, files are also included in a script tag.
files: [
'platform/**/*Spec.js',
'src/**/*Spec.js'
{pattern: 'bower_components/**/*.js', included: false},
{pattern: 'node_modules/d3-*/**/*.js', included: false},
{pattern: 'node_modules/vue/**/*.js', included: false},
{pattern: 'src/**/*', included: false},
{pattern: 'node_modules/painterro/build/*.js', included: false},
{pattern: 'node_modules/dom-to-image/dist/*', included: false},
{pattern: 'example/**/*.html', included: false},
{pattern: 'example/**/*.js', included: false},
{pattern: 'example/**/*.json', included: false},
{pattern: 'platform/**/*.js', included: false},
{pattern: 'warp/**/*.js', included: false},
{pattern: 'platform/**/*.html', included: false},
'test-main.js'
],
// List of files to exclude.
exclude: [
'platform/framework/src/Main.js'
],
// Preprocess matching files before serving them to the browser.
// https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'src/**/!(*Spec).js': [ 'coverage' ],
'platform/**/src/**/!(*Spec).js': [ 'coverage' ]
},
// Test results reporter to use
// Possible values: 'dots', 'progress'
// Available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage', 'html', 'junit'],
// Web server port.
port: 9876,
reporters: [
'progress',
'coverage',
'html'
],
browsers: ['ChromeHeadless'],
// Wnable / disable colors in the output (reporters and logs).
colors: true,
logLevel: config.LOG_INFO,
// Rerun tests when any file changes.
autoWatch: true,
// Specify browsers to run tests in.
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: [
'Chrome'
],
// Code coverage reporting.
coverageReporter: {
dir: process.env.CIRCLE_ARTIFACTS ?
process.env.CIRCLE_ARTIFACTS + '/coverage' :
@@ -74,19 +103,12 @@ module.exports = (config) => {
foldAll: false
},
preprocessors: {
// add webpack as preprocessor
'platform/**/*Spec.js': [ 'webpack' ],
'src/**/*Spec.js': [ 'webpack' ]
junitReporter: {
outputDir: process.env.CIRCLE_TEST_REPORTS || 'dist/reports/junit'
},
webpack: webpackConfig,
webpackMiddleware: {
stats: 'errors-only',
logLevel: 'warn'
},
// Continuous Integration mode.
// If true, Karma captures browsers, runs the tests and exits.
singleRun: true
});
}
};

View File

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

View File

@@ -2,15 +2,7 @@
"name": "openmct",
"version": "0.14.0-SNAPSHOT",
"description": "The Open MCT core platform",
"dependencies": {},
"devDependencies": {
"angular": "1.4.14",
"angular-route": "1.4.14",
"babel-eslint": "8.2.6",
"comma-separated-values": "^3.6.4",
"concurrently": "^3.6.1",
"copy-webpack-plugin": "^4.5.2",
"css-loader": "^1.0.0",
"dependencies": {
"d3-array": "1.2.x",
"d3-axis": "1.0.x",
"d3-collection": "1.0.x",
@@ -21,69 +13,57 @@
"d3-selection": "1.3.x",
"d3-time": "1.0.x",
"d3-time-format": "2.1.x",
"eslint": "5.2.0",
"eventemitter3": "^1.2.0",
"exports-loader": "^0.7.0",
"dom-to-image": "^2.6.0",
"express": "^4.13.1",
"fast-sass-loader": "1.4.6",
"file-loader": "^1.1.11",
"file-saver": "^1.3.8",
"minimist": "^1.1.1",
"painterro": "^0.2.65",
"request": "^2.69.0",
"vue": "^2.5.6"
},
"devDependencies": {
"bower": "^1.7.7",
"git-rev-sync": "^1.4.0",
"glob": ">= 3.0.0",
"html-loader": "^0.5.5",
"html2canvas": "^1.0.0-alpha.12",
"imports-loader": "^0.8.0",
"istanbul-instrumenter-loader": "^3.0.1",
"jasmine-core": "^3.1.0",
"gulp": "^3.9.1",
"gulp-jscs": "^3.0.2",
"gulp-jshint": "^2.0.0",
"gulp-jshint-html-reporter": "^0.1.3",
"gulp-rename": "^1.2.2",
"gulp-requirejs-optimize": "^0.3.1",
"gulp-sass": "^3.1.0",
"gulp-sourcemaps": "^1.6.0",
"jasmine-core": "^2.3.0",
"jscs-html-reporter": "^0.1.0",
"jsdoc": "^3.3.2",
"karma": "^2.0.3",
"karma-chrome-launcher": "^2.2.0",
"karma-cli": "^1.0.1",
"karma-coverage": "^1.1.2",
"jshint": "^2.7.0",
"karma": "^0.13.3",
"karma-chrome-launcher": "^0.1.12",
"karma-cli": "0.0.4",
"karma-coverage": "^0.5.3",
"karma-html-reporter": "^0.2.7",
"karma-jasmine": "^1.1.2",
"karma-webpack": "^3.0.0",
"location-bar": "^3.0.1",
"karma-jasmine": "^0.1.5",
"karma-junit-reporter": "^0.3.8",
"karma-requirejs": "^0.2.2",
"lodash": "^3.10.1",
"markdown-toc": "^0.11.7",
"marked": "^0.3.5",
"mini-css-extract-plugin": "^0.4.1",
"minimist": "^1.1.1",
"merge-stream": "^1.0.0",
"mkdirp": "^0.5.1",
"moment": "^2.11.1",
"moment-duration-format": "^2.2.2",
"moment-timezone": "^0.5.21",
"node-bourbon": "^4.2.3",
"node-sass": "^4.9.2",
"painterro": "^0.2.65",
"printj": "^1.1.0",
"raw-loader": "^0.5.1",
"request": "^2.69.0",
"requirejs": "2.1.x",
"split": "^1.0.0",
"style-loader": "^0.21.0",
"v8-compile-cache": "^1.1.0",
"vue": "2.5.6",
"vue-loader": "^15.2.6",
"vue-template-compiler": "2.5.6",
"webpack": "^4.16.2",
"webpack-cli": "^3.1.0",
"webpack-dev-middleware": "^3.1.3",
"webpack-hot-middleware": "^2.22.3",
"zepto": "^1.2.0"
"v8-compile-cache": "^1.1.0"
},
"scripts": {
"start": "node app.js",
"lint": "eslint platform src openmct.js",
"lint:fix": "eslint platform src openmct.js --fix",
"build:prod": "NODE_ENV=production webpack",
"build:dev": "webpack",
"build:watch": "webpack --watch",
"test": "karma start --single-run",
"test:watch": "karma start --no-single-run",
"verify": "concurrently 'npm:test' 'npm:lint'",
"jshint": "jshint platform example",
"watch": "karma start",
"jsdoc": "jsdoc -c jsdoc.json -R API.md -r -d dist/docs/api",
"otherdoc": "node docs/gendocs.js --in docs/src --out dist/docs --suppress-toc 'docs/src/index.md|docs/src/process/index.md'",
"docs": "npm run jsdoc ; npm run otherdoc",
"prepare": "npm run build:prod"
"prepare": "node ./node_modules/bower/bin/bower install && node ./node_modules/gulp/bin/gulp.js install"
},
"repository": {
"type": "git",

View File

@@ -21,17 +21,17 @@
*****************************************************************************/
define([
"./res/templates/about-dialog.html",
"text!./res/templates/about-dialog.html",
"./src/LogoController",
"./src/AboutController",
"./src/LicenseController",
"./res/templates/app-logo.html",
"./res/templates/about-logo.html",
"./res/templates/overlay-about.html",
"./res/templates/license-apache.html",
"./res/templates/license-mit.html",
"./res/templates/licenses.html",
"./res/templates/licenses-export-md.html",
"text!./res/templates/app-logo.html",
"text!./res/templates/about-logo.html",
"text!./res/templates/overlay-about.html",
"text!./res/templates/license-apache.html",
"text!./res/templates/license-mit.html",
"text!./res/templates/licenses.html",
"text!./res/templates/licenses-export-md.html",
'legacyRegistry'
], function (
aboutDialogTemplate,

View File

@@ -31,14 +31,18 @@ define([
"./src/navigation/NavigateAction",
"./src/navigation/OrphanNavigationHandler",
"./src/windowing/NewTabAction",
"./res/templates/browse.html",
"./res/templates/browse-object.html",
"./res/templates/browse/object-header.html",
"./res/templates/browse/object-header-frame.html",
"./res/templates/menu-arrow.html",
"./res/templates/back-arrow.html",
"./res/templates/browse/object-properties.html",
"./res/templates/browse/inspector-region.html",
"./src/windowing/FullscreenAction",
"./src/windowing/WindowTitler",
"text!./res/templates/browse.html",
"text!./res/templates/browse-object.html",
"text!./res/templates/items/grid-item.html",
"text!./res/templates/browse/object-header.html",
"text!./res/templates/browse/object-header-frame.html",
"text!./res/templates/menu-arrow.html",
"text!./res/templates/back-arrow.html",
"text!./res/templates/items/items.html",
"text!./res/templates/browse/object-properties.html",
"text!./res/templates/browse/inspector-region.html",
'legacyRegistry'
], function (
BrowseController,
@@ -51,12 +55,16 @@ define([
NavigateAction,
OrphanNavigationHandler,
NewTabAction,
FullscreenAction,
WindowTitler,
browseTemplate,
browseObjectTemplate,
gridItemTemplate,
objectHeaderTemplate,
objectHeaderFrameTemplate,
menuArrowTemplate,
backArrowTemplate,
itemsTemplate,
objectPropertiesTemplate,
inspectorRegionTemplate,
legacyRegistry
@@ -65,6 +73,15 @@ define([
legacyRegistry.register("platform/commonUI/browse", {
"extensions": {
"routes": [
{
"when": "/browse/:ids*?",
"template": browseTemplate,
"reloadOnSearch": false
},
{
"when": "",
"redirectTo": "/browse/"
}
],
"constants": [
{
@@ -148,6 +165,19 @@ define([
"view"
]
},
{
"key": "grid-item",
"template": gridItemTemplate,
"uses": [
"type",
"action",
"location"
],
"gestures": [
"info",
"menu"
]
},
{
"key": "object-header",
"template": objectHeaderTemplate,
@@ -221,9 +251,41 @@ define([
"group": "windowing",
"cssClass": "icon-new-window",
"priority": "preferred"
},
{
"key": "fullscreen",
"implementation": FullscreenAction,
"category": "view-control",
"group": "windowing",
"priority": "default"
}
],
"views": [
{
"key": "items",
"name": "Grid",
"cssClass": "icon-thumbs-strip",
"description": "Grid of available items",
"template": itemsTemplate,
"uses": [
"composition"
],
"gestures": [
"drop"
],
"type": "folder",
"editable": false
}
],
"runs": [
{
"implementation": WindowTitler,
"depends": [
"navigationService",
"$rootScope",
"$document"
]
},
{
"implementation": OrphanNavigationHandler,
"depends": [
@@ -233,18 +295,16 @@ define([
]
}
],
"templates": [
"licenses": [
{
key: "browseRoot",
template: browseTemplate
},
{
key: "browseObject",
template: browseObjectTemplate
},
{
key: "inspectorRegion",
template: inspectorRegionTemplate
"name": "screenfull.js",
"version": "1.2.0",
"description": "Wrapper for cross-browser usage of fullscreen API",
"author": "Sindre Sorhus",
"website": "https://github.com/sindresorhus/screenfull.js/",
"copyright": "Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)",
"license": "license-mit",
"link": "https://github.com/sindresorhus/screenfull.js/blob/gh-pages/license"
}
]
}

View File

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

View File

@@ -65,7 +65,7 @@
<div class='split-pane-component t-object pane primary-pane left'>
<mct-representation mct-object="navigatedObject"
key="navigatedObject.getCapability('status').get('editing') ? 'edit-object' : 'browse-object'"
class="abs holder holder-object t-main-view">
class="abs holder holder-object l-main-view t-main-view">
</mct-representation>
<a class="mini-tab-icon anchor-right mobile-hide toggle-pane toggle-inspect flush-right"
title="{{ modelPaneInspect.visible()? 'Hide' : 'Show' }} the Inspection pane"

View File

@@ -19,46 +19,41 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div ng-controller="ObjectInspectorController as controller" class="grid-properties">
<ul class="l-inspector-part">
<h2 class="first">Properties</h2>
<li class="t-repeat grid-row"
ng-repeat="data in metadata"
ng-class="{ first:$index === 0 }">
<div class="grid-cell label">{{ data.name }}</div>
<div class="grid-cell value">{{ data.value }}</div>
</li>
</ul>
<ul class="l-inspector-part" ng-if="contextutalParents.length > 0">
<h2 title="The location of this linked object.">Location</h2>
<li class="grid-row">
<div class="label" ng-if="primaryParents.length > 0">This Link</div>
<div class="grid-cell value">
<div class="t-repeat inspector-location"
ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-click="parent.getCapability('action').perform('navigate')"
class="location-item">
</mct-representation>
</div>
<div ng-controller="ObjectInspectorController as controller">
<ul class="flex-elem grows l-inspector-part">
<li>
<em class="t-inspector-part-header">Properties</em>
<div class="inspector-properties"
ng-repeat="data in metadata"
ng-class="{ first:$index === 0 }">
<div class="label">{{ data.name }}</div>
<div class="value">{{ data.value }}</div>
</div>
</li>
<li class="grid-row" ng-if="primaryParents.length > 0">
<div class="grid-cell label">Original</div>
<div class="grid-cell value">
<div class="t-repeat inspector-location value"
ng-repeat="parent in primaryParents"
ng-class="{ last:($index + 1) === primaryParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-click="parent.getCapability('action').perform('navigate')"
class="location-item">
</mct-representation>
</div>
</div>
<li ng-if="contextutalParents.length > 0">
<em class="t-inspector-part-header" title="The location of this linked object.">Location</em>
<div ng-if="primaryParents.length > 0" class="section-header">This Object</div>
<span class="inspector-location"
ng-repeat="parent in contextutalParents"
ng-class="{ last:($index + 1) === contextualParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-click="parent.getCapability('action').perform('navigate')"
class="location-item">
</mct-representation>
</span>
</li>
<li ng-if="primaryParents.length > 0">
<div class="section-header">Object's Original</div>
<span class="inspector-location"
ng-repeat="parent in primaryParents"
ng-class="{ last:($index + 1) === primaryParents.length }">
<mct-representation key="'label'"
mct-object="parent"
ng-click="parent.getCapability('action').perform('navigate')"
class="location-item">
</mct-representation>
</span>
</li>
</ul>
</div>

View File

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

View File

@@ -19,9 +19,9 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<!-- DO NOT ADD SPACES BETWEEN THE SPANS - IT ADDS WHITE SPACE!! -->
<div class="ls-indicator {{ngModel.getCssClass()}}"
title="{{ngModel.getDescription()}}"
ng-show="ngModel.getText().length > 0">
<span class="label">{{ngModel.getText()}}</span>
<div class='items-holder grid abs'>
<mct-representation key="'grid-item'"
ng-repeat="childObject in composition"
mct-object="childObject">
</mct-representation>
</div>

View File

@@ -47,9 +47,10 @@ define(
urlService,
defaultPath
) {
window.browseScope = $scope;
var initialPath = ($route.current.params.ids || defaultPath).split("/"),
currentIds;
currentIds,
actions,
previewAction;
$scope.treeModel = {
selectedObject: undefined,
@@ -57,16 +58,14 @@ define(
navigationService.setNavigation(object, true);
},
allowSelection: function (object) {
var domainObjectInView = navigationService.getNavigation(),
isInEditMode = domainObjectInView.getCapability('status').get('editing');
// return navigationService.shouldNavigate();
if (navigationService.anyChecksBeforeNavigation()) {
if (isInEditMode) {
var actions = object.getCapability('action'),
previewAction = actions.getActions({key: 'mct-preview-action'})[0];
actions = actions || $scope.domainObject.getCapability('action');
previewAction = previewAction || actions.getActions({key: 'mct-preview-action'})[0];
if (previewAction && previewAction.perform) {
previewAction.perform();
previewAction.perform(object);
return false;
} else {
return navigationService.shouldNavigate();

View File

@@ -31,6 +31,7 @@ define(
* @constructor
*/
function BrowseObjectController($scope, $location, $route) {
var navigatedObject;
function setViewForDomainObject(domainObject) {
var locationViewKey = $location.search().view;
@@ -46,6 +47,7 @@ define(
((domainObject && domainObject.useCapability('view')) || [])
.forEach(selectViewIfMatching);
}
navigatedObject = domainObject;
}
function updateQueryParam(viewKey) {

View File

@@ -56,7 +56,7 @@ define(
// declared as a method but as a property which happens to
// be a function.
if (agentService.isPhone() && agentService.isPortrait()) {
// On phones, trees should collapse in portrait mode
// On phones, πs should collapse in portrait mode
// when something is navigated-to.
self.state = false;
}

View File

@@ -109,6 +109,10 @@ define(
});
};
NavigationService.prototype.anyChecksBeforeNavigation = function () {
return this.checks.length;
};
/**
* Check if navigation should proceed. May prompt a user for input
* if any checkFns return messages. Returns true if the user wishes to

View File

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

View File

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

View File

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

View File

@@ -19,7 +19,6 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/*global console*/
/**
* MCTRepresentationSpec. Created by vwoeltje on 11/6/14.
@@ -49,19 +48,9 @@ define(
controller;
function waitsForNavigation() {
return new Promise(function (resolve) {
mockNavigationService.setNavigation.and.callFake(function (obj) {
var returnValue;
try {
returnValue = NavigationService.prototype.setNavigation.call(mockNavigationService, obj);
} catch (err) {
console.error(err);
//Not rejecting because 'setNavigation' has been called, which is what's being tested here.
//Rejecting will fail tests.
}
resolve();
return returnValue;
});
var calls = mockNavigationService.setNavigation.calls.length;
waitsFor(function () {
return mockNavigationService.setNavigation.calls.length > calls;
});
}
@@ -89,7 +78,7 @@ define(
"urlService",
["urlForLocation"]
);
mockUrlService.urlForLocation.and.callFake(function (mode, object) {
mockUrlService.urlForLocation.andCallFake(function (mode, object) {
if (object === mockDefaultRootObject) {
return [mode, testDefaultRoot].join('/');
}
@@ -117,7 +106,7 @@ define(
"removeListener"
].forEach(function (method) {
spyOn(mockNavigationService, method)
.and.callThrough();
.andCallThrough();
});
mockRootObject = jasmine.createSpyObj(
"rootObjectContainer",
@@ -135,31 +124,32 @@ define(
"nestedDomainObject",
["getId", "getCapability", "getModel", "useCapability", "hasCapability"]
);
mockObjectService.getObjects.and.returnValue(Promise.resolve({
mockObjectService.getObjects.andReturn(Promise.resolve({
ROOT: mockRootObject
}));
mockRootObject.useCapability.and.returnValue(Promise.resolve([
mockRootObject.useCapability.andReturn(Promise.resolve([
mockOtherDomainObject,
mockDefaultRootObject
]));
mockRootObject.hasCapability.and.returnValue(true);
mockDefaultRootObject.useCapability.and.returnValue(Promise.resolve([
mockRootObject.hasCapability.andReturn(true);
mockDefaultRootObject.useCapability.andReturn(Promise.resolve([
mockNextObject
]));
mockDefaultRootObject.hasCapability.and.returnValue(true);
mockOtherDomainObject.hasCapability.and.returnValue(false);
mockNextObject.useCapability.and.returnValue(undefined);
mockNextObject.hasCapability.and.returnValue(false);
mockNextObject.getId.and.returnValue("next");
mockDefaultRootObject.getId.and.returnValue(testDefaultRoot);
mockDefaultRootObject.hasCapability.andReturn(true);
mockOtherDomainObject.hasCapability.andReturn(false);
mockNextObject.useCapability.andReturn(undefined);
mockNextObject.hasCapability.andReturn(false);
mockNextObject.getId.andReturn("next");
mockDefaultRootObject.getId.andReturn(testDefaultRoot);
instantiateController();
return waitsForNavigation();
waitsForNavigation();
});
it("uses composition to set the navigated object, if there is none", function () {
instantiateController();
return waitsForNavigation().then(function () {
waitsForNavigation();
runs(function () {
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject);
});
@@ -167,26 +157,27 @@ define(
it("navigates to a root-level object, even when default path is not found", function () {
mockDefaultRootObject.getId
.and.returnValue("something-other-than-the-" + testDefaultRoot);
.andReturn("something-other-than-the-" + testDefaultRoot);
instantiateController();
return waitsForNavigation().then(function () {
waitsForNavigation();
runs(function () {
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject);
});
});
});
//
it("does not try to override navigation", function () {
mockNavigationService.getNavigation.and.returnValue(mockDefaultRootObject);
mockNavigationService.getNavigation.andReturn(mockDefaultRootObject);
instantiateController();
return waitsForNavigation().then(function () {
expect(mockScope.navigatedObject).toBe(mockDefaultRootObject);
});
waitsForNavigation();
expect(mockScope.navigatedObject).toBe(mockDefaultRootObject);
});
//
it("updates scope when navigated object changes", function () {
// Should have registered a listener - call it
mockNavigationService.addListener.calls.mostRecent().args[0](
mockNavigationService.addListener.mostRecentCall.args[0](
mockOtherDomainObject
);
expect(mockScope.navigatedObject).toEqual(mockOtherDomainObject);
@@ -198,18 +189,19 @@ define(
"$destroy",
jasmine.any(Function)
);
mockScope.$on.calls.mostRecent().args[1]();
mockScope.$on.mostRecentCall.args[1]();
// Should remove the listener it added earlier
expect(mockNavigationService.removeListener).toHaveBeenCalledWith(
mockNavigationService.addListener.calls.mostRecent().args[0]
mockNavigationService.addListener.mostRecentCall.args[0]
);
});
it("uses route parameters to choose initially-navigated object", function () {
mockRoute.current.params.ids = testDefaultRoot + "/next";
instantiateController();
return waitsForNavigation().then(function () {
waitsForNavigation();
runs(function () {
expect(mockScope.navigatedObject).toBe(mockNextObject);
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockNextObject);
@@ -222,10 +214,12 @@ define(
// it hits an invalid ID.
mockRoute.current.params.ids = testDefaultRoot + "/junk";
instantiateController();
return waitsForNavigation().then(function () {
waitsForNavigation();
runs(function () {
expect(mockScope.navigatedObject).toBe(mockDefaultRootObject);
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDefaultRootObject);
});
});
@@ -235,7 +229,8 @@ define(
// should stop at it since remaining IDs cannot be loaded.
mockRoute.current.params.ids = testDefaultRoot + "/next/junk";
instantiateController();
return waitsForNavigation().then(function () {
waitsForNavigation();
runs(function () {
expect(mockScope.navigatedObject).toBe(mockNextObject);
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockNextObject);
@@ -249,11 +244,11 @@ define(
expect(mockRoute.current.pathParams.ids)
.not
.toBe(testDefaultRoot + '/next');
mockLocation.path.and.callFake(function () {
mockLocation.path.andCallFake(function () {
expect(mockRoute.current.pathParams.ids)
.toBe(testDefaultRoot + '/next');
});
mockNavigationService.addListener.calls.mostRecent().args[0](
mockNavigationService.addListener.mostRecentCall.args[0](
mockNextObject
);
expect(mockLocation.path).toHaveBeenCalledWith(

View File

@@ -20,6 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
["../src/BrowseObjectController"],
function (BrowseObjectController) {
@@ -32,7 +33,7 @@ define(
// Utility function; look for a $watch on scope and fire it
function fireWatch(expr, value) {
mockScope.$watch.calls.all().forEach(function (call) {
mockScope.$watch.calls.forEach(function (call) {
if (call.args[0] === expr) {
call.args[1](value);
}
@@ -49,7 +50,7 @@ define(
"$location",
["path", "search"]
);
mockLocation.search.and.returnValue({});
mockLocation.search.andReturn({});
controller = new BrowseObjectController(
mockScope,
@@ -64,7 +65,7 @@ define(
// Allows the path index to be checked
// prior to setting $route.current
mockLocation.path.and.returnValue("/browse/");
mockLocation.path.andReturn("/browse/");
});
it("sets the active view from query parameters", function () {
@@ -78,10 +79,10 @@ define(
{ key: 'xyz' }
];
mockDomainObject.useCapability.and.callFake(function (c) {
mockDomainObject.useCapability.andCallFake(function (c) {
return (c === 'view') && testViews;
});
mockLocation.search.and.returnValue({ view: 'def' });
mockLocation.search.andReturn({ view: 'def' });
fireWatch('domainObject', mockDomainObject);
expect(mockScope.representation.selected)

View File

@@ -50,14 +50,14 @@ define(
"navigationService",
["getNavigation", "addListener"]
);
mockNavigationService.addListener.and.returnValue(mockNavigationUnlistener);
mockNavigationService.addListener.andReturn(mockNavigationUnlistener);
mockStatusUnlistener = jasmine.createSpy("statusUnlistener");
mockStatusCapability = jasmine.createSpyObj(
"statusCapability",
["listen"]
);
mockStatusCapability.listen.and.returnValue(mockStatusUnlistener);
mockStatusCapability.listen.andReturn(mockStatusUnlistener);
mockDomainObject = jasmine.createSpyObj(
'domainObject',
@@ -68,13 +68,13 @@ define(
'hasCapability'
]
);
mockDomainObject.getId.and.returnValue("domainObject");
mockDomainObject.getModel.and.returnValue({});
mockDomainObject.hasCapability.and.returnValue(true);
mockDomainObject.getCapability.and.returnValue(mockStatusCapability);
mockDomainObject.getId.andReturn("domainObject");
mockDomainObject.getModel.andReturn({});
mockDomainObject.hasCapability.andReturn(true);
mockDomainObject.getCapability.andReturn(mockStatusCapability);
mockLocation = jasmine.createSpyObj('location', ['search']);
mockLocation.search.and.returnValue({});
mockLocation.search.andReturn({});
mockAttrs = {};
@@ -84,7 +84,7 @@ define(
it("listens for changes to navigation and attaches a status" +
" listener", function () {
expect(mockNavigationService.addListener).toHaveBeenCalledWith(jasmine.any(Function));
mockNavigationService.addListener.calls.mostRecent().args[0](mockDomainObject);
mockNavigationService.addListener.mostRecentCall.args[0](mockDomainObject);
expect(mockStatusCapability.listen).toHaveBeenCalledWith(jasmine.any(Function));
});
@@ -93,8 +93,8 @@ define(
controller.toggle();
// test pre-condition that inspector is hidden
expect(controller.visible()).toBe(false);
mockNavigationService.addListener.calls.mostRecent().args[0](mockDomainObject);
mockStatusCapability.listen.calls.mostRecent().args[0](["editing"]);
mockNavigationService.addListener.mostRecentCall.args[0](mockDomainObject);
mockStatusCapability.listen.mostRecentCall.args[0](["editing"]);
expect(controller.visible()).toBe(true);
});

View File

@@ -60,8 +60,8 @@ define(
mockActionContext.domainObject = mockDomainObject;
mockActionContext.event = mockEvent;
mockScope.domainObject = mockDomainObject;
mockDomainObject.getCapability.and.returnValue(mockContextMenuAction);
mockContextMenuAction.perform.and.returnValue(jasmine.any(Function));
mockDomainObject.getCapability.andReturn(mockContextMenuAction);
mockContextMenuAction.perform.andReturn(jasmine.any(Function));
controller = new MenuArrowController(mockScope);
});

View File

@@ -39,7 +39,7 @@ define(
mockMutationCapability = jasmine.createSpyObj("mutation", ["mutate"]);
mockTypeCapability = jasmine.createSpyObj("type", ["typeDef", "hasFeature"]);
mockTypeCapability.typeDef = { name: ""};
mockTypeCapability.hasFeature.and.callFake(function (feature) {
mockTypeCapability.hasFeature.andCallFake(function (feature) {
return feature === 'creation';
});
@@ -52,8 +52,8 @@ define(
name: "Test name"
};
mockDomainObject = jasmine.createSpyObj("domainObject", ["getCapability", "getModel"]);
mockDomainObject.getModel.and.returnValue(model);
mockDomainObject.getCapability.and.callFake(function (key) {
mockDomainObject.getModel.andReturn(model);
mockDomainObject.getCapability.andCallFake(function (key) {
return mockCapabilities[key];
});
@@ -62,7 +62,7 @@ define(
};
mockCurrentTarget = jasmine.createSpyObj("currentTarget", ["blur", "textContent"]);
mockCurrentTarget.blur.and.returnValue(mockCurrentTarget);
mockCurrentTarget.blur.andReturn(mockCurrentTarget);
mockEvent = {
which: {},
@@ -109,7 +109,7 @@ define(
expect(mockMutationCapability.mutate).toHaveBeenCalledWith(jasmine.any(Function));
mockMutationCapability.mutate.calls.mostRecent().args[0](model);
mockMutationCapability.mutate.mostRecentCall.args[0](model);
expect(mockDomainObject.getModel().name).toBe("New name");
});
@@ -127,7 +127,7 @@ define(
});
it("disallows editting name when object is non-creatable", function () {
mockTypeCapability.hasFeature.and.returnValue(false);
mockTypeCapability.hasFeature.andReturn(false);
expect(controller.allowEdit()).toBe(false);

View File

@@ -27,6 +27,7 @@ define(
describe("The PaneController", function () {
var mockScope,
mockAgentService,
mockDomainObjects,
mockWindow,
controller,
mockLocation,
@@ -46,6 +47,17 @@ define(
beforeEach(function () {
mockScope = jasmine.createSpyObj("$scope", ["$on"]);
mockDomainObjects = ['a', 'b'].map(function (id) {
var mockDomainObject = jasmine.createSpyObj(
'domainObject-' + id,
['getId', 'getModel', 'getCapability']
);
mockDomainObject.getId.andReturn(id);
mockDomainObject.getModel.andReturn({});
return mockDomainObject;
});
mockAgentService = jasmine.createSpyObj(
"agentService",
["isMobile", "isPhone", "isTablet", "isPortrait", "isLandscape"]
@@ -53,7 +65,7 @@ define(
mockWindow = jasmine.createSpyObj("$window", ["open"]);
mockLocation = jasmine.createSpyObj('location', ['search']);
mockLocation.search.and.returnValue({});
mockLocation.search.andReturn({});
mockAttrs = {};
});
@@ -71,9 +83,9 @@ define(
});
it("collapses on navigation changes on portrait-oriented phones", function () {
mockAgentService.isMobile.and.returnValue(true);
mockAgentService.isPhone.and.returnValue(true);
mockAgentService.isPortrait.and.returnValue(true);
mockAgentService.isMobile.andReturn(true);
mockAgentService.isPhone.andReturn(true);
mockAgentService.isPortrait.andReturn(true);
controller = instantiateController();
expect(controller.visible()).toBeTruthy();
@@ -90,13 +102,13 @@ define(
});
it("sets pane state to false when in location.search", function () {
mockLocation.search.and.returnValue({'hideTree': true});
mockLocation.search.andReturn({'hideTree': true});
expect(instantiateController().visible()).toBe(false);
expect(mockLocation.search).toHaveBeenCalledWith('hideTree', undefined);
});
it("sets state to true when not found in location.search", function () {
mockLocation.search.and.returnValue({});
mockLocation.search.andReturn({});
expect(instantiateController().visible()).toBe(true);
expect(mockLocation.search).not.toHaveBeenCalledWith('hideTree', undefined);
});

View File

@@ -34,6 +34,17 @@ define([
mockDomainObject,
action;
function waitForCall() {
var called = false;
waitsFor(function () {
return called;
});
return function () {
called = true;
};
}
beforeEach(function () {
mockNavigationService = jasmine.createSpyObj(
"navigationService",
@@ -52,24 +63,26 @@ define([
});
it("sets navigation if it is allowed", function () {
mockNavigationService.shouldNavigate.and.returnValue(true);
return action.perform()
.then(function () {
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDomainObject, true);
});
mockNavigationService.shouldNavigate.andReturn(true);
action.perform()
.then(waitForCall());
runs(function () {
expect(mockNavigationService.setNavigation)
.toHaveBeenCalledWith(mockDomainObject, true);
});
});
it("does not set navigation if it is not allowed", function () {
mockNavigationService.shouldNavigate.and.returnValue(false);
mockNavigationService.shouldNavigate.andReturn(false);
var onSuccess = jasmine.createSpy('onSuccess');
return action.perform()
.then(onSuccess, function () {
expect(onSuccess).not.toHaveBeenCalled();
expect(mockNavigationService.setNavigation)
.not
.toHaveBeenCalledWith(mockDomainObject);
});
action.perform()
.then(onSuccess, waitForCall());
runs(function () {
expect(onSuccess).not.toHaveBeenCalled();
expect(mockNavigationService.setNavigation)
.not
.toHaveBeenCalledWith(mockDomainObject);
});
});
it("is only applicable when a domain object is in context", function () {

View File

@@ -69,7 +69,7 @@ define(
navigationService.addListener(callback);
navigationService.setNavigation(testObject);
navigationService.setNavigation(testObject);
expect(callback.calls.count()).toEqual(1);
expect(callback.calls.length).toEqual(1);
});
it("stops notifying listeners after removal", function () {

View File

@@ -65,35 +65,34 @@ define([
mockActionCapability = jasmine.createSpyObj('action', ['perform']);
mockEditor = jasmine.createSpyObj('editor', ['isEditContextRoot']);
mockThrottle.and.callFake(function (fn) {
mockThrottle.andCallFake(function (fn) {
var mockThrottledFn =
jasmine.createSpy('throttled-' + mockThrottledFns.length);
mockThrottledFn.and.callFake(fn);
mockThrottledFn.andCallFake(fn);
mockThrottledFns.push(mockThrottledFn);
return mockThrottledFn;
});
mockTopic.and.returnValue(mockMutationTopic);
mockDomainObject.getId.and.returnValue(testId);
mockDomainObject.getCapability.and.callFake(function (c) {
mockTopic.andReturn(mockMutationTopic);
mockDomainObject.getId.andReturn(testId);
mockDomainObject.getCapability.andCallFake(function (c) {
return {
context: mockContext,
editor: mockEditor
}[c];
});
mockDomainObject.hasCapability.and.callFake(function (c) {
mockDomainObject.hasCapability.andCallFake(function (c) {
return !!mockDomainObject.getCapability(c);
});
mockParentObject.getCapability.and.callFake(function (c) {
mockParentObject.getCapability.andCallFake(function (c) {
return {
action: mockActionCapability
}[c];
});
testParentComposition = [];
mockParentObject.useCapability.and.returnValue(Promise.resolve(testParentComposition));
mockContext.getParent.and.returnValue(mockParentObject);
mockNavigationService.getNavigation.and.returnValue(mockDomainObject);
mockEditor.isEditContextRoot.and.returnValue(false);
mockParentObject.useCapability.andReturn(Promise.resolve(testParentComposition));
mockContext.getParent.andReturn(mockParentObject);
mockNavigationService.getNavigation.andReturn(mockDomainObject);
mockEditor.isEditContextRoot.andReturn(false);
return new OrphanNavigationHandler(
mockThrottle,
@@ -107,7 +106,7 @@ define([
expect(mockMutationTopic.listen)
.toHaveBeenCalledWith(jasmine.any(Function));
expect(mockThrottledFns.indexOf(
mockMutationTopic.listen.calls.mostRecent().args[0]
mockMutationTopic.listen.mostRecentCall.args[0]
)).not.toEqual(-1);
});
@@ -115,7 +114,7 @@ define([
expect(mockNavigationService.addListener)
.toHaveBeenCalledWith(jasmine.any(Function));
expect(mockThrottledFns.indexOf(
mockNavigationService.addListener.calls.mostRecent().args[0]
mockNavigationService.addListener.mostRecentCall.args[0]
)).not.toEqual(-1);
});
@@ -135,14 +134,28 @@ define([
function itNavigatesAsExpected() {
if (isOrphan && !isEditRoot) {
it("navigates to the parent", function () {
return Promise.resolve().then(function () {
var done = false;
waitsFor(function () {
return done;
});
setTimeout(function () {
done = true;
}, 5);
runs(function () {
expect(mockActionCapability.perform)
.toHaveBeenCalledWith('navigate');
});
});
} else {
it("does nothing", function () {
return Promise.resolve().then(function () {
var done = false;
waitsFor(function () {
return done;
});
setTimeout(function () {
done = true;
}, 5);
runs(function () {
expect(mockActionCapability.perform)
.not.toHaveBeenCalled();
});
@@ -152,12 +165,12 @@ define([
describe(caseName, function () {
beforeEach(function () {
mockEditor.isEditContextRoot.and.returnValue(isEditRoot);
mockEditor.isEditContextRoot.andReturn(isEditRoot);
});
describe("when navigation changes", function () {
beforeEach(function () {
mockNavigationService.addListener.calls.mostRecent()
mockNavigationService.addListener.mostRecentCall
.args[0](mockDomainObject);
});
itNavigatesAsExpected();
@@ -165,7 +178,7 @@ define([
describe("when mutation occurs", function () {
beforeEach(function () {
mockMutationTopic.listen.calls.mostRecent()
mockMutationTopic.listen.mostRecentCall
.args[0](mockParentObject);
});

View File

@@ -0,0 +1,59 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* MCTRepresentationSpec. Created by vwoeltje on 11/6/14.
*/
define(
["../../src/windowing/FullscreenAction", "screenfull"],
function (FullscreenAction, screenfull) {
describe("The fullscreen action", function () {
var action,
oldToggle;
beforeEach(function () {
// Screenfull is not shimmed or injected, so
// we need to spy on it in the global scope.
oldToggle = screenfull.toggle;
screenfull.toggle = jasmine.createSpy("toggle");
action = new FullscreenAction({});
});
afterEach(function () {
screenfull.toggle = oldToggle;
});
it("toggles fullscreen mode when performed", function () {
action.perform();
expect(window.screenfull.toggle).toHaveBeenCalled();
});
it("provides displayable metadata", function () {
expect(action.getMetadata().cssClass).toBeDefined();
});
});
}
);

View File

@@ -46,7 +46,7 @@ define(
// tree is opened in a new tab using the
// context menu
mockContextSelected = jasmine.createSpyObj("context", ["selectedObject",
"domainObject"]);
"domainObject"]);
// Mocks the urlService used to make the new tab's url from a
// domainObject and mode
@@ -54,11 +54,11 @@ define(
// Action done using the current context or mockContextCurrent
actionCurrent = new NewTabAction(mockUrlService, mockWindow,
mockContextCurrent);
mockContextCurrent);
// Action done using the selected context or mockContextSelected
actionSelected = new NewTabAction(mockUrlService, mockWindow,
mockContextSelected);
mockContextSelected);
});

View File

@@ -0,0 +1,78 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
/**
* WindowTitlerSpec. Created by vwoeltje on 11/6/14.
*/
define(
["../../src/windowing/WindowTitler"],
function (WindowTitler) {
describe("The window titler", function () {
var mockNavigationService,
mockRootScope,
mockDocument,
mockDomainObject,
titler;
beforeEach(function () {
mockNavigationService = jasmine.createSpyObj(
'navigationService',
['getNavigation']
);
mockRootScope = jasmine.createSpyObj(
'$rootScope',
['$watch']
);
mockDomainObject = jasmine.createSpyObj(
'domainObject',
['getModel']
);
mockDocument = [{}];
mockDomainObject.getModel.andReturn({ name: 'Test name' });
mockNavigationService.getNavigation.andReturn(mockDomainObject);
titler = new WindowTitler(
mockNavigationService,
mockRootScope,
mockDocument
);
});
it("listens for changes to the name of the navigated object", function () {
expect(mockRootScope.$watch).toHaveBeenCalledWith(
jasmine.any(Function),
jasmine.any(Function)
);
expect(mockRootScope.$watch.mostRecentCall.args[0]())
.toEqual('Test name');
});
it("sets the title to the name of the navigated object", function () {
mockRootScope.$watch.mostRecentCall.args[1]("Some name");
expect(mockDocument[0].title).toEqual("Some name");
});
});
}
);

View File

@@ -23,14 +23,13 @@
define([
"./src/DialogService",
"./src/OverlayService",
"./res/templates/overlay-dialog.html",
"./res/templates/overlay-options.html",
"./res/templates/dialog.html",
"./res/templates/overlay-blocking-message.html",
"./res/templates/message.html",
"./res/templates/notification-message.html",
"./res/templates/overlay-message-list.html",
"./res/templates/overlay.html",
"text!./res/templates/overlay-dialog.html",
"text!./res/templates/overlay-options.html",
"text!./res/templates/dialog.html",
"text!./res/templates/overlay-blocking-message.html",
"text!./res/templates/message.html",
"text!./res/templates/overlay-message-list.html",
"text!./res/templates/overlay.html",
'legacyRegistry'
], function (
DialogService,
@@ -40,7 +39,6 @@ define([
dialogTemplate,
overlayBlockingMessageTemplate,
messageTemplate,
notificationMessageTemplate,
overlayMessageListTemplate,
overlayTemplate,
legacyRegistry
@@ -65,8 +63,7 @@ define([
"depends": [
"$document",
"$compile",
"$rootScope",
"$timeout"
"$rootScope"
]
}
],
@@ -91,10 +88,6 @@ define([
"key": "message",
"template": messageTemplate
},
{
"key": "notification-message",
"template": notificationMessageTemplate
},
{
"key": "overlay-message-list",
"template": overlayMessageListTemplate

View File

@@ -19,24 +19,24 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class="c-overlay__top-bar">
<div class="c-overlay__dialog-title">{{ngModel.title}}</div>
<div class="c-overlay__dialog-hint hint">All fields marked <span class="req icon-asterisk"></span> are required.</div>
<div class="abs top-bar">
<div class="dialog-title">{{ngModel.title}}</div>
<div class="hint">All fields marked <span class="req icon-asterisk"></span> are required.</div>
</div>
<div class='c-overlay__contents-main'>
<div class='abs editor'>
<mct-form ng-model="ngModel.value"
structure="ngModel.structure"
class="validates"
name="createForm">
</mct-form>
</div>
<div class="c-overlay__button-bar">
<a class='c-button c-button--major'
<div class="abs bottom-bar">
<a class='s-button major'
ng-class="{ disabled: !createForm.$valid }"
ng-click="ngModel.confirm()">
OK
</a>
<a class='c-button '
<a class='s-button'
ng-click="ngModel.cancel()">
Cancel
</a>

View File

@@ -1,13 +1,10 @@
<div class="c-message"
<div class="l-message"
ng-class="'message-severity-' + ngModel.severity">
<div class="w-message-contents">
<div class="c-message__top-bar">
<div class="c-message__title">{{ngModel.title}}</div>
</div>
<div class="c-message__hint" ng-hide="ngModel.hint === undefined">
{{ngModel.hint}}
<span ng-if="ngModel.timestamp !== undefined">[{{ngModel.timestamp}}]</span>
<div class="top-bar">
<div class="title">{{ngModel.title}}</div>
</div>
<div class="hint" ng-hide="ngModel.hint === undefined">{{ngModel.hint}}</div>
<div class="message-body">
<div class="message-action">
{{ngModel.actionText}}
@@ -16,17 +13,17 @@
ng-model="ngModel"
ng-show="ngModel.progress !== undefined || ngModel.unknownProgress"></mct-include>
</div>
<div class="c-overlay__button-bar">
<button ng-repeat="dialogOption in ngModel.options"
class="c-button"
<div class="bottom-bar">
<a ng-repeat="dialogOption in ngModel.options"
class="s-button"
ng-click="dialogOption.callback()">
{{dialogOption.label}}
</button>
<button class="c-button c-button--major"
</a>
<a class="s-button major"
ng-if="ngModel.primaryOption"
ng-click="ngModel.primaryOption.callback()">
{{ngModel.primaryOption.label}}
</button>
</a>
</div>
</div>
</div>
</div>

View File

@@ -1,25 +0,0 @@
<div class="c-message"
ng-class="'message-severity-' + ngModel.severity">
<div class="w-message-contents">
<div class="c-message__top-bar">
<div class="c-message__title">{{ngModel.message}}</div>
</div>
<div class="message-body">
<mct-include key="'progress-bar'"
ng-model="ngModel"
ng-show="ngModel.progressPerc !== undefined"></mct-include>
</div>
<div class="c-overlay__button-bar">
<button ng-repeat="dialogOption in ngModel.options"
class="c-button"
ng-click="dialogOption.callback()">
{{dialogOption.label}}
</button>
<button class="c-button c-button--major"
ng-if="ngModel.primaryOption"
ng-click="ngModel.primaryOption.callback()">
{{ngModel.primaryOption.label}}
</button>
</div>
</div>
</div>

View File

@@ -1,23 +1,22 @@
<mct-container key="overlay">
<div class="t-message-list c-overlay__contents">
<div class="c-overlay__top-bar">
<div class="c-overlay__dialog-title">{{ngModel.dialog.title}}</div>
<div class="c-overlay__dialog-hint">Displaying {{ngModel.dialog.messages.length}} message<span
ng-show="ngModel.dialog.messages.length > 1 ||
ngModel.dialog.messages.length == 0">s</span>
<div class="t-message-list">
<div class="top-bar">
<div class="dialog-title">{{ngModel.dialog.title}}</div>
<div class="hint">Displaying {{ngModel.dialog.messages.length}} message<span ng-show="ngModel.dialog.messages.length > 1 ||
ngModel.dialog.messages.length == 0">s</span>
</div>
</div>
<div class="w-messages c-overlay__messages">
<div class="w-messages">
<mct-include
ng-repeat="msg in ngModel.dialog.messages | orderBy: '-'"
key="'notification-message'" ng-model="msg.model"></mct-include>
key="'message'" ng-model="msg.model"></mct-include>
</div>
<div class="c-overlay__bottom-bar">
<button ng-repeat="dialogAction in ngModel.dialog.actions"
class="c-button c-button--major"
<div class="bottom-bar">
<a ng-repeat="dialogAction in ngModel.dialog.actions"
class="s-button major"
ng-click="dialogAction.action()">
{{dialogAction.label}}
</button>
</a>
</div>
</div>
</mct-container>

View File

@@ -19,18 +19,18 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<mct-container key="c-overlay__contents">
<div class=c-overlay__top-bar">
<div class="c-overlay__dialog-title">{{ngModel.dialog.title}}</div>
<div class="c-overlay__dialog-hint hint">{{ngModel.dialog.hint}}</div>
<mct-container key="overlay">
<div class="abs top-bar">
<div class="dialog-title">{{ngModel.dialog.title}}</div>
<div class="hint">{{ngModel.dialog.hint}}</div>
</div>
<div class='c-overlay__contents-main'>
<div class='abs editor'>
<mct-include key="ngModel.dialog.template"
parameters="ngModel.dialog.parameters"
ng-model="ngModel.dialog.model">
</mct-include>
</div>
<div class="c-overlay__button-bar">
<div class="abs bottom-bar">
<a ng-repeat="option in ngModel.dialog.options"
href=''
class="s-button lg"

View File

@@ -19,12 +19,12 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class="c-overlay l-overlay-small" ng-class="{'delayEntry100ms' : ngModel.delay}">
<div class="c-overlay__blocker"></div>
<div class="c-overlay__outer">
<button ng-click="ngModel.cancel()"
<div class="abs overlay l-dialog" ng-class="{'delayEntry100ms' : ngModel.delay}">
<div class="abs blocker"></div>
<div class="abs outer-holder">
<a ng-click="ngModel.cancel()"
ng-if="ngModel.cancel"
class="c-click-icon c-overlay__close-button icon-x-in-circle"></button>
<div class="c-overlay__contents" ng-transclude></div>
class="close icon-x-in-circle"></a>
<div class="abs inner-holder contents" ng-transclude></div>
</div>
</div>

View File

@@ -44,9 +44,8 @@ define(
* @memberof platform/commonUI/dialog
* @constructor
*/
function OverlayService($document, $compile, $rootScope, $timeout) {
function OverlayService($document, $compile, $rootScope) {
this.$compile = $compile;
this.$timeout = $timeout;
// Don't include $document and $rootScope directly;
// avoids https://docs.angularjs.org/error/ng/cpws
@@ -94,14 +93,9 @@ define(
scope.key = key;
scope.typeClass = typeClass || 't-dialog';
this.$timeout(() => {
// Create the overlay element and add it to the document's body
element = this.$compile(TEMPLATE)(scope);
// Append so that most recent dialog is last in DOM. This means the most recent dialog will be on top when
// multiple overlays with the same z-index are active.
this.findBody().append(element);
});
// Create the overlay element and add it to the document's body
element = this.$compile(TEMPLATE)(scope);
this.findBody().prepend(element);
return {
dismiss: dismiss

View File

@@ -59,16 +59,16 @@ define(
["resolve", "reject"]
);
mockDocument = jasmine.createSpyObj(
"$document",
["find"]
"$document",
["find"]
);
mockBody = jasmine.createSpyObj('body', ['on', 'off']);
mockDocument.find.and.returnValue(mockBody);
mockDocument.find.andReturn(mockBody);
mockDeferred.promise = "mock promise";
mockQ.defer.and.returnValue(mockDeferred);
mockOverlayService.createOverlay.and.returnValue(mockOverlay);
mockQ.defer.andReturn(mockDeferred);
mockOverlayService.createOverlay.andReturn(mockOverlay);
dialogService = new DialogService(
mockOverlayService,
@@ -85,7 +85,7 @@ define(
it("allows user input to be canceled", function () {
dialogService.getUserInput({}, { someKey: "some value" });
mockOverlayService.createOverlay.calls.mostRecent().args[1].cancel();
mockOverlayService.createOverlay.mostRecentCall.args[1].cancel();
expect(mockDeferred.reject).toHaveBeenCalled();
expect(mockDeferred.resolve).not.toHaveBeenCalled();
});
@@ -93,7 +93,7 @@ define(
it("passes back the result of user input when confirmed", function () {
var value = { someKey: 42 };
dialogService.getUserInput({}, value);
mockOverlayService.createOverlay.calls.mostRecent().args[1].confirm();
mockOverlayService.createOverlay.mostRecentCall.args[1].confirm();
expect(mockDeferred.reject).not.toHaveBeenCalled();
expect(mockDeferred.resolve).toHaveBeenCalledWith(value);
});
@@ -109,7 +109,7 @@ define(
it("can show multiple dialogs if prior ones are dismissed", function () {
dialogService.getUserInput({}, {});
expect(mockLog.warn).not.toHaveBeenCalled();
mockOverlayService.createOverlay.calls.mostRecent().args[1].confirm();
mockOverlayService.createOverlay.mostRecentCall.args[1].confirm();
dialogService.getUserInput({}, {});
expect(mockLog.warn).not.toHaveBeenCalled();
expect(mockDeferred.reject).not.toHaveBeenCalled();
@@ -148,13 +148,13 @@ define(
it("destroys the event listener when the dialog is cancelled", function () {
dialogService.getUserInput({}, {});
mockOverlayService.createOverlay.calls.mostRecent().args[1].cancel();
mockOverlayService.createOverlay.mostRecentCall.args[1].cancel();
expect(mockBody.off).toHaveBeenCalledWith("keydown", jasmine.any(Function));
});
it("cancels the dialog when an escape keydown event is triggered", function () {
dialogService.getUserInput({}, {});
mockBody.on.calls.mostRecent().args[1]({
mockBody.on.mostRecentCall.args[1]({
keyCode: 27
});
expect(mockDeferred.reject).toHaveBeenCalled();
@@ -163,7 +163,7 @@ define(
it("ignores non escape keydown events", function () {
dialogService.getUserInput({}, {});
mockBody.on.calls.mostRecent().args[1]({
mockBody.on.mostRecentCall.args[1]({
keyCode: 13
});
expect(mockDeferred.reject).not.toHaveBeenCalled();
@@ -197,7 +197,7 @@ define(
"overlay",
["dismiss"]
);
mockOverlayService.createOverlay.and.returnValue(secondMockOverlay);
mockOverlayService.createOverlay.andReturn(secondMockOverlay);
secondDialogHandle = dialogService.showBlockingMessage(dialogModel);
//Dismiss the first dialog. It should only dismiss if it

View File

@@ -35,44 +35,39 @@ define(
mockTemplate,
mockElement,
mockScope,
mockTimeout,
overlayService;
beforeEach(function () {
mockDocument = jasmine.createSpyObj("$document", ["find"]);
mockCompile = jasmine.createSpy("$compile");
mockRootScope = jasmine.createSpyObj("$rootScope", ["$new"]);
mockBody = jasmine.createSpyObj("body", ["append"]);
mockBody = jasmine.createSpyObj("body", ["prepend"]);
mockTemplate = jasmine.createSpy("template");
mockElement = jasmine.createSpyObj("element", ["remove"]);
mockScope = jasmine.createSpyObj("scope", ["$destroy"]);
mockTimeout = function (callback) {
callback();
}
mockDocument.find.and.returnValue(mockBody);
mockCompile.and.returnValue(mockTemplate);
mockRootScope.$new.and.returnValue(mockScope);
mockTemplate.and.returnValue(mockElement);
mockDocument.find.andReturn(mockBody);
mockCompile.andReturn(mockTemplate);
mockRootScope.$new.andReturn(mockScope);
mockTemplate.andReturn(mockElement);
overlayService = new OverlayService(
mockDocument,
mockCompile,
mockRootScope,
mockTimeout
mockRootScope
);
});
it("prepends an mct-include to create overlays", function () {
overlayService.createOverlay("test", {});
expect(mockCompile).toHaveBeenCalled();
expect(mockCompile.calls.mostRecent().args[0].indexOf("mct-include"))
expect(mockCompile.mostRecentCall.args[0].indexOf("mct-include"))
.not.toEqual(-1);
});
it("adds the templated element to the body", function () {
overlayService.createOverlay("test", {});
expect(mockBody.append).toHaveBeenCalledWith(mockElement);
expect(mockBody.prepend).toHaveBeenCalledWith(mockElement);
});
it("places the provided model/key in its template's scope", function () {

View File

@@ -23,6 +23,7 @@
define([
"./src/controllers/EditActionController",
"./src/controllers/EditPanesController",
"./src/controllers/ElementsController",
"./src/controllers/EditObjectController",
"./src/actions/EditAndComposeAction",
"./src/actions/EditAction",
@@ -32,8 +33,13 @@ define([
"./src/actions/SaveAndStopEditingAction",
"./src/actions/SaveAsAction",
"./src/actions/CancelAction",
"./src/policies/EditActionPolicy",
"./src/policies/EditPersistableObjectsPolicy",
"./src/policies/EditableLinkPolicy",
"./src/policies/EditableMovePolicy",
"./src/policies/EditContextualActionPolicy",
"./src/representers/EditRepresenter",
"./src/representers/EditToolbarRepresenter",
"./src/capabilities/EditorCapability",
"./src/capabilities/TransactionCapabilityDecorator",
"./src/services/TransactionManager",
@@ -42,18 +48,21 @@ define([
"./src/creation/LocatorController",
"./src/creation/CreationPolicy",
"./src/creation/CreateActionProvider",
"./src/creation/AddActionProvider",
"./src/creation/CreationService",
"./res/templates/create/locator.html",
"./res/templates/create/create-button.html",
"./res/templates/create/create-menu.html",
"./res/templates/library.html",
"./res/templates/edit-object.html",
"./res/templates/edit-action-buttons.html",
"./res/templates/topbar-edit.html",
"text!./res/templates/create/locator.html",
"text!./res/templates/create/create-button.html",
"text!./res/templates/create/create-menu.html",
"text!./res/templates/library.html",
"text!./res/templates/edit-object.html",
"text!./res/templates/edit-action-buttons.html",
"text!./res/templates/elements.html",
"text!./res/templates/topbar-edit.html",
'legacyRegistry'
], function (
EditActionController,
EditPanesController,
ElementsController,
EditObjectController,
EditAndComposeAction,
EditAction,
@@ -63,8 +72,13 @@ define([
SaveAndStopEditingAction,
SaveAsAction,
CancelAction,
EditActionPolicy,
EditPersistableObjectsPolicy,
EditableLinkPolicy,
EditableMovePolicy,
EditContextualActionPolicy,
EditRepresenter,
EditToolbarRepresenter,
EditorCapability,
TransactionCapabilityDecorator,
TransactionManager,
@@ -73,6 +87,7 @@ define([
LocatorController,
CreationPolicy,
CreateActionProvider,
AddActionProvider,
CreationService,
locatorTemplate,
createButtonTemplate,
@@ -80,6 +95,7 @@ define([
libraryTemplate,
editObjectTemplate,
editActionButtonsTemplate,
elementsTemplate,
topbarEditTemplate,
legacyRegistry
) {
@@ -101,6 +117,14 @@ define([
"$scope"
]
},
{
"key": "ElementsController",
"implementation": ElementsController,
"depends": [
"$scope",
"openmct"
]
},
{
"key": "EditObjectController",
"implementation": EditObjectController,
@@ -160,13 +184,12 @@ define([
},
{
"key": "remove",
"category": "legacy",
"category": "contextual",
"implementation": RemoveAction,
"cssClass": "icon-trash",
"name": "Remove",
"description": "Remove this object from its containing object.",
"depends": [
"openmct",
"navigationService"
]
},
@@ -203,10 +226,10 @@ define([
"description": "Save changes made to these objects.",
"depends": [
"$injector",
"policyService",
"dialogService",
"copyService",
"notificationService",
"openmct"
"notificationService"
],
"priority": "mandatory"
},
@@ -223,11 +246,28 @@ define([
}
],
"policies": [
{
"category": "action",
"implementation": EditActionPolicy
},
{
"category": "action",
"implementation": EditPersistableObjectsPolicy,
"depends": ["openmct"]
},
{
"category": "action",
"implementation": EditContextualActionPolicy,
"depends": ["navigationService", "editModeBlacklist", "nonEditContextBlacklist"]
},
{
"category": "action",
"implementation": EditableMovePolicy
},
{
"category": "action",
"implementation": EditableLinkPolicy
},
{
"implementation": CreationPolicy,
"category": "creation"
@@ -257,6 +297,13 @@ define([
"action"
]
},
{
"key": "edit-elements",
"template": elementsTemplate,
"gestures": [
"drop"
]
},
{
"key": "topbar-edit",
"template": topbarEditTemplate
@@ -304,6 +351,18 @@ define([
"policyService"
]
},
{
"key": "AddActionProvider",
"provides": "actionService",
"type": "provider",
"implementation": AddActionProvider,
"depends": [
"$q",
"typeService",
"dialogService",
"policyService"
]
},
{
"key": "CreationService",
"provides": "creationService",
@@ -322,6 +381,22 @@ define([
"depends": [
"$log"
]
},
{
"implementation": EditToolbarRepresenter,
"depends": [
"openmct"
]
}
],
"constants": [
{
"key": "editModeBlacklist",
"value": ["copy", "follow", "link", "locate"]
},
{
"key": "nonEditContextBlacklist",
"value": ["copy", "follow", "properties", "move", "link", "remove", "locate"]
}
],
"capabilities": [
@@ -331,8 +406,7 @@ define([
"description": "Provides transactional editing capabilities",
"implementation": EditorCapability,
"depends": [
"transactionService",
"openmct"
"transactionService"
]
}
],
@@ -350,17 +424,6 @@ define([
"transactionService"
]
}
],
"runs": [
{
depends: [
"toolbars[]",
"openmct"
],
implementation: function (toolbars, openmct) {
toolbars.forEach(openmct.toolbars.addProvider, openmct.toolbars);
}
}
]
}
});

View File

@@ -24,8 +24,7 @@
<div class="items-select left flex-elem l-flex-row grows">
<mct-representation key="'back-arrow'"
mct-object="domainObject"
class="flex-elem l-back">
</mct-representation>
class="flex-elem l-back"></mct-representation>
<mct-representation key="'object-header'"
mct-object="domainObject"
class="l-flex-row flex-elem grows object-header">
@@ -49,8 +48,8 @@
<!-- Toolbar and Save/Cancel buttons -->
<div class="l-edit-controls flex-elem l-flex-row flex-align-end">
<mct-toolbar name="mctToolbar"
structure="editToolbar.structure"
ng-model="editToolbar.state"
structure="toolbar.structure"
ng-model="toolbar.state"
class="flex-elem grows">
</mct-toolbar>
<mct-representation key="'edit-action-buttons'"
@@ -62,6 +61,7 @@
<mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject"
class="abs flex-elem grows object-holder-main scroll"
toolbar="toolbar"
mct-selectable="{
item: domainObject.useCapability('adapter'),
oldItem: domainObject

View File

@@ -0,0 +1,47 @@
<!--
Open MCT, Copyright (c) 2014-2018, United States Government
as represented by the Administrator of the National Aeronautics and Space
Administration. All rights reserved.
Open MCT is licensed under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
Open MCT includes source code licensed under additional open source
licenses. See the Open Source Licenses file (LICENSES.md) included with
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div ng-controller="ElementsController" class="flex-elem l-flex-col holder grows">
<mct-include key="'input-filter'"
class="flex-elem holder"
ng-model="filterBy">
</mct-include>
<div class="flex-elem grows vscroll">
<ul class="tree" id="inspector-elements-tree" ng-if="composition.length > 0">
<li ng-repeat="containedObject in composition | filter:searchElements">
<span class="tree-item">
<span class="grippy-sm"
data-id="{{ containedObject.id }}"
mct-drag-down="dragDown($event)"
mct-drag="drag($event)"
mct-drag-up="dragUp($event)">
</span>
<mct-representation
class="rep-object-label"
key="'label'"
mct-object="containedObject">
</mct-representation>
</span>
</li>
</ul>
<div ng-if="composition.length === 0">No contained elements</div>
</div>
</div>

View File

@@ -49,7 +49,7 @@ define(
name: "Properties",
rows: this.properties.map(function (property, index) {
// Property definition is same as form row definition
var row = JSON.parse(JSON.stringify(property.getDefinition()));
var row = Object.create(property.getDefinition());
row.key = index;
return row;
}).filter(function (row) {

View File

@@ -23,109 +23,111 @@
/**
* Module defining RemoveAction. Created by vwoeltje on 11/17/14.
*/
define([], function () {
define(
[],
function () {
/**
* Construct an action which will remove the provided object manifestation.
* The object will be removed from its parent's composition; the parent
* is looked up via the "context" capability (so this will be the
* immediate ancestor by which this specific object was reached.)
*
* @param {DialogService} dialogService a service which will show the dialog
* @param {NavigationService} navigationService a service that maintains the current navigation state
* @param {ActionContext} context the context in which this action is performed
* @memberof platform/commonUI/edit
* @constructor
* @implements {Action}
*/
function RemoveAction(openmct, navigationService, context) {
this.domainObject = (context || {}).domainObject;
this.openmct = openmct;
this.navigationService = navigationService;
}
/**
* Perform this action.
*/
RemoveAction.prototype.perform = function () {
var dialog,
domainObject = this.domainObject,
navigationService = this.navigationService;
/*
* Check whether an object ID matches the ID of the object being
* removed (used to filter a parent's composition to handle the
* removal.)
/**
* Construct an action which will remove the provided object manifestation.
* The object will be removed from its parent's composition; the parent
* is looked up via the "context" capability (so this will be the
* immediate ancestor by which this specific object was reached.)
*
* @param {DomainObject} object the object to be removed
* @param {ActionContext} context the context in which this action is performed
* @memberof platform/commonUI/edit
* @constructor
* @implements {Action}
*/
function isNotObject(otherObjectId) {
return otherObjectId !== domainObject.getId();
function RemoveAction(navigationService, context) {
this.domainObject = (context || {}).domainObject;
this.navigationService = navigationService;
}
/*
* Mutate a parent object such that it no longer contains the object
* which is being removed.
/**
* Perform this action.
* @return {Promise} a promise which will be
* fulfilled when the action has completed.
*/
function doMutate(model) {
model.composition = model.composition.filter(isNotObject);
}
/*
* Checks current object and ascendants of current
* object with object being removed, if the current
* object or any in the current object's path is being removed,
* navigate back to parent of removed object.
*/
function checkObjectNavigation(object, parentObject) {
// Traverse object starts at current location
var traverseObject = (navigationService).getNavigation(),
context;
// Stop when object is not defined (above ROOT)
while (traverseObject) {
// If object currently traversed to is object being removed
// navigate to parent of current object and then exit loop
if (traverseObject.getId() === object.getId()) {
navigationService.setNavigation(parentObject);
return;
}
// Traverses to parent of current object, moving
// up the ascendant path
context = traverseObject.getCapability('context');
traverseObject = context && context.getParent();
RemoveAction.prototype.perform = function () {
var navigationService = this.navigationService,
domainObject = this.domainObject;
/*
* Check whether an object ID matches the ID of the object being
* removed (used to filter a parent's composition to handle the
* removal.)
*/
function isNotObject(otherObjectId) {
return otherObjectId !== domainObject.getId();
}
}
/*
* Remove the object from its parent, as identified by its context
* capability. Based on object's location and selected object's location
* user may be navigated to existing parent object
*/
function removeFromContext() {
var contextCapability = domainObject.getCapability('context'),
parent = contextCapability.getParent();
/*
* Mutate a parent object such that it no longer contains the object
* which is being removed.
*/
function doMutate(model) {
model.composition = model.composition.filter(isNotObject);
}
// If currently within path of removed object(s),
// navigates to existing object up tree
checkObjectNavigation(domainObject, parent);
/*
* Checks current object and ascendants of current
* object with object being removed, if the current
* object or any in the current object's path is being removed,
* navigate back to parent of removed object.
*/
function checkObjectNavigation(object, parentObject) {
// Traverse object starts at current location
var traverseObject = (navigationService).getNavigation(),
context;
return parent.useCapability('mutation', doMutate);
}
// Stop when object is not defined (above ROOT)
while (traverseObject) {
// If object currently traversed to is object being removed
// navigate to parent of current object and then exit loop
if (traverseObject.getId() === object.getId()) {
navigationService.setNavigation(parentObject);
return;
}
// Traverses to parent of current object, moving
// up the ascendant path
context = traverseObject.getCapability('context');
traverseObject = context && context.getParent();
}
}
removeFromContext();
};
/*
* Remove the object from its parent, as identified by its context
* capability. Based on object's location and selected object's location
* user may be navigated to existing parent object
*/
function removeFromContext(object) {
var contextCapability = object.getCapability('context'),
parent = contextCapability.getParent();
// Object needs to have a parent for Remove to be applicable
RemoveAction.appliesTo = function (context) {
var object = (context || {}).domainObject,
contextCapability = object && object.getCapability("context"),
parent = contextCapability && contextCapability.getParent(),
parentType = parent && parent.getCapability('type'),
parentCreatable = parentType && parentType.hasFeature('creation');
// If currently within path of removed object(s),
// navigates to existing object up tree
checkObjectNavigation(object, parent);
// Only creatable types should be modifiable
return parent !== undefined &&
Array.isArray(parent.getModel().composition) &&
parentCreatable;
};
return parent.useCapability('mutation', doMutate);
}
return RemoveAction;
});
return removeFromContext(domainObject);
};
// Object needs to have a parent for Remove to be applicable
RemoveAction.appliesTo = function (context) {
var object = (context || {}).domainObject,
contextCapability = object && object.getCapability("context"),
parent = contextCapability && contextCapability.getParent(),
parentType = parent && parent.getCapability('type'),
parentCreatable = parentType && parentType.hasFeature('creation');
// Only creatable types should be modifiable
return parent !== undefined &&
Array.isArray(parent.getModel().composition) &&
parentCreatable;
};
return RemoveAction;
}
);

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